Wpf 为什么数据绑定上下文菜单项不';你不会隐藏吗?

Wpf 为什么数据绑定上下文菜单项不';你不会隐藏吗?,wpf,data-binding,contextmenu,menuitem,Wpf,Data Binding,Contextmenu,Menuitem,我不想使用数据绑定对象的某些属性在上下文菜单中隐藏/显示菜单项。 但是我的菜单项并没有隐藏,它们的行为就像它们的Visibility将被设置为Visibility一样。隐藏(不是Visibility,实际上是崩溃的),这种行为的原因是什么 下面是一个例子: XAML: 按钮 和代码隐藏: public partial class Window1 : Window { public ObservableCollection<Item> list = new

我不想使用数据绑定对象的某些属性在上下文菜单中隐藏/显示菜单项。 但是我的菜单项并没有隐藏,它们的行为就像它们的Visibility将被设置为Visibility一样。隐藏(不是Visibility,实际上是崩溃的),这种行为的原因是什么

下面是一个例子:

XAML:


按钮
和代码隐藏:

public partial class Window1 : Window
    {
        public ObservableCollection<Item> list = new ObservableCollection<Item>();
        public Window1()
        {
            InitializeComponent();
            list.Add(new Item() { Title = "First", Visible = true }); ;
            list.Add(new Item() { Title = "Second", Visible = false }); ;
            list.Add(new Item() { Title = "Third", Visible = false }); ;
            list.Add(new Item() { Title = "Fourth", Visible = true }); ;
        }

        private void OnClick(object sender, RoutedEventArgs e)
        {
            ContextMenu cm =  FindResource("menu") as ContextMenu;
            cm.PlacementTarget = e.OriginalSource as UIElement;
            cm.Placement = System.Windows.Controls.Primitives.PlacementMode.Left;
            cm.ItemsSource = list;
            cm.IsOpen = true;
        }
    }

    public class Item
    {
        public string Title { get; set; }
        public bool Visible { get; set; }
    }
公共部分类窗口1:窗口
{
公共ObservableCollection列表=新ObservableCollection();
公共窗口1()
{
初始化组件();
Add(newitem(){Title=“First”,Visible=true});
添加(新项(){Title=“Second”,Visible=false});
添加(新项(){Title=“Third”,Visible=false});
添加(新项(){Title=“Fourth”,Visible=true});
}
private void OnClick(对象发送方,RoutedEventArgs e)
{
ContextMenu cm=FindResource(“菜单”)作为ContextMenu;
cm.PlacementTarget=e.OriginalSource作为UIElement;
cm.Placement=System.Windows.Controls.Primitives.PlacementMode.Left;
cm.ItemsSource=列表;
cm.IsOpen=真;
}
}
公共类项目
{
公共字符串标题{get;set;}
公共布尔可见{get;set;}
}

结果是菜单有四个项目(但是中间有两个在标题中没有任何可见的文本)。

这个行为是因为CONTEXT菜单的ITEM模板将被应用于为该项目创建的MeNuItitem中的每个绑定项目。通过将MenuItem放入DataTemplate,可以创建嵌套的MenuItem。即使你折叠了内部的一个,因为外部的一个仍然可见,所以仍然有空间容纳它

您可以通过删除DataTemplate中的嵌套MenuItem并将其替换为TextBlock,并使用适用于MenuItem的样式设置可见性来解决此问题:

<Window x:Class="MenuTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="converter"/>
        <DataTemplate x:Key="template">
            <TextBlock Text="{Binding Title}"/>
        </DataTemplate>
        <ContextMenu x:Key="menu" ItemTemplate="{StaticResource template}">
            <ContextMenu.Resources>
                <Style TargetType="{x:Type MenuItem}">
                    <Setter Property="Visibility" Value="{Binding Visible, Converter={StaticResource converter}}"/>
                </Style>
            </ContextMenu.Resources>
        </ContextMenu>
    </Window.Resources>
    <Grid>
        <Button HorizontalAlignment="Center" VerticalAlignment="Center" Click="OnClick">Button</Button>
    </Grid>
</Window>

按钮

哇,太快了。谢谢我以为我在史努比查过了,但显然我错了谢谢你的帮助。。这也解决了我的问题。
<Window x:Class="MenuTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="converter"/>
        <DataTemplate x:Key="template">
            <TextBlock Text="{Binding Title}"/>
        </DataTemplate>
        <ContextMenu x:Key="menu" ItemTemplate="{StaticResource template}">
            <ContextMenu.Resources>
                <Style TargetType="{x:Type MenuItem}">
                    <Setter Property="Visibility" Value="{Binding Visible, Converter={StaticResource converter}}"/>
                </Style>
            </ContextMenu.Resources>
        </ContextMenu>
    </Window.Resources>
    <Grid>
        <Button HorizontalAlignment="Center" VerticalAlignment="Center" Click="OnClick">Button</Button>
    </Grid>
</Window>