右键单击MVVM,在treeView中选择节点

时间:2013-08-03 06:29:53

标签: wpf xaml treeview

我想在右键单击中选择树视图的节点。我正在使用MVVM模式,并且不希望在后面的代码中实现这一点。这是我的树视图XAML。

<TreeView Margin="5,0,0,5"  ItemsSource="{Binding TreePads}">
<TreeView.ItemContainerStyle >
    <Style TargetType="{x:Type TreeViewItem}">
        <Setter Property="IsSelected" Value="{Binding DataContext.IsSelected, Mode=TwoWay,  RelativeSource={RelativeSource Self}}" />
        <Setter Property="ContextMenu">
            <Setter.Value>
                <ContextMenu  DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" >
                    <MenuItem IsEnabled="{Binding RenameMenuEnabled}" Header="Rename" Command="{Binding RenameCommand}" />
                </ContextMenu>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
            </Trigger>
        </Style.Triggers>
    </Style>
</TreeView.ItemContainerStyle >
<TreeView.Resources>
    <HierarchicalDataTemplate DataType="{x:Type vm:TreePad}" ItemsSource="{Binding Members, Mode=TwoWay}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding PadName}"/>
        </StackPanel>
    </HierarchicalDataTemplate>
</TreeView.Resources>

2 个答案:

答案 0 :(得分:10)

您可以定义DependencyProperty。下面我分享了一个示例应用程序,它使用依赖属性来实现此目的。

TreeViewExtension.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace WpfApplication1
{
    public static class TreeViewExtension
    {
        public static readonly DependencyProperty SelectItemOnRightClickProperty = DependencyProperty.RegisterAttached(
           "SelectItemOnRightClick",
           typeof(bool),
           typeof(TreeViewExtension),
           new UIPropertyMetadata(false, OnSelectItemOnRightClickChanged));

        public static bool GetSelectItemOnRightClick(DependencyObject d)
        {
            return (bool)d.GetValue(SelectItemOnRightClickProperty);
        }

        public static void SetSelectItemOnRightClick(DependencyObject d, bool value)
        {
            d.SetValue(SelectItemOnRightClickProperty, value);
        }

        private static void OnSelectItemOnRightClickChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            bool selectItemOnRightClick = (bool)e.NewValue;

            TreeView treeView = d as TreeView;
            if (treeView != null)
            {
                if (selectItemOnRightClick)
                    treeView.PreviewMouseRightButtonDown += OnPreviewMouseRightButtonDown;
                else
                    treeView.PreviewMouseRightButtonDown -= OnPreviewMouseRightButtonDown;
            }
        }

        private static void OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            TreeViewItem treeViewItem = VisualUpwardSearch(e.OriginalSource as DependencyObject);

            if (treeViewItem != null)
            {
                treeViewItem.Focus();
                e.Handled = true;
            }
        }

        public static TreeViewItem VisualUpwardSearch(DependencyObject source)
        {
            while (source != null && !(source is TreeViewItem))
                source = VisualTreeHelper.GetParent(source);

            return source as TreeViewItem;
        }
    }
}

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mvvmhelper="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TreeView mvvmhelper:TreeViewExtension.SelectItemOnRightClick="true">
            <TreeViewItem Header="One"/>
            <TreeViewItem Header="Two"/>

            <TreeViewItem Header="Three"/>
            <TreeView.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Menu1"/>
                    <MenuItem Header="Menu2"/>
                </ContextMenu>
            </TreeView.ContextMenu>
        </TreeView>
    </Grid>
</Window>

答案 1 :(得分:0)

您可以使用互动

xmlns:interactive="http://schemas.microsoft.com/expression/2010/interactivity"

xaml:

<TreeView x:Name="TreeView" HorizontalAlignment="Left" Height="373" Margin="13,15,0,0" VerticalAlignment="Top" Width="373" Background="#29292f" 
                  Foreground="White" BorderBrush="Transparent" BorderThickness="0" ItemsSource="{Binding EmtRoot}" FontSize="24" >
            <interactive:Interaction.Triggers>
                <interactive:EventTrigger EventName="SelectedItemChanged">
                    <interactive:InvokeCommandAction Command="{Binding SelectItemCommand}" CommandParameter="{Binding ElementName=TreeView,Path=SelectedItem}"/>
                </interactive:EventTrigger> 
            </interactive:Interaction.Triggers>
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type models:EmtRootModel}" ItemsSource="{Binding Entities}">
                    <TextBlock Text="Root" Foreground="White" ContextMenu="{StaticResource ContextMenuLevel0}"/>
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type models:EntityModel}" ItemsSource="{Binding Slides}">
                    <TextBlock Text="{Binding EntityName}" Foreground="White" ContextMenu="{StaticResource ContextMenuLevel1}"/>
                </HierarchicalDataTemplate>
                <DataTemplate DataType="{x:Type models:SlideModel}">
                    <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource ContextMenuLevel2}">
                        <StackPanel.InputBindings>
                            <MouseBinding MouseAction="RightClick"
                                                Command="{Binding ElementName=Emt,Path=DataContext.TreeViewRightClickCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=TreeViewItem}}"/>
                        </StackPanel.InputBindings>
                        <TextBlock Text="{Binding SlideName}" Foreground="White">
                            <TextBlock.InputBindings>
                                <MouseBinding MouseAction="LeftDoubleClick"
                                                Command="{Binding ElementName=Emt,Path=DataContext.SlideDoubleClickCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=TextBlock},Path=DataContext}"/>
                            </TextBlock.InputBindings>
                        </TextBlock>
                        <CheckBox IsChecked="{Binding IsChecked}" Foreground="White" />
                    </StackPanel>
                </DataTemplate>
            </TreeView.Resources>
      </TreeView>

在viewModel中:

 private void ExecuteTreeViewRightClickCommand(object obj)
        {
            ((TreeViewItem)obj).IsSelected = true;
            SelectedSlide = ((TreeViewItem)obj).Header as SlideModel;
        }