将上下文菜单添加到 TreeView WPF 中的叶节点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17499821/
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
Adding context menu to leaf node in TreeView WPF
提问by WAQ
In my WPF application, I want to add a context menu and its handler in ViewModelto the leaf nodes of my TreeViewcontrol. Here is how I have added the TreeViewControl.
在我的 WPF 应用程序中,我想将上下文菜单及其处理程序添加ViewModel到我的TreeView控件的叶节点中。这是我添加TreeView控件的方式。
<TreeView Name="treePads" ItemsSource="{Binding pads}" Width="190">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type self:Pad}" ItemsSource="{Binding Members}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Text=" [" Foreground="Blue" />
<TextBlock Text="{Binding Members.Count}" Foreground="Blue" />
<TextBlock Text="]" Foreground="Blue" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type self:PadInfo}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="["></TextBlock>
<TextBlock Text="{Binding SlotID}" />
<TextBlock Text="] ["></TextBlock>
<TextBlock Text="{Binding WellID}" />
<TextBlock Text="]"></TextBlock>
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
Here is how the output of this code looks like:
这段代码的输出如下所示:


I want to add a ContextMenuhaving two options: Rename, Deleteand add there event handlers to the ViewModel. How can I do that?
我想添加一个ContextMenu有两个选项:Rename,Delete并将那里的事件处理程序添加到ViewModel. 我怎样才能做到这一点?
回答by Anand Murali
This is good article on TreeView
这是一篇关于 TreeView
http://www.codeproject.com/Articles/26288/Simplifying-the-WPF-TreeView-by-Using-the-ViewMode
http://www.codeproject.com/Articles/26288/Simplifying-the-WPF-TreeView-by-Using-the-ViewMode
Below I have shared a sample app which has a Rename Context Menu. The sample should help you to fix your problem.
下面我分享了一个具有重命名上下文菜单的示例应用程序。该示例应该可以帮助您解决问题。
XAML:
XAML:
<TreeView Name="treeView">
<TreeView.ItemContainerStyle>
<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" />
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Rename" Command="{Binding RenameCommand}"/>
</ContextMenu>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubElements}">
<StackPanel Orientation="Horizontal">
<!--<Image Margin="2" Source="{Binding ImageLocation}" Height="30" Width="30"/>-->
<TextBlock Margin="2" Text="{Binding HeaderText}" ></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Code behind
背后的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<TreeViewElement> elements = new List<TreeViewElement>();
TreeViewElement mainElement = new TreeViewElement() { ImageLocation = "Images/1.png", HeaderText = "MainElement1" };
mainElement.SubElements = new List<TreeViewElement>();
mainElement.SubElements.Add(new TreeViewElement() { ImageLocation = "Images/2.png", HeaderText = "SubElement1" });
mainElement.SubElements.Add(new TreeViewElement() { ImageLocation = "Images/2.png", HeaderText = "SubElement2", BackgroundColor = "Blue" });
elements.Add(mainElement);
TreeViewElement mainElement2 = new TreeViewElement() { HeaderText = "MainElement2" };
elements.Add(mainElement2);
this.treeView.ItemsSource = elements;
}
}
public class TreeViewElement
{
public string ImageLocation { get; set; }
public string HeaderText { get; set; }
public string BackgroundColor { get; set; }
public List<TreeViewElement> SubElements { get; set; }
private ICommand _RenameCommand;
public ICommand RenameCommand
{
get {
if (_RenameCommand == null)
{
_RenameCommand = new RelayCommand((o) =>
{
// Your logic should go here
MessageBox.Show("HeaderText is " +HeaderText);
});
}
return _RenameCommand; }
}
}
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion // ICommand Members
}
}

