【问题标题】:Prevent child element's event from bubbling up to it's parent in MVVM way防止子元素的事件以 MVVM 方式冒泡到其父元素
【发布时间】:2021-04-14 17:52:11
【问题描述】:

我有一个带有子按钮的ComboBoxItem,我想防止在单击该按钮时ComboBox 掉落(折叠)。显然,按钮似乎将点击事件冒泡到ComboBoxItem,导致下拉列表崩溃。

<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>

如我们所见,我尝试了MouseDownClick,处理事件,如下:

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

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

我该怎么做?另外,是否可以仅使用 MVVM 代码(基于 XAML 的代码,没有 C#)?

Here's a screenshot of the ComboBox open

【问题讨论】:

    标签: c# wpf xaml mvvm event-bubbling


    【解决方案1】:

    您还没有测试过PreviewMouseLeftButtonDown 并通过ComboBox 进行测试。或者您可以参加另一个Preview* 活动。

    private void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        e.Handled = sender is Button;
    }
    
    <ComboBox DropDownOpened="OnWindowsDropDownOpened" PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown">
    

    【讨论】:

    • 使用Preview* 事件确实会阻止ComboBox 下降,但它也会阻止绑定Command(未触发)。是否可以让这两种行为都起作用(无需将命令代码移动到Button_PreviewMouseLeftButtonDown)?类似于:
    • 您可以在事件处理程序中调用(sender as Button).Command.Execute(null);
    • (sender as Button).Command.Execute(null); 确实是一个不错的解决方法。如上所述,是否可以使用单个按钮属性完成所有操作?例如:&lt;Button ChainEvents="False"/&gt;
    • 我会说不。您可以尝试将具有命令执行的事件处理程序放在行为中,并在 XAML 中使用/重用它。
    • 您也可以在ComboBox 中收听PreviewMouseLeftButtonDown,而不是在Button 中。
    【解决方案2】:

    在 WPF 中,元素的选择是基于它们的行为,而不是它们的视觉外观。
    ComboBox(包括)的行为是在选择项目时折叠。
    如果您不需要此操作,但需要用户执行明确的单独操作来折叠列表,请使用其他元素或它们的组合。

    在我看来,带有嵌套 ListBox 的 Expander 将最方便您的任务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 2013-09-29
      • 1970-01-01
      • 2011-07-03
      • 2010-11-30
      相关资源
      最近更新 更多