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

时间:2016-07-05 17:07:54

标签: c# wpf mvvm listbox viewmodel

Hello Stackoverflowers,

我有一个System.Windows.Control.ListBox。它做得很好但我想在选择某些类型的物品时有一些行为。

我无法在SelectedItem的bind属性中执行此操作,因为我的Listbox的View Model(Foo)并不知道我想要的工作所需的所有数据(一些来自另一个ViewModel :Bar)。

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

我使用Interaction.Triggers,EventTrigger和InvokeCommandAction将Foo和Bar中的click事件发送到Zot。它对Bar(这是一个画布)很有用。但是我的列表框有问题。

在测试事件SelectionChanged,MouseDown和Click之后,如果我单击包含列表框的网格而不是单击ListBox时,似乎会触发MouseDown。感觉列表框中的嵌入选择与其他事件冲突。

任何人都有任何想法在不同的视图模型中根据所选项目执行特定操作?

非常感谢

编辑:

这是Listbox的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>

这是Listbox上的事件,来自主窗口xaml(该视图模型包含列表框视图模型,我在下面解释了原因)。但是事件永远不会被触发。稍后在同一个文件中,3个类似的事件完美地工作(在画布上)。我尝试使用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>

现在我称之为&#34;嵌入选择&#34;是列表框的行为,我可以突出显示列表框中的元素并选择它。这与上面的代码完美配合(我可以选择我的工具,ViewModel中绑定的属性相应地更改)。我正在尝试做的是在选择列表框中的某些元素类别时触发SelectionChanged事件以执行特殊工作。

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

请告诉我,请不要清楚。

1 个答案:

答案 0 :(得分:1)

您正试图在ToolboxView中设置一个不知道任何SelectionChanged事件的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}"/>