heltonbiker
heltonbiker

Reputation: 27605

How to have different menus for each application screen in WPF

My application has three screens: Overview, CreateActivity and ViewActivities.

When I am in the CreateActivity, I want to show some menus that only make sense for that screen, and the same goes to ViewActivities screen, which will have yet another exclusive menus.

That is similar to what happens nowadays in Microsoft Office: you click in some tab, and some extra menu entries appear in the menu-bar, related to that tab.

How should I implement this in WPF?

Currently, my main window is like shown below. There is one property ActiveScreen of type ViewModelBase, and I would like to bind menubar content to each different of my three screens.

<Window
        (...)
        x:Class="CompanyNamespace.Product.Views.ShellView">

    <Window.DataContext>
        <vm:ShellViewModel/>
    </Window.DataContext>

    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <!-- What here? -->
        </Menu>
        <ContentControl Content="{Binding ActiveScreen}"/>
    </DockPanel>

</Window>

Upvotes: 2

Views: 224

Answers (1)

Bizhan
Bizhan

Reputation: 17095

My suggestion is to change Visibility of each Menu/MenuItem.

First create an enum with flags attribute. I could add an item All = 7 but in this case there is no need to do that. instead simply remove Visibility="..." part from MenuItem in XAML

[Flags]
public enum MenuSetTypes
{
    //I prefer adding a None in flags mode
    None = 0,

    //main items
    Overview = 1,
    CreateActivity = 2,
    ViewActivities = 4,

    //define multi state items
    OverviewAndCreate = 3,
    CreateAndView = 6,
}

Add a bindable property to view model

public MenuSetTypes MenuSetType { ... } 

MenuItem XAML:

<MenuItem Header="SomeMenuVisibileInOverViewAndCreate"
          Visibility="{Binding ActiveScreen.MenuSetType,
          Converter={StaticResource MenuTypeToVisibilityConverter},
          ConverterParameter={x:Static enums:MenuSetTypes.OverviewAndCreate}}"/>

Converter code:

public class MenuTypeToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        //value & param highlights enum items that are in both value and param
        //so that by comparing it with None we can tell if there is any
        //overlapped enum item or not 
        return ((MenuSetTypes)value & (MenuSetTypes)parameter) == MenuSetTypes.None ?
             Visibility.Collapsed : Visibility.Visible;
    }

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

Upvotes: 1

Related Questions