WPF:如何正确使用MVVM模式

3
这是一个可以轻松解决的问题。我的问题是如何以正确的方式遵循MVVM模式来解决它。
模型(M)很简单: 分析机器的音频系统(单声道或立体声)。 将此数据传递给VM 将所有(左/右或单声道)通道的音量级别传递给VM 从用户那里得到所选通道
因此,VM也非常简单。它具有以下布尔属性: 如果是单声道系统,则IsMono为true,如果是立体声则为false。 IsLeft-仅适用于立体声 此外,还有3个整数属性:RightLevel、LeftLevel和MonoLevel
视图(V)将如下所示(对于立体声): enter image description here 现在,如果系统是单声道,则不应显示音频通道框架框,并且音频级别框架框应显示单行,标记为“Mono”。级别计量器的源将是MonoLevel。 逻辑似乎很简单,但我应该把它实现在哪里?我需要将“音频通道”框架框和其他控件的IsVisible绑定到“not IsMono”,将单声道级别计量器绑定到“IsMono”。还需要添加其他(简单)逻辑,例如正确的标签和图标。
我应该使用Convertors作为我的主要工具吗?转换器被认为是View(V)或VM的一部分吗?我应该在XAML中为Mono和Stereo创建单独的视图,然后只显示所选的视图吗?是否好主意扩展VM以包括IsStereo(仅为NOT IsMono)和其他冗余以简化XAML?

1
模型持有数据。ViewModel 是您音频逻辑的网关。当前状态由视图模型的属性公开,这些属性可能包括您设计的模型或基本/效果类型。视图决定如何向用户显示此状态信息。用户交互被视图转换为视图模型中的命令或方法调用。这就是大局。 - user1228
谢谢你,威尔。你提到了我问题中涉及用户输入的部分。为什么不使用事件呢?个人而言,我不喜欢它们,因为它们往往会将VM与V实现混合在一起。你同意吗? - Shaul
1
为什么不使用事件呢?我不确定你在问什么。ViewModel通常具有DependencyProperties或实现INotifyPropertyChanged,两者都使用事件(某种类型的事件)来订阅绑定。这就是UI知道何时更新VM状态的方式。模型也是如此。 - user1228
1个回答

1

我会在ViewModel中创建一个属性,命名为IsStereo或者IsMono,因为ViewModel不应该关心展示层的事情,因此只需要一个布尔值来报告其状态。然后在View中使用两个转换器(它们属于展示层)BooleanToVisibilityBooleanToVisiblityNot,前者是系统提供的,后者是完全相反的,创建一个不应该成为问题。绑定将仅触发那个带有转换器的属性:

<AudioLevelUserControl x:Name="Mono" Visibility="{Binding IsMono, Converter={StaticResource BoolToVis}"/>
<AudioLevelUserControl x:Name="Stereo" Visibility="{Binding IsMono, Converter={STaticResource BoolToVisNot}"/>

类似的逻辑也适用于其他属性:left、right等等。
然而,在ViewModel中同时拥有这两个属性也不是“罪恶”的行为,只是样式/打字的偏好。只需要确保更改其中一个属性会引发另一个属性的属性更改,因此两个绑定都会重新查询状态()并请求当前值的getter。
public bool IsMono
{
    get {return _isMono;}
    set
    {
        if (_isMono == value) return;
        _isMono = value;
        RaisePropertyChanged(()=> IsMono);
        RaisePropertyChanged(()=> IsStereo);
}
//then do the same thing for IsStereo property..

关于您的问题:

如果系统是Mono,则不应显示Audio Channel frame框,并且Audio Level frame框应显示一个标记为“Mono”的单行。电平表的源将是MonoLevel。

这完全取决于您和您的用户。这与MVVVM无关。在UI设计方面有不同的思路。然而,越来越多的人认为,在没有必要使用控件的情况下,不要在UI中拥挤控件。如果您正在播放Mono,为什么要使用立体声选项?但是,如果您的用户习惯同时使用两者-那就都放上,客户永远是对的:)


从纯架构的角度来看,同时拥有两者似乎是一种“罪恶”,因为这是不合逻辑的,除非你知道它极大地简化了XAML部分——而你不应该知道。另一方面,转换器真的很尴尬,特别是如果它们是多参数的话,而它们经常是这样的。 - Shaul
1
同意!补充一下你的观点:1.在ViewModel中只有一个属性意味着少了很多需要担心的测试和错误。2.即使转换器看起来很奇怪,你也可以对它们进行单元测试,这增加了UI测试的覆盖范围。 - denis morozov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接