Я не хочу скрывать / показывать элементы меню в контекстном меню, используя некоторые свойства объекта привязки к данным. Но мои элементы меню не скрываются, они ведут себя так, как если бы для их Visiblity было установлено значение Visibility.Hidden (а не Visibility.Collapsed, как это есть на самом деле), в чем причина такого поведения?
Вот пример:
XAML:
<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">
<MenuItem Visibility = "{Binding Visible, Converter = {StaticResource converter}}" Header = "{Binding Title}" />
</DataTemplate>
<ContextMenu x:Key = "menu" ItemTemplate = "{StaticResource template}"/>
</Window.Resources>
<Grid>
<Button VerticalAlignment = "Center" HorizontalAlignment = "Center" Click = "OnClick">Button</Button>
</Grid>
</Window>
И код позади:
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; }
}
Результатом является меню с четырьмя пунктами (но два посередине без видимого текста в заголовке).





Такое поведение вызвано тем, что ItemTemplate из ContextMenu будет применяться к каждому из ваших связанных элементов в MenuItem, созданных для этого элемента. Помещая MenuItem в свой DataTemplate, вы создаете вложенный MenuItem. Даже если вы свернете внутреннюю, поскольку внешняя все еще видна, для нее все равно останется место.
Вы можете исправить это, избавившись от вложенного MenuItem в вашем DataTemplate и заменив его TextBlock, а также используя Style, который применяется к 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>
Спасибо за помощь .. Это также устранило мою проблему.
Вау, это было быстро. Спасибо. Думал, что проверил в Снупе, но видимо ошибался. ;)