Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin.Forms: Get all cells/items of a listview

I want to make some changes to all of the cells shown in the ListView. Therefore I want to get all cells or items. E.g.

this.listView.ItemSource.Items

Items in the above code doesn't exist. Furthermore I didn't found any options on ListView or ItemSource, which could do this. Is it possible to get all cells/items? If not what other options do I have to change the appearence of the cells after they were loaded? E.g. for changing text or layout.

like image 900
testing Avatar asked Mar 07 '16 16:03

testing


People also ask

What is the difference between ListView and CollectionView in xamarin forms?

While the CollectionView and ListView APIs are similar, there are some notable differences: CollectionView has a flexible layout model, which allows data to be presented vertically or horizontally, in a list or a grid. CollectionView supports single and multiple selection. CollectionView has no concept of cells.

What is ViewCell in xamarin forms?

A Xamarin. Forms ViewCell is a cell that can be added to a ListView or TableView, which contains a developer-defined view. This article demonstrates how to create a custom renderer for a ViewCell that's hosted inside a Xamarin. Forms ListView control. This stops the Xamarin.

How do you bind data in ListView in xamarin forms?

ListView allows you to bind the data directly from the DataTable by converting the data table rows in to the collection and bind it to the ItemsSource property but the data model values is in array type, so you can directly bind the array values in the element.

What is Datatemplate in xamarin forms?

The DataTemplateSelector is a class that lets you change the data template you want to use, in a ListView or CarouselView, depending upon the type of data for each item, in the list. Rather than making a complex ViewCell or ItemTemplate, you can design each one specifically for the type of data you want.


1 Answers

I am probably late to the party, but here's another approach using System.Reflection. Anyways, I'd suggest using it only in cases where databinding isn't possible and as a last resort option.

For a given ListView

<ListView x:Name="connectionsListView" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" ItemSelected="OnConnectionSelect">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell Height="40">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="50"/>
                    </Grid.ColumnDefinitions>
                    <customs:MyViewClass Grid.Column="0"/>
                </Grid>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
    <ListView.Footer>
        <ContentView />
    </ListView.Footer>
</ListView>

You can crawl through the ListView by grabbing the "TemplatedItems" property, casting it to ITemplatedItemsList<Cell> and iterating through your (View)cells.

IEnumerable<PropertyInfo> pInfos = (connectionsListView as ItemsView<Cell>).GetType().GetRuntimeProperties();
var templatedItems = pInfos.FirstOrDefault(info => info.Name == "TemplatedItems");
if (templatedItems != null)
{
  var cells = templatedItems.GetValue(connectionsListView);
    foreach (ViewCell cell in cells as Xamarin.Forms.ITemplatedItemsList<Xamarin.Forms.Cell>)
    {
        if (cell.BindingContext != null && cell.BindingContext is MyModelClass)
        {
            MyViewClass target = (cell.View as Grid).Children.OfType<MyViewClass>().FirstOrDefault();
            if (target != null)
            {
               //do whatever you want to do with your item... 
            }
        }
    }
}

Update: Since it was asked, if (cell.BindingContext != null && cell.BindingContext is MyModelClass) is basically a safeguard to prevent access to non-existing views, for instance if the ListView hasn't been populated yet.

If a check for the BindingContext being a particular model class isn't necessary, it would be sufficient to reduce the line to

if (cell.BindingContext != null)
like image 171
Markus Michel Avatar answered Nov 15 '22 11:11

Markus Michel