I'm trying to setup a gallery of images, that also features the ability to click on the image to show/hide a grid with image description, using the MVVM process.
However, i think my model, view model and view is not correctly setup because i am only able to display the images in the stacklayout if i use BindableLayout.ItemsSource="{Binding GalleryList.Gallery}"
in the top stacklayout, but not able to access the other parts of the class, i.e. only the Gallery list.
So essentially, I cant access InfoGridVisible
binding, since the it can't find/reach it? (i'm not sure to be honest).
Here is a snippet of my work so far:
View - testpage.xaml:
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="testproject.Pages.testpage"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:styles="clr-namespace:testproject.Styles"
xmlns:behaviours="clr-namespace:testproject.ViewModels"
mc:Ignorable="d"
xmlns:pancakeview="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView"
xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin"
BackgroundColor="Orange"
x:Name="Root">
<ContentPage.Content>
<ScrollView>
<Grid
Grid.Row="3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!--PROBLEM STARTS HERE -->
<StackLayout x:Name="GalleryStk" Grid.Row="1" Orientation="Vertical" BindableLayout.ItemsSource="{Binding GalleryList.Gallery}" Margin="10,0,10,0">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Grid RowSpacing="5" ColumnSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="AUTO"/>
<RowDefinition Height="AUTO"/>
</Grid.RowDefinitions>
<Frame x:Name="ImageFrame" CornerRadius="20" Padding="0" IsClippedToBounds="True" Grid.Row="0">
<Image Source="{Binding Image}" Aspect="AspectFill" Grid.RowSpan="2" HorizontalOptions="Center" VerticalOptions="Center">
<Image.GestureRecognizers>
<TapGestureRecognizer BindingContext="{Binding Source={x:Reference Root}, Path=BindingContext}" Command="{Binding TapCommand}"/>
</Image.GestureRecognizers>
</Image>
</Frame>
<!--<Image Source="ShadowOverlay" Grid.RowSpan="2" Aspect="Fill" VerticalOptions="End" HorizontalOptions="Fill" />-->
<Grid x:Name="InfoGrid" RowSpacing="10" ColumnSpacing="10" Grid.Row="0" IsEnabled="False" IsVisible="{Binding GalleryList.InfoGridVisible, Source={x:Reference InfoGrid}}">
<Grid.RowDefinitions>
<RowDefinition Height="AUTO"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="AUTO"/>
</Grid.ColumnDefinitions>
<BoxView Color="Black" Opacity="0.5" CornerRadius="20" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Row="0" Grid.RowSpan="5" Grid.ColumnSpan="3"/>
<Label Text="{Binding Title}" Padding="10,10,0,0" Grid.Row="0" Grid.ColumnSpan="3" Style="{StaticResource TitleLabel}" LineBreakMode="NoWrap"/>
<!--<controls:CircleImage Source="{Binding ProfileImage}" Aspect="AspectFill" Grid.Row="1" Grid.Column="0" WidthRequest="25" HeightRequest="25" />-->
<Label Text="{Binding Description}" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" Padding="10,0,10,0" Grid.Row="1" Grid.RowSpan="4" Grid.ColumnSpan="3" Style="{StaticResource HandleLabel}"/>
<!--<Button Text="See More" x:Name="ExpandContractButton" Clicked="ExpandContractButton_Clicked" Padding="10,0,10,0" Grid.Row="2" Grid.RowSpan="3" Grid.ColumnSpan="3"/>-->
<!--<StackLayout Orientation="Horizontal" VerticalOptions="Center" Grid.Column="2" Grid.Row="1" Spacing="5">
<Image Source="Eye"/>
<Label Text="{Binding ViewCount, StringFormat='{0:N0}'}" Style="{StaticResource HandleLabel}" />
<Label Text="views" Style="{StaticResource BodyLabel}"/>
</StackLayout>-->
</Grid>
</Grid>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</Grid>
</ScrollView>
</ContentPage.Content>
</ContentPage>
Code behind for view - testpage.xaml.cs
public partial class testpage : ContentPage
{
private Image _galleryImage;
public Grid GalleryInfoGrid;
private static testpage _instance;
public UserProfileViewModel vm { get; }
public static testpage Instance
{
get
{
if (_instance == null)
_instance = new testpage();
return _instance;
}
}
public testpage()
{
InitializeComponent();
vm = new UserProfileViewModel();
BindingContext = new UserProfileViewModel();
//var _galleryInfoGrid = (Grid)Root.FindByName("InfoGrid");
//_galleryInfoGrid.IsEnabled = true;
//_galleryInfoGrid.IsVisible = true;
}
Model:
{
public List<GalleryImage> Gallery { get; set; }
public string InfoGridVisible;
public string InfoGridEnabled;
}
public class GalleryImage
{
public string Title { get; set; }
public string Image { get; set; }
public string Description { get; set; }
}
Services (data):
public class ProfileService
{
private static ProfileService _instance;
public static ProfileService Instance
{
get
{
if (_instance == null)
_instance = new ProfileService();
return _instance;
}
}
public GalleryList GetGallery()
{
return new GalleryList
{
InfoGridEnabled = "False",
InfoGridVisible = "False",
Gallery = new List<GalleryImage>
{
new GalleryImage { Title="sevilla01.jpg", Image = "sevilla01.jpg", Description="Description1Description1Description1Description1 Description1Description1Description1 Description1Description1" },
new GalleryImage { Title="sevilla02.jpg", Image = "sevilla02.jpg", Description="Description2 Description1Description1Description1Description1Descript ion1Description1" },
new GalleryImage {Title="sevilla03.jpg", Image = "sevilla03.jpg", Description="Description3Description1Description1Description1" },
new GalleryImage {Title="sevilla04.jpg", Image = "sevilla04.jpg", Description="Description4Description1Description1" },
new GalleryImage {Title="sevilla05.jpg", Image = "sevilla05.jpg", Description="Description5Description1" },
new GalleryImage {Title="sevilla06.jpg", Image = "sevilla06.jpg", Description="Description6" },
new GalleryImage {Title="sevilla07.jpg", Image = "sevilla07.jpg", Description="Description7Description1Description1Description1Description1Description1Description1Description1Description1 Description1" }
}
};
}
}
View Model - UserProfileViewModel.cs:
public class UserProfileViewModel : BindableObject
{
//Models
private Profile _profile;
private GalleryList _galleryList;
int taps = 0;
ICommand tapCommand;
public UserProfileViewModel()
{
Profile = ProfileService.Instance.GetProfile();
GalleryList = ProfileService.Instance.GetGallery();
tapCommand = new Command(OnTapped);
}
public ICommand TapCommand
{
get { return tapCommand; }
}
void OnTapped(object s)
{
taps++;
//var info1Grid = testpage.Instance.GalleryInfoGrid;
//info1Grid.IsVisible = true;
//info1Grid.IsEnabled = true;
//GalleryList.InfoGridEnabled = "False";
//GalleryList.InfoGridVisible = "False";
Console.WriteLine("parameter: " + taps + " " + GalleryList.InfoGridVisible);
OnPropertyChanged();
}
public Profile Profile
{
get { return _profile; }
set
{
_profile = value;
OnPropertyChanged();
}
}
public GalleryList GalleryList
{
get { return _galleryList; }
set
{
_galleryList = value;
OnPropertyChanged();
}
}
}
Apologies for the code dump, any help would be appreciated as i have been stuck on this for a few days. If there is a better method of implementing this, i would love to hear it.
What I want you try is something like this:
public class GalleryList : BindableObject {
private string _InfoGridVisible { get; set; }
private string _InfoGridEnabled { get; set; }
public List<GalleryImage> Gallery { get; set; }
public string InfoGridVisible
{
get { return _InfoGridVisible; }
set
{
_InfoGridVisible = value;
OnPropertyChanged();
}
}
public string InfoGridEnabled
{
get { return _InfoGridEnabled; }
set
{
_InfoGridEnabled = value;
OnPropertyChanged();
}
}
}
public class GalleryImage : BindableObject {
private string _Title { get; set; }
private string _Image { get; set; }
private string _Description { get; set; }
public string Title
{
get { return _Title; }
set
{
_Title = value;
OnPropertyChanged();
}
}
public string Image
{
get { return _Image; }
set
{
_Image = value;
OnPropertyChanged();
}
}
public string Description
{
get { return _Description; }
set
{
_Description = value;
OnPropertyChanged();
}
}
}