Prevent child element's event from bubbling up to it's parent in MVVM way

Viewed 452

I have a ComboBoxItem with a child button and I would like to prevent the ComboBox from dropping up (collapsing) when that button is clicked. Apparently it seems that the button is bubbling up the click event to the ComboBoxItem, causing the drop down to collapse.

<ComboBox DropDownOpened="OnWindowsDropDownOpened">
    <ComboBox.ItemTemplateSelector>
        <s:ComboBoxItemTemplateSelector>
            <s:ComboBoxItemTemplateSelector.SelectedTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Description}" />
                </DataTemplate>
            </s:ComboBoxItemTemplateSelector.SelectedTemplate>
            <s:ComboBoxItemTemplateSelector.DropDownTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                        <Button Command="{Binding DataContext.HighlightWindow, ElementName=Windows}" CommandParameter="{Binding}" MouseDown="Button_MouseDown" Click="Button_Click">
                            <md:PackIcon Kind="Target" />
                        </Button>
                        <TextBlock Text="{Binding Description}" />
                    </StackPanel>
                </DataTemplate>
            </s:ComboBoxItemTemplateSelector.DropDownTemplate>
        </s:ComboBoxItemTemplateSelector>
    </ComboBox.ItemTemplateSelector>
    <ComboBox.ItemContainerStyle>
        <Style BasedOn="{StaticResource MaterialDesignComboBoxItemStyle}" TargetType="ComboBoxItem">
            <Setter Property="IsEnabled" Value="{Binding Valid}" />
            <Setter Property="ToolTip">
                <Setter.Value>
                    <TextBlock Text="{Binding Title}" />
                </Setter.Value>
            </Setter>
        </Style>
    </ComboBox.ItemContainerStyle>
</ComboBox>

As we can see, I tried both MouseDown and Click, handling the event, as follows:

private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
    e.Handled = true;
}

private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
    e.Handled = true;
}

How do I do that? Also, is it possible to use MVVM code only (XAML-based code, no C#)?

Here's a screenshot of the ComboBox open

2 Answers

One you have not tested yet PreviewMouseLeftButtonDown and do it by the ComboBox. Or you can take another Preview* event.

private void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    e.Handled = sender is Button;
}

<ComboBox DropDownOpened="OnWindowsDropDownOpened" PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown">

In WPF, elements are selected based on their behavior, not their visual appearance.
The behavior of the ComboBox (including) is to collapse when an item is selected.
If you do not need this, but need an explicit, separate action from the user to collapse the list, then use another element or a combination of them.

In my opinion, the Expander with a nested ListBox will be the most convenient for your task.

Related