Le problème est que le ItemsControl de la région est stylé mais que ses enfants ne le font pas lorsque la région est utilisée dans un MenuItem. J'ai trouvé une solution en utilisant des menus dynamiques à partir de diverses sources:
WPF Sample Series – Databound HierarchicalDataTemplate Menu Sample
Building a Databound WPF Menu Using a HierarchicalDataTemplate
J'ai créé un IMenuService et MenuItemViewModel dans mon projet d'infrastructure, mettre en œuvre le IMenuService dans mon projet de Shell, et utiliser IMenuService dans mon module pour ajouter un menu.
public interface IMenuService
{
List<MenuItemViewModel> Menu { get; set; }
MenuItemViewModel FileMenu { get; set; }
}
public class MenuItemViewModel : NotificationObject
{
private string _header;
private bool _isEnabled = true;
private ICommand _command;
private Image _icon;
private string _inputGestureText;
private ObservableCollection<MenuItemViewModel> _children;
public MenuItemViewModel()
{
Children = new ObservableCollection<MenuItemViewModel>();
}
public MenuItemViewModel(bool isSeparator) : this()
{
_isSeparator = isSeparator;
}
public string Header
{
get { return _header; }
set
{
_header = value;
RaisePropertyChanged("Header");
}
}
public bool IsEnabled
{
get { return _isEnabled; }
set
{
_isEnabled = value;
RaisePropertyChanged("IsEnabled");
}
}
public ICommand Command
{
get { return _command; }
set
{
_command = value;
RaisePropertyChanged("Command");
}
}
public Image Icon
{
get { return _icon; }
set
{
_icon = value;
RaisePropertyChanged("Icon");
}
}
public string InputGestureText
{
get { return _inputGestureText; }
set
{
_inputGestureText = value;
RaisePropertyChanged("InputGestureText");
}
}
public ObservableCollection<MenuItemViewModel> Children
{
get { return _children; }
set { _children = value; }
}
private bool _isSeparator;
public bool IsSeparator
{
get { return _isSeparator; }
set { _isSeparator = value; }
}
}
MenuService dans le projet Shell:
[Export(typeof(IMenuService))]
public class MenuService : IMenuService
{
[ImportingConstructor]
public MenuService()
{
_menu = new List<MenuItemViewModel>();
_fileMenu = new MenuItemViewModel {Header = "_File"};
_fileMenu.Children.Add(new MenuItemViewModel { Header = "_New" });
_fileMenu.Children.Add(new MenuItemViewModel(true)); // Separator
_menu.Add(_fileMenu);
}
private static Image CreateImage(string url)
{
var image = new Image
{
Source = new BitmapImage(new Uri("Resources/" + url, UriKind.Relative)),
Height = 16,
Width = 16
};
RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.NearestNeighbor);
return image;
}
private List<MenuItemViewModel> _menu;
public List<MenuItemViewModel> Menu
{
get { return _menu; }
set { _menu = value; }
}
private MenuItemViewModel _fileMenu;
public MenuItemViewModel FileMenu
{
get { return _fileMenu; }
set { _fileMenu = value; }
}
}
Dans Shell.xaml
<Window.Resources>
<Style TargetType="{x:Type MenuItem}" x:Key="separatorStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Separator HorizontalAlignment="Stretch" IsEnabled="False"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style BasedOn="{StaticResource {x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding Command}"/>
<Setter Property="Icon" Value="{Binding Icon}"/>
<Setter Property="InputGestureText" Value="{Binding InputGestureText}"/>
<Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
</Style>
<HierarchicalDataTemplate DataType="{x:Type infrastructure:MenuItemViewModel}" ItemsSource="{Binding Path=Children, UpdateSourceTrigger=PropertyChanged}">
<ContentPresenter Content="{Binding Header}" RecognizesAccessKey="True" />
</HierarchicalDataTemplate>
<local:SeparatorStyleSelector x:Key="separatorStyleSelector"/>
Dans le ShellViewModel:
[ImportingConstructor]
public ShellViewModel(IMenuService menuService)
{
Menu = menuService.Menu.ToObservableCollection();
}
private ObservableCollection<MenuItemViewModel> _menu = new ObservableCollection<MenuItemViewModel>();
public ObservableCollection<MenuItemViewModel> Menu
{
get { return _menu; }
set
{
_menu = value;
RaisePropertyChanged("MenuItems");
}
}
Ajout d'un menu à partir du module:
[ModuleExport(typeof(OptionModule))]
public class OptionModule : IModule
{
[ImportingConstructor]
public OptionModule(IMenuService menuService)
{
menuService.ToolsMenu.Children.Add(new MenuItemViewModel {Header = "Options", Command = OptionCommand});
}
}
Voici le SeparatorStyleSelector à partir du site de Karl ci-dessus:
public override Style SelectStyle(object item, DependencyObject container)
{
if (((MenuItemViewModel)item).IsSeparator)
{
return (Style) ((FrameworkElement) container).FindResource("separatorStyle");
}
return base.SelectStyle(item, container);
}
enter code here
peut vous envoyer un échantillon? –