我创建了一个服务模块,视图可以注册以添加与它们相关的功能区项目,此外,任何主视图实例都可以提供与该实例相关的自己的功能区项目.一个RibbonItem是一个小类,它抽象一个功能区项的选项,主要有Title,Description,Command,UIType和ChildItems.当主视图发生变化时,该服务负责重建功能区.
我的一位同事认为这是糟糕的MVVM,因为用户需要在C#代码而不是XAML中设计他们的功能区视图,他还说这样做很难使一组项目被禁用或立即启用,如这些项目的每个命令都需要单独更新其CanExecute.相反,他建议使用主要的Ribbon View和viewmodel文件,其中每个想要为其模块或视图添加功能区按钮的开发人员需要在View XAML中添加它们,并在viewmodel中添加相关命令.此外,VisualStates将用于根据viewmodel中的更改(例如视图更改或选择更改)确定要显示或启用的项目.我真的不喜欢这个解决方案,主要是因为所有开发人员都必须将他们的模块知识放在一次大文件中.
请注意,功能区中的某些项目(例如,选项,退出)对整个应用程序是通用的,而某些项目与特定应用程序域相关,而某些项目仅与特定视图相关.
编辑:我想我的主要问题是允许多个开发团队集成在一个功能区上的推荐方法是什么?我们是否应该有一个RibbonView和一个Ribbonviewmodel,它将包含功能区中的所有可能项目,每个团队都会将其项目添加到这些V / VM,并定义何时显示它们的逻辑(可能通过使用可视状态) ?或者我们是否允许每个视图,视图模型或模块在服务中注册功能区项目(在他们自己的C#代码中),然后让服务在活动视图随注册到该类型的所有项目更改时根据需要呈现功能区?或者有没有更好的方法来实现这种集成?
你怎么看?
您是否对如何管理多个开发人员常见的单个功能区资源有更好的想法或意见?
谢谢,
splintor
viewmodel应该只包含表示层渲染它所需的所有信息.
因此,viewmodel应该具有Ribbon栏需要绑定的所有属性才能运行.然后,您可以使用Resources.xaml或其他策略来呈现它.
在黑暗中拍摄我会为viewmodels尝试这样的事情:
public interface IMenuviewmodel : INotifyPropertyChanged { ICommand Command {get;} string Title {get;} string Description {get;} UIType Type {get;} IList<IMenuviewmodel> ChildItems {get;} }
然后,我可能会创建一个抽象类,它为实现INotifyPropertyChanged提供了一个集合类,它实现了INotifyCollectionChanged来处理管道代码.
我可能会在Resources.xaml中做类似的事情
<DataTemplate DataType="{x:Type vm:IMenuviewmodel}"> <StackPanel> <Button Command="{Binding Command}" Content="{Binding Type}"/> <ItemsControl ItemsSource="{Binding ChildItems}"/> </StackPanel> </DataTemplate>
为您的视图模型提供默认视图
然后所有人必须做的是在你的功能区栏中创建一个条目
1)实现IMenuviewmodel
2)如果他们希望他们的小部件呈现方式不同,可以选择将另一个DataTemplate条目添加到resources.xaml中:
<DataTemplate DataType="{x:Type vm:Fooviewmodel}"> <v:FooView /> </DataTemplate>
我希望我没有深入研究如何实施.
重点是viewmodel应该只公开视图所需的属性来完成它的工作(这是渲染viewmodel),而不是viewmodel来完成工作或者关心它是如何完成的.