Search code examples
c#wpflistviewitemcontainerstyle

Trying to Respond to Simple ListView Item Click


Simple goal. Click the %$^%# clown ... get a *&^$^$ message box. I want to be able to react to the click on a single row of the listview. This is proving to be vexingly difficult. I know the ItemContainerStyle is being applied ... the items are all pushed to the right. So why is the event not firing?

Here's the XAML:

    <Window x:Class="TryListView.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TryListView"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        Background="Black">
    <Grid Background="Transparent">
        <ListView Grid.Row="1" x:Name="lbClowns" Background="Transparent">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Border Margin="5" BorderBrush="White" BorderThickness="1">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                                </Grid.RowDefinitions>
                                <TextBlock Margin="5,0,0,0" Grid.Row="0" x:Name="NameTxt" TextWrapping="Wrap" Text="{Binding ClownName}" FontSize="28" Foreground="White"/>
                                <TextBlock Margin="5,0,0,0" Grid.Row="1" x:Name="TrickTxt"  TextWrapping="Wrap" Foreground="White" FontSize="18" Text="{Binding ClownTrick}" />
                            </Grid>
                        </Border>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Right" />
                    <EventSetter Event="MouseLeftButtonDown" Handler="KlownKlicked" />
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>

    </Grid>
</Window>

Here's the code-behind:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;

namespace TryListView
{
    public class Clown
    {
        public string ClownName { get; set; }
        public string ClownTrick { get; set; }
    }

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            PopulateMyListView();
        }

        private void PopulateMyListView()
        {
            var ListOClownz = new List<Clown>()
            {
                new Clown() { ClownName = "Krusty", ClownTrick="Juggling" },
                new Clown() { ClownName = "Pennywise", ClownTrick="Human Sacrifice" },
                new Clown() { ClownName = "Shakes", ClownTrick="Vomiting" },
                new Clown() { ClownName = "Bozo", ClownTrick="Swordfighting" },
            };

            lbClowns.ItemsSource = ListOClownz;
        }

        private void KlownKlicked(object sender, MouseButtonEventArgs e)
        {
            MessageBox.Show("Congratulations, you klicked a klown. Now get lost.");
        }
    }
}

Screenshot


Solution

  • MouseButtonEventArgs was marked as Handled (e.Handled) somewhere along the way (most likely due to selection of ListViewItem).

    you can trigger click method if use PreviewMouseLeftButtonDown event

    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="KlownKlicked" />
    
    private void KlownKlicked(object sender, MouseButtonEventArgs e)
    {
        var clown = ((ListViewItem)sender).DataContext as Clown;
        MessageBox.Show(String.Format("Congratulations, you klicked a klown {0}.", clown.ClownName));
    }
    

    ...and as an alternative try use ListView.SelectionChanged event:

    <ListView Grid.Row="1" x:Name="lbClowns" 
              Background="Transparent" 
              SelectionChanged="ListSelectionChanged">
    
    private void ListSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var clown = (Clown)lbClowns.SelectedItem;
        MessageBox.Show(String.Format("Congratulations, you klicked a klown {0}.", clown.ClownName));
    }