WPF/MVVM - 如何处理双击 ViewModel 中的 TreeViewItems? [英] WPF/MVVM - how to handle double-click on TreeViewItems in the ViewModel?

查看:34
本文介绍了WPF/MVVM - 如何处理双击 ViewModel 中的 TreeViewItems?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(注意 - 这是重新发布的,因为我的第一个问题发布在错误的标题下:这里 对不起!)

(Note - this is a re-post as my first question got posted under wrong headline: Here Sorry!)

我有一个标准的 WPF 树视图,并且绑定了项目来查看模型类.

I have a standard WPF treeview and have bound items to view model classes.

我现在希望处理双击项目时的行为(以视觉工作室风格打开文档).

I now wish to handle behaviour when items are double-clicked (opening documents visual-studio-style).

我可以让事件处理程序在包含树视图的控件中触发(显示为 xaml),但是我如何绑定到视图模型类上的特定行为 - 例如项目视图模型?

I can get event-handler to fire in the control housing the treeview (xaml shown), but how do I bind to specific behaviour on the view model classes - e.g. ProjectViewModel?

首选绑定到 ICommand-implementer,因为它在其他地方使用...

Preferable bound to ICommand-implementer, as this is used elsewhere...

<TreeView ItemsSource="{Binding Projects}" MouseDoubleClick="TreeView_MouseDoubleClick">
    <TreeView.ItemContainerStyle>
        <!-- 
This Style binds a TreeViewItem to a TreeViewItemViewModel. 
-->
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
            <Setter Property="FontWeight" Value="Normal" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="FontWeight" Value="Bold" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </TreeView.ItemContainerStyle>

    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type Implementations:ProjectViewModel}" ItemsSource="{Binding Children}">
            <StackPanel Orientation="Horizontal">
                <Image Width="16" Height="16" Margin="3,0" Source="ImagesRegion.png" />
                <TextBlock Text="{Binding DisplayName}" />
            </StackPanel>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type Implementations:PumpViewModel}" ItemsSource="{Binding Children}">
            <StackPanel Orientation="Horizontal">
                <Image Width="16" Height="16" Margin="3,0" Source="ImagesState.png" />
                <TextBlock Text="{Binding Name}" />
            </StackPanel>
        </HierarchicalDataTemplate>

        <DataTemplate DataType="{x:Type Implementations:PumpDesignViewModel}">
            <StackPanel Orientation="Horizontal">
                <Image Width="16" Height="16" Margin="3,0" Source="ImagesCity.png" />
                <TextBlock Text="{Binding Name}" />
            </StackPanel>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>

推荐答案

稍微更新我的答案.

为此我尝试了很多不同的方法,但我仍然觉得附加行为是最好的解决方案.尽管一开始看起来可能有很多开销,但实际上并非如此.我将 ICommands 的所有行为都保存在同一个地方,每当我需要支持另一个事件时,只需复制/粘贴并更改 PropertyChangedCallback 中的事件.

I've tried alot of different approaches for this and I still feel like Attached Behaviors is the best solution. Although it might look like alot of overhead in the begining it really isn't. I keep all of my behaviors for ICommands in the same place and whenever I need support for another event it is just a matter of copy/paste and change the event in the PropertyChangedCallback.

我还添加了对 CommandParameter 的可选支持.

I also added the optional support for CommandParameter.

在设计器中,只需选择所需的事件

In the designer it is just a matter of selecting the desired event

您可以在 TreeViewTreeViewItem 或任何其他您喜欢的地方设置它.

You can set this either on TreeView, TreeViewItem or any other place that you like.

示例.在 TreeView

<TreeView commandBehaviors:MouseDoubleClick.Command="{Binding YourCommand}"
          commandBehaviors:MouseDoubleClick.CommandParameter="{Binding}"
          .../>

示例.在 TreeViewItem

<TreeView ItemsSource="{Binding Projects}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="commandBehaviors:MouseDoubleClick.Command"
                    Value="{Binding YourCommand}"/>
            <Setter Property="commandBehaviors:MouseDoubleClick.CommandParameter"
                    Value="{Binding}"/>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

这是附加行为 MouseDoubleClick

public class MouseDoubleClick
{
    public static DependencyProperty CommandProperty =
        DependencyProperty.RegisterAttached("Command",
        typeof(ICommand),
        typeof(MouseDoubleClick),
        new UIPropertyMetadata(CommandChanged));

    public static DependencyProperty CommandParameterProperty =
        DependencyProperty.RegisterAttached("CommandParameter",
                                            typeof(object),
                                            typeof(MouseDoubleClick),
                                            new UIPropertyMetadata(null));

    public static void SetCommand(DependencyObject target, ICommand value)
    {
        target.SetValue(CommandProperty, value);
    }

    public static void SetCommandParameter(DependencyObject target, object value)
    {
        target.SetValue(CommandParameterProperty, value);
    }
    public static object GetCommandParameter(DependencyObject target)
    {
        return target.GetValue(CommandParameterProperty);
    }

    private static void CommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
    {
        Control control = target as Control;
        if (control != null)
        {
            if ((e.NewValue != null) && (e.OldValue == null))
            {
                control.MouseDoubleClick += OnMouseDoubleClick;
            }
            else if ((e.NewValue == null) && (e.OldValue != null))
            {
                control.MouseDoubleClick -= OnMouseDoubleClick;
            }
        }
    }

    private static void OnMouseDoubleClick(object sender, RoutedEventArgs e)
    {
        Control control = sender as Control;
        ICommand command = (ICommand)control.GetValue(CommandProperty);
        object commandParameter = control.GetValue(CommandParameterProperty);
        command.Execute(commandParameter);
    }
}

这篇关于WPF/MVVM - 如何处理双击 ViewModel 中的 TreeViewItems?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆