首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MVVM在占用屏幕上相同占用空间的视图之间切换的正确方法

MVVM在占用屏幕上相同占用空间的视图之间切换的正确方法
EN

Software Engineering用户
提问于 2017-11-09 04:01:21
回答 3查看 12.8K关注 0票数 4

一个示例是根据汉堡包菜单中选定的项切换主视图。而且,有时只是GUI的一小部分根据应用程序状态或用户与GUI其他部分的交互而变化。

在WebForms时代,我们使用创建选项卡控件和隐藏选项卡按钮条,并以编程方式更改当前选项卡页。或者在设计和运行时将视图叠加在一起,只隐藏一个视图。

在WPF和MVVM中,我看到人们为每个视图创建DataTemplate,将每个视图附加到视图模型,并通过将绑定对象更改为不同视图模型类型来切换,因此视图会发生变化。

我明白为什么这对汉堡包菜单视图来说是个好主意,但对于其他一些情况,每个视图不一定有一个视图模型。在这种情况下,我想避免为每个视图创建虚拟视图模型,只是为了能够在它们之间进行切换,而不是真正地将不同类型的数据绑定到每个视图。

我关心这个设计细节是对的吗?

有人遇到过同样的情况吗?您实现切换视图效果的方式是什么?

通常,假设每个视图之间没有附加不同类型的数据,那么仅仅为纯GUI创建视图模型是一种正确的做法吗?换句话说,视图模型是否更多地耦合到数据,哪些数据是可用的,或者是GUI和我们需要涵盖的视图类型?我们是否应该在代码后面编写用于更改某些触发器上的视图的代码,以防我们一致认为这是纯粹的GUI,而视图模型不包括在内?

EN

回答 3

Software Engineering用户

回答已采纳

发布于 2017-11-09 13:22:27

在MVVM中,ViewModel包含UI的状态。视图仅仅是这种状态的反映。这种状态反映是通过绑定、转换器、样式等来实现的。

我认为您需要的是ViewModel上的一个状态变量,并且可以看到绑定到该状态的各种UI位。

首先,定义状态枚举并在VM上创建一个属性:

代码语言:javascript
运行
复制
    enum ViewState
    {
        State1,
        State2
    }

    class MyVM
    {
        public ViewState ViewState {get;set;}
    }

然后,在您的视图中,可以使用触发器隐藏/显示UI元素:

代码语言:javascript
运行
复制
    <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>
票数 2
EN

Software Engineering用户

发布于 2017-11-09 11:26:20

仅仅为纯GUI创建视图模型是正确的做法吗?

是的,这是正确的,因为拥有ViewModel的核心目的是表示UI中的某些内容。此外,还可以通过测试视图模型中的更改,在UI中对这些更改进行单元测试。

我们是否应该在代码背后的某些触发器上编写更改视图的代码,以防我们一致认为这纯粹是GUI,而视图模型不需要涉及?

如果这些只是纯粹的GUI关注点,您可以在代码隐藏、XAML中编写此触发器,也可以使用VisualStateManager。我认为所有这些选择都解决了你的担忧。但是,您将无法使用这些选项测试GUI流。

票数 2
EN

Software Engineering用户

发布于 2020-05-02 12:46:13

我正在用与OP相同的问题来处理我的第一个WPF项目,我越多地思考它,我的想法就越多:

您的CRUD操作都在使用相同的Model,并且该对象可能有一种显示自己的方法(它自己的视图模型)。因此,人们很容易认为“我想正确地做MVVM,这些都是相同的模型,我只是以不同的方式展示它们,因此不同的视图,而不是不同的视图模型。

正如其他人所建议的,我的第一个想法是将不同的场景表示为主ViewModel中的某种枚举,并将DataTemplate或ControlTemplate的选择绑定到该枚举中。

但是,由于View模型是对模型对象的呈现方式的抽象,所以对您正在使用它所做的事情进行抽象,那么每个操作场景(创建、读取、更新等)实际上都是您对对象所做的不同的事情,因此最好用单独的视图模型来表示。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/360492

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档