Question

Je wan't pour cacher / menuitems spectacle dans un contextmenu utilisant une propery d'objet databound. Mais mes menuitems ne se cachent pas, ils se comportent comme si leur serait mis Visibilité à Visibility.Hidden (non Visibility.Collapsed comme il est vraiment), quelle est la raison d'un tel comportement?

Voici un exemple:

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>

Et le code derrière:

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

Le résultat est menu avec quatre éléments (mais deux au milieu sans texte visible en-tête).

Était-ce utile?

La solution

Ce comportement est parce que le ItemTemplate ContextMenu sera appliqué à chacun de vos objets liés dans les MenuItem créé pour cet article. En mettant un MenuItem dans votre DataTemplate, vous créez un MenuItem imbriqué. Même si vous réduisez l'intérieure, puisque l'externe est encore visible, il y a encore de la place pour elle.

Vous pouvez résoudre ce problème en se débarrassant de la MenuItem imbriqué dans votre DataTemplate et le remplacer par un TextBlock, et en utilisant un style qui applique à MENUITEM pour définir la visibilité:

<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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top