Aman Sharma
Aman Sharma

Reputation: 698

How to access ListViewItems when DataType is set in DataTemplate of ListView?

I'm working on a UWP app. I want to iterate through all the ListViewItems of a ListView in a page. Here's the xaml for the ListView.

<ListView x:Name="DownloadTaskListView"
                  ItemsSource="{x:Bind ViewModel.CompletedDownloads}"
                  HorizontalContentAlignment="Stretch" 
                  Background="{x:Null}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="data:DownloadTask">
                    <Grid x:Name="ItemViewGrid" Background="{x:Null}" Margin="4,0,0,0">
                    ....
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalAlignment" Value="Stretch" />
                    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                    <Setter Property="BorderThickness" Value="0" />
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>

I use this piece of code to achieve this.

foreach(ListViewItem item in DownloadTaskListView.Items)
{
     // Do something useful

}

But it gave me an Exception. Because I set the DataType of DataTemplate so runtime throw me an exception that it cannot convert from from DownloadTask (In this case the data type) to the ListViewItem. So I want to ask what is the other way of accessing ListViewItems?

Upvotes: 1

Views: 1714

Answers (2)

Grace Feng
Grace Feng

Reputation: 16652

You can use ItemsControl.ContainerFromItem method to find container corresponding to the specified item, then get the root element of this container, in your case it's a Grid. For example like this:

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    foreach (var item in DownloadTaskListView.Items)
    {
        var listviewitem = item as DownloadTask;
        var container = DownloadTaskListView.ContainerFromItem(listviewitem) as ListViewItem;
        var ItemViewGrid = container.ContentTemplateRoot as Grid;
        //TODO:
    }
}

Just be aware that if you want to use this method in SelectionChanged event of your listview, you can just pass the selected Item into ContainerFromItem method, otherwise it will not find the ListBoxItem.

I should say, if it is possible, using data binding is better.

Upvotes: 3

AVK
AVK

Reputation: 3923

Since you are setting ItemsSource as ViewModel.CompletedDownloads do the Item loop on the same.

foreach(var Items in ViewModel.CompletedDownloads)
{
    //Do Something Useful.
}

Upvotes: 0

Related Questions