Reputation: 27605
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
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