wpf 右键单击 MVVM 在 treeView 中选择节点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18030055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Select node in treeView on right click MVVM
提问by WAQ
I want to select a node of tree view on right click. I am using MVVM pattern and don't want to achieve this in code behind. Here is my XAML for tree view.
我想在右键单击时选择树视图的节点。我正在使用 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>
回答by Anand Murali
You could define a DependencyProperty. Below I have shared a sample app which uses a dependency property to achieve this.
您可以定义一个DependencyProperty. 下面我分享了一个示例应用程序,它使用依赖属性来实现这一点。
TreeViewExtension.cs
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:
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>
回答by Markel Eddie
You can use interactivity
您可以使用交互性
xmlns:interactive="http://schemas.microsoft.com/expression/2010/interactivity"
The xaml:
xml:
<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>
And in the viewModel:
在视图模型中:
private void ExecuteTreeViewRightClickCommand(object obj)
{
((TreeViewItem)obj).IsSelected = true;
SelectedSlide = ((TreeViewItem)obj).Header as SlideModel;
}

