Omri Btian
Omri Btian

Reputation: 6547

Post selection mouse click event on ListBox

background

I have custom control, containing a Popup which contains a ListBox

Requirement

I need to close the popup and do some logic with the selected item when the user chooses an item. User chooses an item when :

  1. he click's on the item with the mouse.
  2. he selected and item through keyboard navigation (up/down keys) and clicks enter

Problem

I have implemented all the above, but my problem is with the events to listen to inorder to execute my logic.

If I execute my logic on the SelectionChanged event, It will not fire when the user clicks on the selected item, so I'm missing my first scenario. If I execute my logic on the PreviewMouseLeftButtonDown It will fire before the selection changed so I don't know what the user has chosen. This is also why I can't use both.

I thought of listening on the ListBoxItem events to do this (How to capture a mouse click on an Item in a ListBox in WPF?) or firing a command from an implicit ListBoxItem style (WPF Interaction triggers in a Style to invoke commands on View Model) but they didn't work for me.

The best idea that I came up with, is to create some kind of a "post selection" MouseButtonDown event via behaviours or actions, but I am not sure how, or if this is even the way to go.

Any Idea how to create such a thing? Or is there a better solution for this?

Upvotes: 0

Views: 2231

Answers (1)

Sheridan
Sheridan

Reputation: 69959

The answer is to Bind to the ListBox.SelectedItem property and to handle the PreviewKeyDown event of your control. This way, you'll always know which item is the selected one and when the Enter key is hit:

public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.
    Register("SelectedItem", typeof(YourDataType), typeof(YourControl), 
    new UIPropertyMetadata(null, OnSelectedItemPropertyChanged));

public YourDataType SelectedItem 
{
    get { return (YourDataType)GetValue(SelectedItemProperty); }
    set { SetValue(SelectedItemProperty, value); }
}

private static void OnSelectedItemPropertyChanged(DependencyObject sender, 
    DependencyPropertyChangedEventArgs e)
{
    // User has selected an item
}
...
private void Control_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter || e.Key == Key.Return)
    {
        // User pressed Enter... do something with SelectedItem property here
    }
}

UPDATE >>>

Ok, I think I understand your problem a bit better now. The simplest solution would be if you could slightly alter the requirement so that;

  1. An item is selected with either the mouse or keyboard up/down keys
  2. An item is chosen with the Enter key

That way, you'd always know the selected item when the user chooses. However, if you can't do that, can you handle the PreviewMouseLeftButtonUp instead of the PreviewMouseLeftButtonDown event? I'm not 100% sure, but I think that that would occur after the selection has been made.

Upvotes: 1

Related Questions