从昨天开始,我一直在努力使用 MVVM 在 WPF 上构建一个(我认为的)简单的功能区。
我在互联网上(以及 Stack Overflow)上找到了很多链接,但没有一个能真正解决我的问题。
简而言之,我的问题是:我做错了,还是像我一样将功能区绑定(bind)到 ViewModel 是完全不可能的?
详细信息:
这是我的菜单模型:每个 MenuGroup 都应该呈现为 RibbonGroup,并且 MenuGroup 包含 MenuItem 的集合,该集合应该呈现为 RibbonButton(当然在它们各自的 RibbonGroup 内)。
using Caliburn.Micro;
namespace MyCompany.Poc.Wpf.Models
{
public class MenuGroup
{
public MenuGroup()
{
Items = new BindableCollection<MenuItem>();
}
public string Name { get; set; }
public IObservableCollection<MenuItem> Items { get; set; }
}
}
using System.Windows.Input;
namespace MyCompany.Poc.Wpf.Models
{
public class MenuItem
{
public MenuGroup Group { get; set; }
public string Name { get; set; }
public string Link { get; set; }
public ICommand OpenMenuUrl { get; set; }
}
}
我的 ViewModel 只包含这些 MenuGroup 的集合,用于 XAML 上的绑定(bind):
public IObservableCollection<MenuGroup> LegacyMenuItems
{
get { return _legacyMenuItems; }
}
一旦虚拟机被实例化,集合就会被填充(暂时),其中包含虚假数据):
var group1 = new MenuGroup();
group1.Name = "Group 1";
var group2 = new MenuGroup();
group2.Name = "Group 2";
group1.Items.Add(new MenuItem {Group = group1, Link = "http://www.google.co.uk", Name = "Link 1", OpenMenuUrl = OpenMenuUrl});
group1.Items.Add(new MenuItem {Group = group1, Link = "http://www.google.co.uk", Name = "Link 2", OpenMenuUrl = OpenMenuUrl});
group2.Items.Add(new MenuItem {Group = group2, Link = "http://www.google.co.uk", Name = "Link 3", OpenMenuUrl = OpenMenuUrl});
group2.Items.Add(new MenuItem {Group = group2, Link = "http://www.google.co.uk", Name = "Link 4", OpenMenuUrl = OpenMenuUrl});
LegacyMenuItems.Add(group1);
LegacyMenuItems.Add(group2);
现在是 XAML:
<my:Ribbon DockPanel.Dock="Top">
<my:RibbonTab Header="Legacy A.I." ItemsSource="{Binding LegacyMenuItems}">
<my:RibbonTab.ItemTemplate>
<DataTemplate>
<my:RibbonGroup Header="{Binding Name}" ItemsSource="{Binding Items}">
<my:RibbonGroup.ItemTemplate>
<DataTemplate>
<my:RibbonButton Label="{Binding Name}" Command="{Binding OpenMenuUrl}" CommandParameter="{Binding Link}"></my:RibbonButton>
</DataTemplate>
</my:RibbonGroup.ItemTemplate>
</my:RibbonGroup>
</DataTemplate>
</my:RibbonTab.ItemTemplate>
</my:RibbonTab>
<my:RibbonTab Header="Static">
<my:RibbonGroup Name="Administration" Header="Admin">
<my:RibbonButton Label="Stuffs" Command="{Binding Path=OpenMenuUrl}" CommandParameter="http://www.mycompany.com/somelink"></my:RibbonButton>
<my:RibbonButton Label="Google" Command="{Binding Path=OpenMenuUrl}" CommandParameter="http://www.google.co.uk"></my:RibbonButton>
</my:RibbonGroup>
</my:RibbonTab>
</my:Ribbon>
以及它呈现的内容:
如您所见,“静态”选项卡运行良好,功能区组(“管理员”)的“标题”显示在正确的位置。
现在,“传统人工智能”选项卡,没有按钮 (每组应该有 2 个按钮),并且 RibbonGroup 标题显示有趣( 下面应该是 )。
如果您对我在这里做错了什么有任何线索,请告诉我:)
我对 WPF 世界很陌生,所以我显然不能正确理解模板......
帮助您调用电话的一些事实:
- 模型加载正确,因为我们可以看到“组 1”和“组 2”,它们是在 ViewModel 中加载的假数据的一部分
- 我试过 Telerik 的 RadRibbon,它的行为完全一样!因此,除非他们在同一个地方都错了,否则问题一定来自我
晚安,好运 :)
最佳答案
我也在 MVVM 应用程序中使用功能区,并决定坚持使用 XAML 中定义的控件,将它们链接到我的 View 模型层中定义的类中的静态 ICommand 属性。这是非常不灵活的,但到目前为止对我有用。
如果您已经下载并安装了官方的 Microsoft Ribbon,您将在以下位置找到它的源代码和一些示例:
C:\Program Files\Microsoft Ribbon for WPF\MicrosoftRibbonForWPFSourceAndSamples
这包括一个也实现 MVVM 的示例。这使用了一种完全不同的方法,尽管可能不是您需要的,但我认为查看它可能会有所帮助。
关于wpf - 如何将 Ribbon 控件绑定(bind)到我的 ViewModel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7187116/