在 WPF 的 TreeView 中为叶节点添加上下文菜单

4
在我的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>

这是代码输出的样子: 我想添加一个包含两个选项的ContextMenu:Rename和Delete,并在ViewModel中添加事件处理程序。我该怎么做?
1个回答

6
这是一篇关于TreeView的好文章。
以下是一个示例应用程序,其中包含重命名上下文菜单。该示例应可帮助您解决问题。
XAML:

http://www.codeproject.com/Articles/26288/Simplifying-the-WPF-TreeView-by-Using-the-ViewMode

<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>

后台代码

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
    }
}

这段代码没有触发RenameCommand事件。如果我将<TreeView.ItemTemplate>更改为<TreeViewItem>,则会触发事件。但在这种情况下,树视图不会使用指定的数据源进行填充。 - WAQ
我刚刚运行了我分享的示例代码,它按预期工作。我正在使用.NET 4.0。你尝试在新项目中运行这段代码了吗? - Anand Murali
是的,我刚刚做到了。这在一个新项目中可行。不知道为什么它没有在我的应用程序中触发事件。 - WAQ
接受您的问题作为答案,因为问题出在我的代码上。针对此问题添加一个新问题。 - WAQ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接