Q: How do you arrange for the following menu item scenarios #956
Replies: 4 comments
-
On the first question, is the default |
Beta Was this translation helpful? Give feedback.
-
The regular For point 2, it's usually done with a combination of commands, |
Beta Was this translation helpful? Give feedback.
-
Thank you so much for the thoughtful guidance in response. I am sort of successful at persuading a model first, view model menuing strategy, but I am having this difficulty, so strange. Not sure how/why the parent Window is failing to see it as the main menu. <Menu IsMainMenu="True" Height="auto" ItemsSource="{Binding Path=MenuItems}">
<Menu.Resources>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding Command}" />
<Setter Property="Header" Value="{Binding Header}" />
<Setter Property="Icon">
<Setter.Value>
<Image Source="{Binding MenuIcon}" Height="16px" Width="16px" />
</Setter.Value>
</Setter>
<Setter Property="ItemsSource" Value="{Binding Items}"/>
</Style>
</Menu.Resources>
</Menu> I do not think the All that being mapped to my top level // Top level `System.Windows.Controls.MenuItem`
public virtual ICollection<MenuItem> MenuItems { get; private set; } = new List<MenuItem> { };
// ...
private void InitializeMenuItems(ICollection<MenuItem> menuItems)
{
static IEnumerable<MenuItem> CreateMenuItems()
{
yield return new Views.FileMenuItem();
}
foreach (var menuItem in CreateMenuItems())
{
menuItems.Add(menuItem);
}
OnPropertyChanged(nameof(MenuItems));
} Eventually would also like to facilitate things like checkbox menu items, or a group of radio button items. But first things first, baby steps building up some confidence here, and proficiencies. Actually in the space of this post, I figured out the first bit of rendering, something really dumb like the default XAML injected <MenuItem x:Class="Ellumination.ServiceWatcher.Views.FileMenuItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
mc:Ignorable="d" Header="_File">
<MenuItem.Items>
<ui:MenuItem Header="E_xit" Command="{Binding Path=ExitCommand}"/>
</MenuItem.Items>
</MenuItem> // This is the top level menu item, which perhaps the children could be mapped better, not as a 'flat view model'
public partial class FileMenuItem : MenuItem
{
// Probably do not need Header view models here
// But there are definitely some use cases where those need to be bound to the view model
public ICommand ExitCommand { get; private set; }
private void OnExit()
{
Application.Current.MainWindow.Close();
}
public FileMenuItem()
{
InitializeComponent();
ExitCommand = new RelayCommand(OnExit);
}
} Now the issue is that the My goal there is of couse to do it more properly the MVVM way, the views doing their bit of the work, and the view models wiring up what they are responsible toward as well. MVVM being facilitated by |
Beta Was this translation helpful? Give feedback.
-
On the radio button operation, so far kind of taking a semi-crude approach at the issue. Actually, I am not hating it. The only way I might like to think about improving it, is by somehow enumerating of a range of the Have seen a couple similar approaches, involving In the view model... Stubbed in descriptions, the thought being to enumerate the values and map it somehow to [Description("Large Icons")]
public virtual bool ViewStyleLargeIcons
{
get => ViewStyle == ViewStyleType.LargeIcons;
set => ViewStyle = ViewStyleType.LargeIcons;
}
[Description("Small Icons")]
public virtual bool ViewStyleSmallIcons
{
get => ViewStyle == ViewStyleType.SmallIcons;
set => ViewStyle = ViewStyleType.SmallIcons;
}
[Description("List")]
public virtual bool ViewStyleList
{
get => ViewStyle == ViewStyleType.List;
set => ViewStyle = ViewStyleType.List;
}
[Description("Details")]
public virtual bool ViewStyleDetails
{
get => ViewStyle == ViewStyleType.Details;
set => ViewStyle = ViewStyleType.Details;
}
private ViewStyleType _style = ViewStyleType.Details;
public virtual ViewStyleType ViewStyle
{
get => _style;
set => SetProperty(ref _style, value);
}
// ...
private void OnPropertyChanging(object? sender, PropertyChangingEventArgs e)
{
switch (e.PropertyName)
{
case nameof(ViewStyle) when ReferenceEquals(sender, this):
OnPropertyChanging(nameof(ViewStyleLargeIcons));
OnPropertyChanging(nameof(ViewStyleSmallIcons));
OnPropertyChanging(nameof(ViewStyleList));
OnPropertyChanging(nameof(ViewStyleDetails));
break;
}
}
private void OnPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(ViewStyle) when ReferenceEquals(sender, this):
OnPropertyChanged(nameof(ViewStyleLargeIcons));
OnPropertyChanged(nameof(ViewStyleSmallIcons));
OnPropertyChanged(nameof(ViewStyleList));
OnPropertyChanged(nameof(ViewStyleDetails));
break;
}
} And the subsequent XAML, somewhat cleaner looking that it was under this approach. INPC and the view model properties are doing the heavier lifting. <!-- again here Header would be better mapped property DescriptionAttribute -->
<!-- or better still replace the VM prop approach altogether with direct enum value integration -->
<ui:MenuItem Header="Large Icons" IsCheckable="True" IsChecked="{Binding ViewStyleLargeIcons}" />
<ui:MenuItem Header="Small Icons" IsCheckable="True" IsChecked="{Binding ViewStyleSmallIcons}" />
<ui:MenuItem Header="List" IsCheckable="True" IsChecked="{Binding ViewStyleList}" />
<ui:MenuItem Header="Details" IsCheckable="True" IsChecked="{Binding ViewStyleDetails}" /> One last tidbit, nice to have aspiration. Would like to change the default checkbox rendering for these radio button group style For what it is, "it works", but I think I could do better, not quite sure how yet. |
Beta Was this translation helpful? Give feedback.
-
Assumed first in WPF, and second with Wpf.Ui in particular.
First, separator menu items? I've read some of the blogs commonly discovered on the matter, but I am still confused. Is there a
SeparatorMenuItem
class I need to add in a model, view model, etc? Not clear how that is wired up in the view.Second, arranging for access keys. or alias keys. I see how to specify
MenuItem.Header
for instance, i.e."_File"
, but then how to connect a function key (i.e.F5
) or alias (i.e.Ctrl+E
), and so on. I do not see any properties in the MenuItem which lend themselves to this, or what the XAML guidance might be on the subject.Would very much like for these to be model driven, model first, if you will, if at all possible.
Thank you!
Beta Was this translation helpful? Give feedback.
All reactions