Search code examples
xamluwpwindows-runtime

How do I tell when a ListViewItem gets focus?


I have a UWP XAML ListView, and I would like to handle focus events when I switch between items within with arrow keys. However, I cannot figure out how to handle focus events for my items:

<ListView ItemsSource="{x:Bind Items}"
                  CanDragItems="True" CanReorderItems="True" AllowDrop="True"
                  SelectionMode="None" IsItemClickEnabled="True" ItemClick="ListView_ItemClick">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="x:String">
                    <!-- Never fires, even with Control.IsTemplateFocusTarget="True" : -->
                    <StackPanel GotFocus="StackPanel_GotFocus">
                        <!-- Never fires: -->
                        <TextBlock Text="{x:Bind}" GotFocus="TextBlock_GotFocus" />
                        <Button Content="Foo" IsTabStop="False" />
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListViewItem">
                                <!-- Never fires: -->
                                <ListViewItemPresenter [...]
                                                       GotFocus="Root_GotFocus" />
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>

Where else could I listen to get these focus events?

Thanks!

Disclaimer: I work for Microsoft.


Solution

  • When using <ListView> or <ListBox> you don't need to use GotFocus events. Instead you use SelectionChanged event in the main <listView> control, and in code get the index of the <ListViewItem> that got selected.

    SelectionChanged event is triggered every time the user change his selection in the <ListView>.

    ListView.SelectedIndex returns the index number of the selected <ListViewItem> First item is 0.

    Here is an example:

    XAML:

    <Image x:Name="img"/>
    <ListView x:Name="listView" SelectionChanged="ListView_SelectionChanged">  
    <ListViewItem>Image 1</ListViewItem>
    <ListViewItem>Image 2</ListViewItem> 
    <ListViewItem>Image 3</ListViewItem>
    </ListView>
    

    C#:

    private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {                                                                                                                                                                                                                                                                           
        int num = listView.SelectedIndex + 1;                                                                         
        img.Source = new BitmapImage(new Uri($"ms-appx:///Assets/Pictures/image{num}.jpg"));
    }