Reputation: 2085
I read a lot of topics about usage of ObservableCollection, but I don't understand what should I do in my case. I have the following PageContent
structure:
I use IList collection to store my Xamarin.Form.Image
. I take it from the database. The number of the grid layout rows and columns definitely depend on the number of images in a database. User can load new images to a database. It ads to a database by using ImageRepository
and it ads to the IList<T>
collection, but I don't know how to dynamically redraw my grid layout. I tried to do this as follows:
//this.images
//is a IList<Images> which stores as property of the class.
private void OnClickSearchImagesButton(object sender, EventArgs args)
{
IFiler filer = DependencyService.Get<IFiler>();
// Get all paths of the images
IEnumerable<string> filesPath = filer.GetFilesPaths(FileExtension.JPG);
IEnumerable<Image> images = filesPath.Select(f => new Image { Source = ImageSource.FromFile(f) });
foreach (Image img in images)
{
// If found image does not exist
// Add it to a database
// --------------------
// Redraw grid layout
this.gridLayout = new Grid();
const int numberOfImagesPerRow = 3;
int numberOfImages = this.images.Count;
int numberOfRows = (int)Math.Ceiling((double)numberOfImages / numberOfImagesPerRow);
// configure grid layout
for (int i = 0; i < numberOfRows; i++)
{
this.gridLayout.RowDefinitions.Add(new RowDefinition { Height = new GridLength(200) });
}
for (int i = 0; i < numberOfImagesPerRow; i++)
{
this.gridLayout.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
}
for (int i = 0, imageNumber = 0; i < numberOfRows; i++)
{
for (int j = 0; j < numberOfImagesPerRow && imageNumber < numberOfImages; j++, imageNumber++)
{
this.gridLayout.Children.Add(images[imageNumber], j, i);
}
}
}
}
But it didn't help me. I saw some topics when people use ObservableCollection
for items instead of List
. I'm a little bit confused with it, because I think that I need to store all my items in ObservableCollection. Please, could you explain me what is the best way to hold actual information on the page?
Upvotes: 3
Views: 976
Reputation: 1099
ObservableCollection is helpful because it fires events when the collection changes, but you need to either use a control that consumes those events, or create one yourself. In your case, I would suggest looking at some third party controls that layout images as you want (another answer mentioned FlowListView), or look at creating a custom layout in Xamarin Forms.
Upvotes: 1
Reputation: 5768
ObservableCollection is very useful when you use controls like ListView. If you add a record or remove a record from the ObservableCollection, ListView updates automatically.
If you create a Grid and add Images to it, you should add or remove items "by code". ObservableCollection can't help you.
If you need a ListView that display images (so you can use ObservableCollection) you can take a look to
it's a powerful plugin that can visualize Images in a List
DataTemplate and DataTemplateSelector support
Fixed or automatic column count
Grouping support
Columns can expand to empty space (configurable)
ANY View can be used as a cell
All Xamarin.Forms platforms supported
Simple sample
<flv:FlowListView FlowColumnCount="3" SeparatorVisibility="None" HasUnevenRows="false"
FlowItemTappedCommand="{Binding ItemTappedCommand}" FlowLastTappedItem="{Binding LastTappedItem}"
FlowItemsSource="{Binding Items}" >
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<Label HorizontalOptions="Fill" VerticalOptions="Fill"
XAlign="Center" YAlign="Center" Text="{Binding Title}"/>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
If you need a demo
Upvotes: 3