一个示例是根据汉堡包菜单中选定的项切换主视图。而且,有时只是GUI的一小部分根据应用程序状态或用户与GUI其他部分的交互而变化。
在WebForms时代,我们使用创建选项卡控件和隐藏选项卡按钮条,并以编程方式更改当前选项卡页。或者在设计和运行时将视图叠加在一起,只隐藏一个视图。
在WPF和MVVM中,我看到人们为每个视图创建DataTemplate,将每个视图附加到视图模型,并通过将绑定对象更改为不同视图模型类型来切换,因此视图会发生变化。
我明白为什么这对汉堡包菜单视图来说是个好主意,但对于其他一些情况,每个视图不一定有一个视图模型。在这种情况下,我想避免为每个视图创建虚拟视图模型,只是为了能够在它们之间进行切换,而不是真正地将不同类型的数据绑定到每个视图。
我关心这个设计细节是对的吗?
有人遇到过同样的情况吗?您实现切换视图效果的方式是什么?
通常,假设每个视图之间没有附加不同类型的数据,那么仅仅为纯GUI创建视图模型是一种正确的做法吗?换句话说,视图模型是否更多地耦合到数据,哪些数据是可用的,或者是GUI和我们需要涵盖的视图类型?我们是否应该在代码后面编写用于更改某些触发器上的视图的代码,以防我们一致认为这是纯粹的GUI,而视图模型不包括在内?
发布于 2017-11-09 13:22:27
在MVVM中,ViewModel包含UI的状态。视图仅仅是这种状态的反映。这种状态反映是通过绑定、转换器、样式等来实现的。
我认为您需要的是ViewModel上的一个状态变量,并且可以看到绑定到该状态的各种UI位。
首先,定义状态枚举并在VM上创建一个属性:
enum ViewState
{
State1,
State2
}
class MyVM
{
public ViewState ViewState {get;set;}
}然后,在您的视图中,可以使用触发器隐藏/显示UI元素:
<StackPanel>
<StackPanel.Style>
<Style TargetType="StackPanel">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ViewState}" Value="{x:Static local:ViewState.State1}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
</StackPanel>发布于 2017-11-09 11:26:20
仅仅为纯GUI创建视图模型是正确的做法吗?
是的,这是正确的,因为拥有ViewModel的核心目的是表示UI中的某些内容。此外,还可以通过测试视图模型中的更改,在UI中对这些更改进行单元测试。
我们是否应该在代码背后的某些触发器上编写更改视图的代码,以防我们一致认为这纯粹是GUI,而视图模型不需要涉及?
如果这些只是纯粹的GUI关注点,您可以在代码隐藏、XAML中编写此触发器,也可以使用VisualStateManager。我认为所有这些选择都解决了你的担忧。但是,您将无法使用这些选项测试GUI流。
发布于 2020-05-02 12:46:13
我正在用与OP相同的问题来处理我的第一个WPF项目,我越多地思考它,我的想法就越多:
您的CRUD操作都在使用相同的Model,并且该对象可能有一种显示自己的方法(它自己的视图模型)。因此,人们很容易认为“我想正确地做MVVM,这些都是相同的模型,我只是以不同的方式展示它们,因此不同的视图,而不是不同的视图模型。
正如其他人所建议的,我的第一个想法是将不同的场景表示为主ViewModel中的某种枚举,并将DataTemplate或ControlTemplate的选择绑定到该枚举中。
但是,由于View模型是对模型对象的呈现方式的抽象,所以对您正在使用它所做的事情进行抽象,那么每个操作场景(创建、读取、更新等)实际上都是您对对象所做的不同的事情,因此最好用单独的视图模型来表示。
https://softwareengineering.stackexchange.com/questions/360492
复制相似问题