Dmitry
Dmitry

Reputation: 91

Why in UWP application Holding is not called for ListViewItem in ListView

I have a ListView on a page of my UWP app:

        <ListView x:Name="ArrivalsListView" Margin="30,135,40,160">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid Holding="Grid_Holding" Background="Transparent" VerticalAlignment="Stretch">
                    <ItemsControl Holding="Grid_Holding">
                        <FlyoutBase.AttachedFlyout>
                            <MenuFlyout>
                                <MenuFlyoutItem x:Name="EditButton" Background="Transparent" Text="Edit" Click="EditClick"/>
                                <MenuFlyoutItem x:Name="RemoveButton" Background="Transparent" Text="Remove" Click="RemoveClick"/>
                            </MenuFlyout>
                        </FlyoutBase.AttachedFlyout>
                    </ItemsControl>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

As you can see, it contains MenuFlyout, which is attached to Holding in code behind:

    private void Grid_Holding(object sender, HoldingRoutedEventArgs e)
    {
        FrameworkElement senderElement = sender as FrameworkElement;
        FlyoutBase flyoutBase = FlyoutBase.GetAttachedFlyout(senderElement);
        flyoutBase.ShowAt(senderElement);
    }

When I add items to ListView as following

    ArrivalsListView.Items.Add(arrival.Time.ToString(@"hh\:mm"));

it works fine and Meny Flyout appears in emulator on holding ListView item.

But when I add items as following (I need it for setting color and so on):

    ListViewItem listItem = new ListViewItem();
    listItem.Content = departure.Time.ToString(@"hh\:mm");
    DeparturesListView.Items.Add(listItem);

holding does not work (Grid_Holding is not called), and, so that, Menu does not appear.

What is the reason and how can I fix that?

Upvotes: 1

Views: 489

Answers (1)

Decade Moon
Decade Moon

Reputation: 34286

My guess is that in the first instance:

ArrivalsListView.Items.Add(arrival.Time.ToString(@"hh\:mm"));

The ListView is given a string as an item. In order for it to display this, it needs to create a ListViewItem with that string as its DataContext. It inflates the ItemTemplate to create the content for the new ListViewItem, whereby the Holding event is hooked up correctly (since it is part of the template).

In the second instance:

ListViewItem listItem = new ListViewItem();
listItem.Content = departure.Time.ToString(@"hh\:mm");
DeparturesListView.Items.Add(listItem);

you're giving the ListView a custom ListViewItem that you have configured (with custom colors and so forth, as you mentioned). In this case, the ListView just uses the ListViewItem as-is. The content of that ListViewItem was not generated from the ItemTemplate. In fact, if you inspect the ListViewItem using the Live Visual Tree tools, you'll see that it doesn't contain the Grid from the ItemTemplate.

Your options are:

  • If you're going to make a ListViewItem by hand, then you are responsible for setting up any event handlers and such too.
  • (My recommendation) Don't create ListViewItems by hand. If you need specialized behaviour or appearance for particular items, then use ListView.ItemTemplateSelector, or, if it's just the color of the item that needs to change, bind to the color property (you might need a IValueConverter too). This is also better for virtualization, since the ListView will be able to recycle items.

Upvotes: 0

Related Questions