我已经实现了一个 WPF 应用程序,它使用带有 MVVM 模式的 Ribbon 控件,但我的方法是创建一组我将 Ribbon 绑定到的导航界面。我还利用功能区元素的样式来控制数据绑定,我相信这可以帮助您完成您所追求的目标。
将 Ribbon 控件绑定到视图模型后,您可以填充选项卡及其子组,以便呈现要显示的图像,然后在选择组时指定要执行的视图模型上的 ICommand . 此命令将调用一个方法来设置集合的当前项。
功能区控制样式:
<Window.Resources>
<!-- RibbonMenuItem -->
<Style TargetType="{x:Type ribbon:RibbonMenuItem}">
<Setter Property="Header" Value="{Binding Header}" />
<Setter Property="ImageSource" Value="{Binding Image}" />
<Setter Property="ribbon:RibbonControlService.ToolTipTitle" Value="{Binding ToolTipTitle}" />
<Setter Property="ribbon:RibbonControlService.ToolTipDescription" Value="{Binding ToolTipDescription}" />
<Setter Property="ribbon:RibbonControlService.ToolTipImageSource" Value="{Binding ToolTipImage}" />
<Setter Property="ribbon:RibbonControlService.ToolTipFooterTitle" Value="{Binding ToolTipFooterTitle}" />
<Setter Property="ribbon:RibbonControlService.ToolTipFooterDescription" Value="{Binding ToolTipFooterDescription}" />
<Setter Property="ribbon:RibbonControlService.ToolTipFooterImageSource" Value="{Binding ToolTipFooterImage}" />
<Setter Property="KeyTipService.KeyTip" Value="{Binding KeyTip}" />
<Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
<Setter Property="Command" Value="{Binding Command}" />
<Setter Property="IsCheckable" Value="{Binding IsCheckable}" />
<Setter Property="IsChecked" Value="{Binding IsChecked}" />
<Setter Property="CanUserResizeVertically" Value="{Binding IsVerticallyResizable}" />
<Setter Property="CanUserResizeHorizontally" Value="{Binding IsHorizontallyResizable}" />
<Setter Property="ItemsSource" Value="{Binding Items}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Command}" Value="{x:Null}">
<Setter Property="Command" Value="{x:Null}" />
</DataTrigger>
<DataTrigger Binding="{Binding CommandParameter}" Value="{x:Null}">
<Setter Property="CommandParameter" Value="{x:Null}" />
</DataTrigger>
<DataTrigger Binding="{Binding Image}" Value="{x:Null}">
<Setter Property="ImageSource" Value="{x:Null}" />
</DataTrigger>
<DataTrigger Binding="{Binding ToolTipImage}" Value="{x:Null}">
<Setter Property="ribbon:RibbonControlService.ToolTipImageSource" Value="{x:Null}" />
</DataTrigger>
<DataTrigger Binding="{Binding ToolTipFooterImage}" Value="{x:Null}">
<Setter Property="ribbon:RibbonControlService.ToolTipFooterImageSource" Value="{x:Null}" />
</DataTrigger>
</Style.Triggers>
</Style>
<!-- RibbonSplitMenuItem -->
<Style TargetType="{x:Type ribbon:RibbonSplitMenuItem}" BasedOn="{StaticResource {x:Type ribbon:RibbonMenuItem}}">
<Setter Property="HeaderQuickAccessToolBarId" Value="{Binding Command}" />
<Setter Property="QuickAccessToolBarId" Value="{Binding DropDownButtonData.Command}" />
<Setter Property="HeaderKeyTip" Value="{Binding KeyTip}" />
<Setter Property="KeyTip" Value="{Binding DropDownButtonData.KeyTip}" />
<Setter Property="DropDownToolTipTitle" Value="{Binding DropDownButtonData.ToolTipTitle}" />
<Setter Property="DropDownToolTipDescription" Value="{Binding DropDownButtonData.ToolTipDescription}" />
<Setter Property="DropDownToolTipImageSource" Value="{Binding DropDownButtonData.ToolTipImage}" />
<Setter Property="DropDownToolTipFooterTitle" Value="{Binding DropDownButtonData.ToolTipFooterTitle}" />
<Setter Property="DropDownToolTipFooterDescription" Value="{Binding DropDownButtonData.ToolTipFooterDescription}" />
<Setter Property="DropDownToolTipFooterImageSource" Value="{Binding DropDownButtonData.ToolTipFooterImage}" />
<Style.Triggers>
<DataTrigger Binding="{Binding DropDownButtonData.ToolTipImage}" Value="{x:Null}">
<Setter Property="DropDownToolTipImageSource" Value="{x:Null}" />
</DataTrigger>
<DataTrigger Binding="{Binding DropDownButtonData.ToolTipFooterImage}" Value="{x:Null}">
<Setter Property="DropDownToolTipFooterImageSource" Value="{x:Null}" />
</DataTrigger>
</Style.Triggers>
</Style>
<!-- RibbonApplicationMenuItem -->
<Style TargetType="{x:Type ribbon:RibbonApplicationMenuItem}" BasedOn="{StaticResource {x:Type ribbon:RibbonMenuItem}}">
<Style.Triggers>
<Trigger Property="Level" Value="Middle">
<Setter Property="ImageSource" Value="{Binding Image}" />
<Setter Property="KeyTipService.KeyTip" Value="{Binding KeyTip}" />
<Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
<Setter Property="Command" Value="{Binding Command}" />
<Setter Property="Header" Value="{Binding Header}" />
</Trigger>
</Style.Triggers>
</Style>
<!-- RibbonApplicationSplitMenuItem -->
<Style TargetType="{x:Type ribbon:RibbonApplicationSplitMenuItem}" BasedOn="{StaticResource {x:Type ribbon:RibbonSplitMenuItem}}" />
<!-- RibbonTab -->
<Style TargetType="{x:Type ribbon:RibbonTab}">
<Setter Property="Header" Value="{Binding Header}" />
<Setter Property="ItemsSource" Value="{Binding Groups}" />
</Style>
<!-- RibbonGroupItem -->
<Style TargetType="{x:Type ribbon:RibbonButton}" x:Key="RibbonGroupItemButton">
<Setter Property="Label" Value="{Binding Label}" />
<Setter Property="LargeImageSource" Value="{Binding LargeImage}" />
<Setter Property="SmallImageSource" Value="{Binding SmallImage}" />
<Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
<Setter Property="Command" Value="{Binding Command}" />
<Style.Triggers>
<DataTrigger Binding="{Binding LargeImage}" Value="{x:Null}">
<Setter Property="LargeImageSource" Value="{x:Null}" />
</DataTrigger>
<DataTrigger Binding="{Binding SmallImage}" Value="{x:Null}">
<Setter Property="SmallImageSource" Value="{x:Null}" />
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type ribbon:RibbonControl}" x:Key="RibbonGroupItemTemplate">
<ribbon:RibbonButton Style="{StaticResource RibbonGroupItemButton}" />
</DataTemplate>
<!-- RibbonGroup -->
<Style TargetType="{x:Type ribbon:RibbonGroup}">
<Setter Property="Header" Value="{Binding Header}" />
<Setter Property="ItemsSource" Value="{Binding Items}" />
<Setter Property="ItemTemplate" Value="{StaticResource RibbonGroupItemTemplate}" />
</Style>
</Window.Resources>
视图模型(数据绑定)公开的属性:
#region MenuItems
/// <summary>
/// Gets the application menu items.
/// </summary>
/// <value>
/// A <see cref="SelectableObservableCollection{IMenuItem}"/> that contains
/// the application menu items. The default value is an <i>empty</i> collection.
/// </value>
public SelectableObservableCollection<IMenuItem> MenuItems
{
get
{
if (_viewModelMenuItems == null)
{
_viewModelMenuItems = new SelectableObservableCollection<IMenuItem>();
}
return _viewModelMenuItems;
}
}
private SelectableObservableCollection<IMenuItem> _viewModelMenuItems;
#endregion
#region Tabs
/// <summary>
/// Gets the application navigation tabs.
/// </summary>
/// <value>
/// A <see cref="SelectableObservableCollection{INavigationTab}"/> that contains
/// the application navigation tabs. The default value is an <i>empty</i> collection.
/// </value>
public SelectableObservableCollection<INavigationTab> Tabs
{
get
{
if (_viewModelTabs == null)
{
_viewModelTabs = new SelectableObservableCollection<INavigationTab>();
}
return _viewModelTabs;
}
}
private SelectableObservableCollection<INavigationTab> _viewModelTabs;
#endregion
查看(功能区 XAML):
<ribbon:Ribbon Grid.Row="0" ItemsSource="{Binding Path=Tabs}">
<ribbon:Ribbon.ApplicationMenu>
<ribbon:RibbonApplicationMenu
Margin="0, 5, 0, 0"
LargeImageSource="/MyApp;component/Resources/Images/ApplicationMenu.png"
SmallImageSource="/MyApp;component/Resources/Icons/ApplicationMenu.png"
ItemsSource="{Binding Path=MenuItems}"
>
<ribbon:RibbonApplicationMenu.FooterPaneContent>
<DockPanel LastChildFill="False">
<ribbon:RibbonButton
DockPanel.Dock="Right" Margin="2" BorderBrush="#B8114EAF"
Command="{Binding Path=Shutdown}"
Label="Exit" ToolTipTitle="Quit application" KeyTip="X"
SmallImageSource="/MyApp;component/Resources/Icons/Exit.png" />
</DockPanel>
</ribbon:RibbonApplicationMenu.FooterPaneContent>
</ribbon:RibbonApplicationMenu>
</ribbon:Ribbon.ApplicationMenu>
</ribbon:Ribbon>
导航界面:
public interface IMenuItem : ICloneable, INotifyPropertyChanged, INotifyPropertyChanging
{
#region Command
/// <summary>
/// Gets or sets the command associated with the menu item.
/// </summary>
/// <value>
/// The <see cref="ISurrogateCommand"/> associated with the menu item.
/// </value>
ISurrogateCommand Command
{
get;
set;
}
#endregion
#region CommandParameter
/// <summary>
/// Gets or sets the parameter to pass to the command associated with the menu item.
/// </summary>
/// <value>
/// The parameter to pass to the <see cref="Command"/> associated with the menu item.
/// </value>
object CommandParameter
{
get;
set;
}
#endregion
#region Header
/// <summary>
/// Gets or sets the item that labels the menu item.
/// </summary>
/// <value>
/// The item that labels the menu item.
/// </value>
object Header
{
get;
set;
}
#endregion
#region Image
/// <summary>
/// Gets or sets the image that is displayed on the menu item.
/// </summary>
/// <value>
/// The <see cref="ImageSource"/> that is displayed on the menu item.
/// </value>
ImageSource Image
{
get;
set;
}
#endregion
#region IsCheckable
/// <summary>
/// Gets or sets a value that indicates whether the menu item can be checked.
/// </summary>
/// <value>
/// <see langword="true"/> if the menu item can be checked; otherwise, <see langword="false"/>.
/// </value>
bool IsCheckable
{
get;
set;
}
#endregion
#region IsChecked
/// <summary>
/// Gets or sets a value that indicates whether the menu item is checked.
/// </summary>
/// <value>
/// <see langword="true"/> if the menu item is checked; otherwise, <see langword="false"/>.
/// </value>
bool IsChecked
{
get;
set;
}
#endregion
#region IsHorizontallyResizable
/// <summary>
/// Gets or sets a value that indicates whether the menu item can be resized horizontally.
/// </summary>
/// <value>
/// <see langword="true"/> if the menu item can be resized horizontally; otherwise, <see langword="false"/>.
/// </value>
bool IsHorizontallyResizable
{
get;
set;
}
#endregion
#region IsVerticallyResizable
/// <summary>
/// Gets or sets a value that indicates whether the menu item can be resized vertically.
/// </summary>
/// <value>
/// <see langword="true"/> if the menu item can be resized vertically; otherwise, <see langword="false"/>.
/// </value>
bool IsVerticallyResizable
{
get;
set;
}
#endregion
#region Items
/// <summary>
/// Gets the child menu items for the menu item.
/// </summary>
/// <value>
/// A <see cref="SelectableObservableCollection{IMenuItem}"/> collection that contains the child menu items for the menu item.
/// </value>
SelectableObservableCollection<IMenuItem> Items
{
get;
}
#endregion
#region KeyTip
/// <summary>
/// Gets or sets the text to use for the menu item key tip.
/// </summary>
/// <value>
/// The text to use for the menu item key tip.
/// </value>
string KeyTip
{
get;
set;
}
#endregion
#region ToolTipDescription
/// <summary>
/// Gets or sets the description for the menu item tooltip.
/// </summary>
/// <value>
/// The description for the menu item tooltip.
/// </value>
string ToolTipDescription
{
get;
set;
}
#endregion
#region ToolTipFooterDescription
/// <summary>
/// Gets or sets the description for the menu item tooltip footer.
/// </summary>
/// <value>
/// The description for the menu item tooltip footer.
/// </value>
string ToolTipFooterDescription
{
get;
set;
}
#endregion
#region ToolTipFooterImage
/// <summary>
/// Gets or sets the image for the menu item tooltip footer.
/// </summary>
/// <value>
/// The <see cref="ImageSource"/> for the menu item tooltip footer.
/// </value>
ImageSource ToolTipFooterImage
{
get;
set;
}
#endregion
#region ToolTipFooterTitle
/// <summary>
/// Gets or sets the title for the menu item tooltip footer.
/// </summary>
/// <value>
/// The title for the menu item tooltip footer.
/// </value>
string ToolTipFooterTitle
{
get;
set;
}
#endregion
#region ToolTipImage
/// <summary>
/// Gets or sets the image for the menu item tooltip.
/// </summary>
/// <value>
/// The <see cref="ImageSource"/> for the menu item tooltip.
/// </value>
ImageSource ToolTipImage
{
get;
set;
}
#endregion
#region ToolTipTitle
/// <summary>
/// Gets or sets the title for the menu item tooltip.
/// </summary>
/// <value>
/// The title for the menu item tooltip.
/// </value>
string ToolTipTitle
{
get;
set;
}
#endregion
}
public interface INavigationTab : ICloneable, INotifyPropertyChanged, INotifyPropertyChanging
{
#region Groups
/// <summary>
/// Gets the groups for the navigation tab.
/// </summary>
/// <value>
/// A <see cref="SelectableObservableCollection{INavigationTabGroup}"/> collection that contains
/// the navigation groups for the navigation tab.
/// </value>
SelectableObservableCollection<INavigationTabGroup> Groups
{
get;
}
#endregion
#region Header
/// <summary>
/// Gets or sets the item that labels the navigation tab.
/// </summary>
/// <value>
/// The item that labels the navigation tab.
/// </value>
object Header
{
get;
set;
}
#endregion
}
public interface INavigationTabGroup : ICloneable, INotifyPropertyChanged, INotifyPropertyChanging
{
#region Header
/// <summary>
/// Gets or sets the item that labels the navigation tab group.
/// </summary>
/// <value>
/// The item that labels the navigation tab group.
/// </value>
object Header
{
get;
set;
}
#endregion
#region Items
/// <summary>
/// Gets the items for the navigation tab group.
/// </summary>
/// <value>
/// A <see cref="SelectableObservableCollection{INavigationTabGroupItem}"/> collection that contains
/// the navigation items for the navigation tab group.
/// </value>
SelectableObservableCollection<INavigationTabGroupItem> Items
{
get;
}
#endregion
}
public interface INavigationTabGroupItem : ICloneable, INotifyPropertyChanged, INotifyPropertyChanging
{
#region Command
/// <summary>
/// Gets or sets the command associated with the navigation tab group item.
/// </summary>
/// <value>
/// The <see cref="ISurrogateCommand"/> associated with the navigation tab group item.
/// </value>
ISurrogateCommand Command
{
get;
set;
}
#endregion
#region CommandParameter
/// <summary>
/// Gets or sets the parameter to pass to the command associated with the navigation tab group item.
/// </summary>
/// <value>
/// The parameter to pass to the <see cref="Command"/> associated with the navigation tab group item.
/// </value>
object CommandParameter
{
get;
set;
}
#endregion
#region Label
/// <summary>
/// Gets or sets the item that labels the navigation tab group item.
/// </summary>
/// <value>
/// The item that labels the navigation tab group item.
/// </value>
object Label
{
get;
set;
}
#endregion
#region LargeImage
/// <summary>
/// Gets or sets the large image that is displayed by the navigation tab group item.
/// </summary>
/// <value>
/// The <see cref="ImageSource"/> that represents the large image that is displayed
/// by the navigation tab group item.
/// </value>
ImageSource LargeImage
{
get;
set;
}
#endregion
#region SmallImage
/// <summary>
/// Gets or sets the small image that is displayed by the navigation tab group item.
/// </summary>
/// <value>
/// The <see cref="ImageSource"/> that represents the small image that is displayed
/// by the navigation tab group item.
/// </value>
ImageSource SmallImage
{
get;
set;
}
#endregion
}
这是填充其 Tabs 集合的视图模型的示例:
private void AddTabs()
{
INavigationTab homeTab = new NavigationTab(Properties.Resources.Shell_Tab_Home_Header);
INavigationTabGroup generalGroup = new NavigationTabGroup(Properties.Resources.Shell_TabGroup_General_Header);
generalGroup.Items.Add(
new NavigationTabGroupItem
{
Label = Properties.Resources.Shell_StartPage_Header,
LargeImage = GetImage("/MyApp;component/Resources/Images/Home.png"),
CommandParameter = this,
Command = this.DisplayStartPage
}
);
generalGroup.Items.Add(
new NavigationTabGroupItem
{
Label = Properties.Resources.Shell_Settings_Header,
SmallImage = GetImage("/MyApp;component/Resources/Icons/Settings.png")
}
);
generalGroup.Items.Add(
new NavigationTabGroupItem
{
Label = Properties.Resources.Shell_UserInformation_Header,
SmallImage = GetImage("/MyApp;component/Resources/Icons/UserInformation.png")
}
);
generalGroup.Items.Add(
new NavigationTabGroupItem
{
Label = Properties.Resources.Shell_About_Header,
SmallImage = GetImage("/MyApp;component/Resources/Icons/About.png"),
Command = this.AboutApplication
}
);
homeTab.Groups.Add(generalGroup);
this.Tabs.Add(homeTab);
}
另外,我最初在绑定图像源时遇到了一些问题,但通过使用 Freeze 找到了解决方案。这是一个例子:
// Build navigation tab
this.Tab = new NavigationTab(Properties.Resources.Module_Tab_Header);
var administrationImage = GetImage("/MyApp;component/Resources/Images/Administration.png");
administrationImage.Freeze();
INavigationTabGroup administrationGroup = new NavigationTabGroup(Properties.Resources.Module_TabGroup_Administration_Header);
administrationGroup.Items.Add(
new NavigationTabGroupItem
{
Label = Properties.Resources.Module_StartPage_Header,
LargeImage = administrationImage
}
);
/// <summary>
/// Gets an image resource in the assembly for the specified path.
/// </summary>
/// <param name="path">The relative path to the image resource.</param>
/// <returns>
/// The <see cref="System.Windows.Media.ImageSource"/> located at the specified <paramref name="path"/>.
/// </returns>
/// <example>
/// Path: <i>/MyAssembly;component/Resources/Icons/MyIcon.png</i>
/// </example>
protected static System.Windows.Media.ImageSource GetImage(string path)
{
return new System.Windows.Media.Imaging.BitmapImage(
new Uri(String.Format(null, "pack://application:,,,{0}", path))
);
}
希望这可以帮助您解决绑定问题。