Joe
Joe

Reputation: 95

Execute a command when selecting same entry again in ComboBox using mvvm

I have Combobox in my wpf 'mvvm' app. The Items in my ComboBox are: 'a' , 'b', 'c' , 'Browse Folder' , 'd'

Here is what i am trying to do:

  1. (Keyboard) When i press Enter on the last Browse Folder entry I have to execute command (Cmd1) to open File Browser.
  2. (Keyboard) - Closing & re-opening combo-box and hit press Enter on Browser Folder should re-execute the command (Cmd1).

What I tried:

  1. If I write a Data Template to comboBox items as buttons, the button command only works with mouse click and not with keyboard Enter key.

    <ComboBox.ItemTemplate> 
        <DataTemplate>
            <Button Command="{Binding DataContext.Cmd1, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ComboBox}}}" Background="Transparent" Content="{Binding Name}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
    
  2. If i write the command (Cmd1) logic in SelectedIndex/SelectionChanged the it only executes one time , and I have to select a different value and Browse Folder again in drop-down to re-execute.

  3. If i attach my Cmd1 logic to DropDownClosed then the last selected entry (Browse Folder) keeps executing every-time i open-&-close drop-down list.

How can i execute a command if i select the same entry multiple times in ComboBox in mvvm! Thanks a lot

Upvotes: 0

Views: 300

Answers (1)

mm8
mm8

Reputation: 169360

You could use an attached behaviour that handles the KeyDown event for the specific item:

public class KeyDownBehavior
{
    public static readonly DependencyProperty EnterCommandProperty = DependencyProperty.RegisterAttached(
        "EnterCommand",
        typeof(ICommand),
        typeof(KeyDownBehavior),
        new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnSet)));

    public static void SetEnterCommand(UIElement element, ICommand value) =>
        element.SetValue(EnterCommandProperty, value);

    public static ICommand GetEnterCommand(UIElement element) =>
        (ICommand)element.GetValue(EnterCommandProperty);

    private static void OnSet(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        UIElement element = (UIElement)d;
        element.KeyDown += OnKeyDown;
    }

    private static void OnKeyDown(object sender, KeyEventArgs e)
    {
        ICommand command = GetEnterCommand((UIElement)sender);
        if (command != null)
            command.Execute(null);
    }
}

Sample XAML markup:

<ComboBox>
    <ComboBox.ItemContainerStyle>
        <Style TargetType="ComboBoxItem">
            <Style.Triggers>
                <DataTrigger Binding="{Binding}" Value="Browse Folder">
                    <Setter Property="local:KeyDownBehavior.EnterCommand"
                            Value="{Binding DataContext.Cmd1, 
                                RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ComboBox.ItemContainerStyle>
    <s:String>a</s:String>
    <s:String>b</s:String>
    <s:String>c</s:String>
    <s:String>Browse Folder</s:String>
    <s:String>d</s:String>
</ComboBox>

Upvotes: 1

Related Questions