列表框选择隐藏其他鼠标事件

Listbox selection hides other mouse event

你好 Whosebugers,

我有一个System.Windows.Control.ListBox。它做得很好,但我希望在 select 某些类型的项目时有一些行为。

我无法在 SelectedItem 的绑定 属性 中执行此操作,因为我的列表框的视图模型 (Foo) 不知道我想要的工作所需的所有数据(一些来自另一个 ViewModel : Bar ).

我提到的两个 ViewModel 是一个更大的 class Zot 的字段,以便 Zot 访问 Foo 和 Bar 的内容

我使用 Interaction.Triggers、EventTrigger 和 InvokeCommandAction 将 Foo 和 Bar 中的点击事件转发给 Zot。它对 Bar(canvas)非常有用。但是我在使用列表框时遇到了麻烦。

在测试 SelectionChanged、MouseDown 和 Click 事件后,如果我单击包裹列表框的网格似乎会触发 MouseDown,但当我单击 ListBox 时不会。感觉Listbox中嵌入的selection与其他事件有冲突。

有人知道在不同的视图模型中根据 selected 项目执行特定操作吗?

非常感谢

编辑:

这是列表框的 XAML(在 ToolboxView.xaml 中)

     d:DataContext="{d:DesignInstance viewModels:ToolboxViewModel}">
       <Grid>
          <ListBox
                ItemsSource="{Binding Tools}"
                SelectedItem="{Binding SelectedTool}"
                x:Name="ToolView" >

            <ListBox.ItemTemplate>
                <DataTemplate DataType="interfaces:IBuilder">
                    <TextBlock 
                        FontWeight="DemiBold"
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        Text="{Binding Name}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>

这是列表框上的事件,来自主要 window xaml(哪个视图模型包含列表框视图模型,我在下面解释原因)。但是,该事件永远不会被触发。稍后在同一个文件中,3 个类似的事件完美运行(在 canvas 上)。我尝试使用 MouseDown 而不是 SelectionChanged,它在我单击包含列表框的网格时触发,但在我单击列表框时不触发。

(在MainWindow.xaml)

<DockPanel>
        <views:ToolboxView DockPanel.Dock="Left"
                                Width="120" 
                                IsHitTestVisible="True"
                                DataContext="{Binding ToolBoxViewModel}" 
                                x:Name="ToolboxView">

            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:InvokeCommandAction Command="{Binding Path=DataContext.SelectionChangedCommand,  RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                                           CommandParameter="{Binding ElementName=ToolboxOverlayView}"/>
                </i:EventTrigger>
           </i:Interaction.Triggers>

现在我所说的 "embeded selection" 是列表框的行为,我可以在其中突出显示列表框内的元素并 select 它。这与上面的代码完美配合(我可以 select 我的工具,绑定在 ViewModel 中的 属性 相应地改变)。我想要做的是触发 SelectionChanged 事件以在列表框中的特定类别元素被 selected 时执行特殊工作。

我可以在绑定到列表框的 ItemSelected 的 属性 的 setter 中执行此操作,但是要做的工作需要列表框视图模型中未知的数据,这就是为什么我有一个 mainwindow 包含列表框视图模型的视图模型,我尝试在主 window 视图模型(和另一个视图模型)中获取 SelectionChanged 事件。

如果不清楚请告诉我。

您正在尝试在不知道任何 SelectionChanged 事件的 ToolboxView 中设置 SelectionChanged 事件。

您可以在存储命令及其参数的 ToolboxView 中创建两个 DP:

#region SelectionChangedCommand 

public ICommand SelectionChangedCommand
{
    get { return (ICommand)GetValue(SelectionChangedCommandProperty); }
    set { SetValue(SelectionChangedCommandProperty, value); }
}

private readonly static FrameworkPropertyMetadata SelectionChangedCommandMetadata = new FrameworkPropertyMetadata {
    DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};

public static readonly DependencyProperty SelectionChangedCommandProperty = 
    DependencyProperty.Register("SelectionChangedCommand", typeof(ICommand), typeof(ToolboxView), SelectionChangedCommandMetadata);
#endregion


#region SelectionChangedCommandParameter 

public Object SelectionChangedCommandParameter
{
    get { return (Object)GetValue(SelectionChangedCommandParameterProperty); }
    set { SetValue(SelectionChangedCommandParameterProperty, value); }
}

private readonly static FrameworkPropertyMetadata SelectionChangedCommandParameterMetadata = new FrameworkPropertyMetadata {
    DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};

public static readonly DependencyProperty SelectionChangedCommandParameterProperty = 
    DependencyProperty.Register("SelectionChangedCommandParameter", typeof(Object), typeof(ToolboxView), SelectionChangedCommandParameterMetadata);
#endregion

然后在 ToolboxView.xaml:

<Grid>
    <ListBox
        ItemsSource="{Binding Tools}"
        SelectedItem="{Binding SelectedTool}"
        x:Name="ToolView" >
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectionChanged">
                <i:InvokeCommandAction Command="{Binding Path=SelectionChangedCommand,  RelativeSource={RelativeSource AncestorType={x:Type ToolboxView}}}"
                                       CommandParameter="{Binding Path=SelectionChangedCommandParameter,  RelativeSource={RelativeSource AncestorType={x:Type ToolboxView}}}"/>
            </i:EventTrigger>
       </i:Interaction.Triggers>
        <ListBox.ItemTemplate>
            <DataTemplate DataType="interfaces:IBuilder">
                <TextBlock 
                    FontWeight="DemiBold"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    Text="{Binding Name}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

并在MainWindow.xaml中使用它:

<views:ToolboxView DockPanel.Dock="Left"
                    Width="120" 
                    IsHitTestVisible="True"
                    DataContext="{Binding ToolBoxViewModel}" 
                    x:Name="ToolboxView"
                    SelectionChangedCommand="{Binding Path=DataContext.SelectionChangedCommand,  RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                    SelectionChangedCommandParameter="{Binding ElementName=ToolboxOverlayView}"/>