在XAML的TreeView中未选择任何内容时,禁用TreeView上下文菜单项

时间:2014-10-21 08:30:48

标签: wpf xaml treeview contextmenu

如果树视图的SelectedItem属性为null,我试图在树视图的上下文菜单中禁用某些菜单项。我的期望是,通过将TreeView的SelectedItem属性绑定到MenuItem的IsEnabled属性并在其间使用转换器,这将是最简单的实现。

我还没有特别的WPF经验,所以我猜测我的绑定有问题。

我已经找到this解决方案,无论何时打开菜单,都会手动强制使用IsEnabled属性,但它似乎不是我的理想解决方案。如果在树视图中没有选择任何内容,那么添加新菜单项的人就不会立即清楚他们需要修改后面的代码来禁用他们的新菜单项。如果我试图通过绑定(或其他一些XAML解决方案)实现的目标是不可能的,那么我将采用这种强力解决方案。

这是我到目前为止的一个简单示例:

MainWindow.xaml

<Window x:Class="treeViewTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:treeViewTest="clr-namespace:treeViewTest"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <treeViewTest:NullObjectToDisabledConverter
            x:Key="NullObjectToDisabledConverter" />
    </Window.Resources>

    <Grid>
        <TreeView Name="treeView" MouseLeftButtonDown="treeView_MouseLeftButtonDown">
            <TreeViewItem Header="Parent" IsExpanded="True">
                <TreeViewItem Header="Child" />
            </TreeViewItem>
            <TreeViewItem Header="Sibling" />

            <TreeView.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Copy"
                        IsEnabled="{Binding ElementName=treeView, Path=SelectedItem,
                        Converter={StaticResource NullObjectToDisabledConverter}}" />
                    <MenuItem Header="Paste"
                        IsEnabled="{Binding ElementName=treeView, Path=SelectedItem,
                        Converter={StaticResource NullObjectToDisabledConverter}}" />
                </ContextMenu>
            </TreeView.ContextMenu>
        </TreeView>
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;

namespace treeViewTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

        }

        private void treeView_MouseLeftButtonDown(object sender,
            MouseButtonEventArgs e)
        {
            TreeViewItem node = treeView.SelectedItem as TreeViewItem;
            if (node != null)
            {
                node.IsSelected = false;
            }
        }
    }

    public class NullObjectToDisabledConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter,
            CultureInfo culture)
        {
            return (value != null);
        }

        public object ConvertBack(object value, Type targetType, object parameter,
            CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

我尝试在转换器中返回false以强制禁用菜单项但转换器实际上从未被调用。

提前感谢任何帮助,了解为什么这不起作用。

1 个答案:

答案 0 :(得分:2)

这是使用DataTrigger

的解决方法
<TreeView Name="treeView">
    <TreeViewItem Header="Parent"
                  IsExpanded="True">
        <TreeViewItem Header="Child" />
    </TreeViewItem>
    <TreeViewItem Header="Sibling" />
    <TreeView.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Copy"
                      x:Name="copy">
                <MenuItem.Style>
                    <Style TargetType="MenuItem">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding PlacementTarget.SelectedItem,RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}}"
                                         Value="{x:Null}">
                                <Setter Property="IsEnabled"
                                        Value="False" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </MenuItem.Style>
            </MenuItem>
            <MenuItem Header="Paste" />
        </ContextMenu>
    </TreeView.ContextMenu>
</TreeView>

如果没有选定项目,此示例将禁用第一个菜单项。同样可以适用于其他人

试一试,看看这是不是你想要的。