thitemple
thitemple

Reputation: 6059

Dynamically hiding menu items

I have a menu built with xaml, and the MenuItem has the property ItemTemplate set to the following template:

<HierarchicalDataTemplate x:Key="MenuItemTemplate" DataType="{x:Type mainMenu:MenuItem}" ItemsSource="{Binding ChildMenuItems}">
     <MenuItem Command="{Binding Command}" CommandParameter="{Binding CommandParameter}" Header="{Binding Path=Header}" Visibility="{Binding Visible, Converter={converter:BooleanToVisibilityConverter}}" />
</HierarchicalDataTemplate>

When I change the value of the property Visible to false with the intention of hiding the sub-menu what I have as a result is this:

enter image description here

The sub-menus are hidden but they still take some space. How can I change that to adapt to the number of items left in the menu?

Edit:

Here's the code from the converter:

public class BooleanToVisibilityConverter : MarkupExtension, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (bool) value ? Visibility.Visible : Visibility.Collapsed;
    }
}

Upvotes: 4

Views: 4604

Answers (3)

Sheridan
Sheridan

Reputation: 69985

You shouldn't be using a HierarchicalDataTemplate to define your child MenuItems. Instead, try using the MenuItem.ItemsSource property:

<DataTemplate x:Key="MenuItemTemplate" DataType="{x:Type mainMenu:MenuItem}">
    <MenuItem Command="{Binding Command}" CommandParameter="{Binding CommandParameter}"
        Header="{Binding Path=Header}" Visibility="{Binding Visible, Converter={
        converter:BooleanToVisibilityConverter}}" 
        ItemsSource="{Binding ChildMenuItems}" />
</DataTemplate>

UPDATE >>>

Yeah sorry, you need to set the child MenuItem properties in a Style set as the MenuItem.ItemContainerStyle. Rather than explain it all here, I prefer to direct you to the Binding menus using HeirarchicalDataTemplates page from Lester's WPF\SL Blog on MSDN, which explains how to do it well.

Also, if you're going to data bind the MenuItems, then you might as well remove the relevant items from the data bound collection instead of trying to set the Visibility. The UI will look the same, but it will be much simpler. It's always best to manipulate the data elements in WPF when you can, rather than the UI elements.

Upvotes: 1

paparazzo
paparazzo

Reputation: 45106

I did not test with binding but I have used successfully used binding in style before

<Menu>
    <Menu.Resources>
        <Style TargetType="MenuItem">
            <Setter Property="Visibility" Value="Collapsed" />
        </Style>
    </Menu.Resources>
    <MenuItem Header="ONe" />
    <MenuItem Header="Two" />
    <MenuItem Header="Three" />
</Menu>

Upvotes: 0

Rohit Vats
Rohit Vats

Reputation: 81333

I suspect you are returning Visibility.Hidden from your converter. Instead return Visibility.Collapsed.

From MSDN:

enter image description here


Moreover WPF provides BooleanToVisibilityConverter, you don't need to re-define it unless doing something extra. You can add resource under App resource section like this and use:

<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>

Upvotes: 2

Related Questions