我们的应用程序是一个包含许多模块和视图的大型项目。主窗口中有一个功能区,我们正在寻找将功能区集成到应用程序中的最佳方法。
我创建了一个服务模块,视图可以注册以添加与它们相关的功能区项目,此外,任何主视图实例都可以提供与该实例相关的自己的功能区项目。一个RibbonItem是一个小类,它抽象一个功能区项的选项,主要有Title,Description,Command,UIType和ChildItems。当主视图发生变化时,该服务负责重建功能区。
我的一位同事认为这是糟糕的MVVM,因为用户需要用C#代码而不是XAML来设计他们的功能区视图,他还说这样做会很难使一组项目被禁用或启用一次,因为这些项目的每个命令都需要单独更新其CanExecute。相反,他建议使用主要的Ribbon View和ViewModel文件,其中每个想要为其模块或视图添加功能区按钮的开发人员需要在View XAML中添加它们,并在ViewModel中添加相关命令。此外,VisualStates将用于根据ViewModel中的更改(例如视图更改或选择更改)确定要显示或启用的项目。我真的不喜欢这个解决方案,主要是因为所有开发人员都必须将他们的模块知识放在一个大文件中。
请注意,功能区中的某些项目(例如,选项,退出)对整个应用程序是通用的,而某些项目与特定应用程序域相关,而某些项目仅与特定视图相关。
编辑:我想我的主要问题是允许多个开发团队集成在一个功能区上的推荐方法是什么?我们是否应该有一个RibbonView和一个RibbonViewModel,它将包含功能区中的所有可能项目,每个团队都会将其项目添加到这些V / VM,并定义何时显示它们的逻辑(可能通过使用可视状态) ?或者我们是否允许每个视图,视图模型或模块在服务中注册功能区项目(在他们自己的C#代码中),然后让服务在活动视图随注册到该类型的所有项目更改时根据需要呈现功能区?或者有没有更好的方法来实现这种集成?
你怎么看? 您是否对如何管理多个开发人员常见的单一功能区资源有更好的想法或意见?谢谢, splintor
答案 0 :(得分:1)
我同意Will的评论,你的视图模型不应该关心或知道它是如何呈现的,或者设计师是否决定改变它的呈现方式。
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>
为viewmodels提供默认视图
然后所有人必须做的就是在条带栏中创建一个条目
1)实施IMenuViewModel
2)如果他们希望他们的小部件呈现不同的方式,可以选择将另一个DataTemplate条目添加到resources.xaml中:
<DataTemplate DataType="{x:Type vm:FooViewModel}">
<v:FooView />
</DataTemplate>
我希望我没有深入研究如何实施。
重点是ViewModel
应该只公开视图所需的属性来执行它的工作(呈现ViewModel
),而不是ViewModel
来完成工作或者关心它是如何完成的。