WPF 功能区绑定到 ViewModel HierarchicalDataTemplate 奇怪的行为
WPF Ribbon Binding to ViewModel HierarchicalDataTemplate Strange behaviour
我的计划是构建一个大型 WPF 应用程序,其中包含多个用户控件作为按需加载的模块。这些模块提供自己的菜单项列表,显示在主 window.
提供的菜单是MenuTab的列表objects。
public class MenuTab
{
private string _label;
private List<MenuGroup> _menuGroups = new List<MenuGroup>();
public string Label
{
get { return _label; }
set { _label = value; }
}
public List<MenuGroup> MenuGroups
{
get { return _menuGroups; }
}
public MenuTab(string label)
{
Label = label;
}
}
public class MenuGroup
{
private string _label;
private string _description;
private List<MenuEntry> _menuEntries = new List<MenuEntry>();
public string Label
{
get { return _label; }
set { _label = value; }
}
public string Description
{
get { return _description; }
set { _description = value; }
}
public List<MenuEntry> MenuEntries
{
get { return _menuEntries; }
}
public MenuGroup(string label)
{
Label = label;
}
}
public class MenuEntry
{
private string _label;
private BitmapSource _largeImage;
private BitmapSource _smallImage;
private ICommand _command;
public string Label
{
get { return _label; }
set { _label = value; }
}
public BitmapSource LargeImage
{
get { return _largeImage; }
set { _largeImage = value; }
}
public BitmapSource SmallImage
{
get { return _smallImage; }
set { _smallImage = value; }
}
public ICommand Command
{
get { return _command; }
set { _command = value; }
}
public MenuEntry(string label)
{
Label = label;
}
}
我在 Internet 上找到了多个关于如何构建菜单以添加其他静态菜单等的提示。
这里是我构建菜单和 HierarchicalDataTemplate 的方法,它们基本上会产生正确数量的选项卡、组和项目。
即使是命令绑定也能正常工作。
<RibbonWindow.Resources>
<Style x:Key="ModuleGroup" TargetType="RibbonGroup">
<Setter Property="Background" Value="AntiqueWhite" />
<Setter Property="Foreground" Value="Green" />
</Style>
<HierarchicalDataTemplate DataType="{x:Type CommonModel:MenuTab}" ItemsSource="{Binding Path=MenuGroups}">
<RibbonTab Header="{Binding Path=Label}" Background="Orange" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type CommonModel:MenuGroup}" ItemsSource="{Binding Path=MenuEntries}">
<RibbonGroup Header="{Binding Path=Label}" Style="{StaticResource ModuleGroup}" />
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type CommonModel:MenuEntry}">
<RibbonButton Label="{Binding Path=Label}" LargeImageSource="{Binding Path=LargeImage}" SmallImageSource="{Binding Path=SmallImage}" Command="{Binding Path=Command}" />
</DataTemplate>
<CollectionViewSource x:Key="ModuleMenuTabs" Source="{Binding ModuleMenu}"/>
</RibbonWindow.Resources>
然后在我的静态选项卡之间:
<CollectionContainer Collection="{Binding Source={StaticResource ModuleMenuTabs}}"/>
但选项卡 header 和背景未显示为异常。而且生成的组的背景也不例外(例如,我向其中一个工作正常的静态组添加了一些背景。)
谁能告诉我如何正确生成色带?
现在有回复后,我自己做了进一步的研究和测试。
我找到了适合我的解决方案 - 也许这对其他人有帮助。
我在XAML的资源部分看起来是这样的:
<RibbonWindow.Resources>
<DataTemplate x:Key="buttonTempl">
<RibbonButton Label="{Binding Path=Label}" LargeImageSource="{Binding Path=LargeImage}" SmallImageSource="{Binding Path=SmallImage}" Command="{Binding Path=Command}" />
</DataTemplate>
<Style TargetType="RibbonGroup" x:Key="groupStyle">
<Setter Property="Header" Value="{Binding Label}"/>
<Setter Property="ItemsSource" Value="{Binding MenuEntries}"/>
<Setter Property="ItemTemplate" Value="{StaticResource buttonTempl}"/>
</Style>
<Style TargetType="RibbonTab" x:Key="tabStyle">
<Setter Property="Header" Value="{Binding Label}"/>
<Setter Property="ItemsSource" Value="{Binding MenuGroups}"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource groupStyle}"/>
</Style>
<CollectionViewSource x:Key="StaticMenuSrc" Source="{Binding StaticMenu}"/>
<CollectionViewSource x:Key="ModuleMenuSrc" Source="{Binding ModuleMenu}"/>
并且功能区定义为:
<Ribbon DockPanel.Dock="Top" ItemContainerStyle="{StaticResource tabStyle}" >
<Ribbon.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource StaticMenuSrc}}" />
<CollectionContainer Collection="{Binding Source={StaticResource ModuleMenuSrc}}" />
</CompositeCollection>
</Ribbon.ItemsSource>
</Ribbon>
这样我就可以使用 MVVM 提供静态应用程序菜单和特定于模块的菜单。
我的计划是构建一个大型 WPF 应用程序,其中包含多个用户控件作为按需加载的模块。这些模块提供自己的菜单项列表,显示在主 window.
提供的菜单是MenuTab的列表objects。
public class MenuTab
{
private string _label;
private List<MenuGroup> _menuGroups = new List<MenuGroup>();
public string Label
{
get { return _label; }
set { _label = value; }
}
public List<MenuGroup> MenuGroups
{
get { return _menuGroups; }
}
public MenuTab(string label)
{
Label = label;
}
}
public class MenuGroup
{
private string _label;
private string _description;
private List<MenuEntry> _menuEntries = new List<MenuEntry>();
public string Label
{
get { return _label; }
set { _label = value; }
}
public string Description
{
get { return _description; }
set { _description = value; }
}
public List<MenuEntry> MenuEntries
{
get { return _menuEntries; }
}
public MenuGroup(string label)
{
Label = label;
}
}
public class MenuEntry
{
private string _label;
private BitmapSource _largeImage;
private BitmapSource _smallImage;
private ICommand _command;
public string Label
{
get { return _label; }
set { _label = value; }
}
public BitmapSource LargeImage
{
get { return _largeImage; }
set { _largeImage = value; }
}
public BitmapSource SmallImage
{
get { return _smallImage; }
set { _smallImage = value; }
}
public ICommand Command
{
get { return _command; }
set { _command = value; }
}
public MenuEntry(string label)
{
Label = label;
}
}
我在 Internet 上找到了多个关于如何构建菜单以添加其他静态菜单等的提示。
这里是我构建菜单和 HierarchicalDataTemplate 的方法,它们基本上会产生正确数量的选项卡、组和项目。 即使是命令绑定也能正常工作。
<RibbonWindow.Resources>
<Style x:Key="ModuleGroup" TargetType="RibbonGroup">
<Setter Property="Background" Value="AntiqueWhite" />
<Setter Property="Foreground" Value="Green" />
</Style>
<HierarchicalDataTemplate DataType="{x:Type CommonModel:MenuTab}" ItemsSource="{Binding Path=MenuGroups}">
<RibbonTab Header="{Binding Path=Label}" Background="Orange" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type CommonModel:MenuGroup}" ItemsSource="{Binding Path=MenuEntries}">
<RibbonGroup Header="{Binding Path=Label}" Style="{StaticResource ModuleGroup}" />
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type CommonModel:MenuEntry}">
<RibbonButton Label="{Binding Path=Label}" LargeImageSource="{Binding Path=LargeImage}" SmallImageSource="{Binding Path=SmallImage}" Command="{Binding Path=Command}" />
</DataTemplate>
<CollectionViewSource x:Key="ModuleMenuTabs" Source="{Binding ModuleMenu}"/>
</RibbonWindow.Resources>
然后在我的静态选项卡之间:
<CollectionContainer Collection="{Binding Source={StaticResource ModuleMenuTabs}}"/>
但选项卡 header 和背景未显示为异常。而且生成的组的背景也不例外(例如,我向其中一个工作正常的静态组添加了一些背景。)
谁能告诉我如何正确生成色带?
现在有回复后,我自己做了进一步的研究和测试。 我找到了适合我的解决方案 - 也许这对其他人有帮助。
我在XAML的资源部分看起来是这样的:
<RibbonWindow.Resources>
<DataTemplate x:Key="buttonTempl">
<RibbonButton Label="{Binding Path=Label}" LargeImageSource="{Binding Path=LargeImage}" SmallImageSource="{Binding Path=SmallImage}" Command="{Binding Path=Command}" />
</DataTemplate>
<Style TargetType="RibbonGroup" x:Key="groupStyle">
<Setter Property="Header" Value="{Binding Label}"/>
<Setter Property="ItemsSource" Value="{Binding MenuEntries}"/>
<Setter Property="ItemTemplate" Value="{StaticResource buttonTempl}"/>
</Style>
<Style TargetType="RibbonTab" x:Key="tabStyle">
<Setter Property="Header" Value="{Binding Label}"/>
<Setter Property="ItemsSource" Value="{Binding MenuGroups}"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource groupStyle}"/>
</Style>
<CollectionViewSource x:Key="StaticMenuSrc" Source="{Binding StaticMenu}"/>
<CollectionViewSource x:Key="ModuleMenuSrc" Source="{Binding ModuleMenu}"/>
并且功能区定义为:
<Ribbon DockPanel.Dock="Top" ItemContainerStyle="{StaticResource tabStyle}" >
<Ribbon.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource StaticMenuSrc}}" />
<CollectionContainer Collection="{Binding Source={StaticResource ModuleMenuSrc}}" />
</CompositeCollection>
</Ribbon.ItemsSource>
</Ribbon>
这样我就可以使用 MVVM 提供静态应用程序菜单和特定于模块的菜单。