views:

8467

answers:

3

I have the following ListView:

<ListView Name="TrackListView">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Title" Width="100" HeaderTemplate="{StaticResource BlueHeader}" DisplayMemberBinding="{Binding Name}"/>
            <GridViewColumn Header="Artist" Width="100" HeaderTemplate="{StaticResource BlueHeader}" DisplayMemberBinding="{Binding Album.Artist.Name}" />
        </GridView>
    </ListView.View>
</ListView>

My question is, how can I attach an event to every bound item that will fire on double-clicking the item?

+2  A: 

In your example are you trying to catch when an item in your ListView is selected or when a column header is clicked on? If it's the former you would add a SelectionChanged handler.

<ListView Name="TrackListView" SelectionChanged="MySelectionChanged">

If it's the latter you would have to use some combination of MouseLeftButtonUp or MouseLeftButtonDown events on the GridViewColumn items to detect a double click and take appropriate action. Alternatively you could handle the events on the GridView and work out from there which column header was under the mouse.

sipwiz
I wanted an event on the bounded items, not the headers
Andreas Grech
That's a new one for me. Thanks for putting up your answer (and I'll remove the no DoubleClick event statement from mine).
sipwiz
Glad to be of help =)
Andreas Grech
+23  A: 

Found the solution from here: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/3d0eaa54-09a9-4c51-8677-8e90577e7bac/


XAML:

<UserControl.Resources>
    <Style x:Key="itemstyle" TargetType="{x:Type ListViewItem}">
        <EventSetter Event="MouseDoubleClick" Handler="HandleDoubleClick" />
    </Style>
</UserControl.Resources>

<ListView Name="TrackListView" ItemContainerStyle="{StaticResource itemstyle}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Title" Width="100" HeaderTemplate="{StaticResource BlueHeader}" DisplayMemberBinding="{Binding Name}"/>
            <GridViewColumn Header="Artist" Width="100" HeaderTemplate="{StaticResource BlueHeader}" DisplayMemberBinding="{Binding Album.Artist.Name}" />
        </GridView>
    </ListView.View>
</ListView>

C#:

protected void HandleDoubleClick(object sender, MouseButtonEventArgs e)
{
    var track = ((ListViewItem) sender).Content as Track; //Casting back to the binded Track
}
Andreas Grech
If you don't need to re-use the style, you can put it directly into the <ListView.Resources/> section and remove the x:Key.
David Schmitt
Thanks for the tip David.
Andreas Grech
This worked for me, too. Thanks!BTW, you will probably want to stop the bubbling of the doubleClick event within your handler by setting: e.Handled = true;
Tom A
I have a problem with this. That is, I use x:Key-less styles in the window to style all the UI elements, including the ListViews used in a custom control on that window. Putting this event-handler in the custom control's xaml disables the style applied in the window.
csuporj
Just out of curiosity, is there another way to do this that doesn't violate MVVM?
Dave
Yes, in place of retrieving the selected item into the Content property of the sender parameter of the event, you can bind the SelectedItem of the listview and take this value into the handler of the double click event.
Coolweb
As a warning: using an `EventSetter` can lead to memory leaks if its handler's target lives longer than the `ListViewItem`. I spent the last few days debugging a serious memory leak (20mb at a time), only to find out that `ListViewItem`s and their associated memory were being leaked through an `EventSetter`.
Zach Johnson
A: 

Why ListView.AddHandle(ListViewItem.MouseDoubleClick, xxx) doesn't work?

Cooper.Wu