wpf - 这段代码会破坏 MVVM 吗?

标签 wpf vb.net mvvm

使用 MVVM 构建我的第一个项目,我想知道以下代码是否破坏了模型。

该命令的目的是在两个用户控件(ucDrumStandard 和 ucDrumStandardList 之间切换。两者共享相同的 View 模型。
此 View 模型继承自包含“ParentContext”的 View 模型库。
用户控件“存储”在 ParentContext.listOfViews 中。

(为我的 VB 代码道歉 ;-)

#Region "CmdSwitchDrumStandardView"

Public ReadOnly Property CmdSwitchDrumStandardView() As ICommand
    Get
        If _cmdSwitchDrumStandardView Is Nothing Then
            _cmdSwitchDrumStandardView = New RelayCommand(AddressOf SwitchDrumStandardView)

        End If
        Return _cmdSwitchDrumStandardView
    End Get
End Property

Private Sub SwitchDrumStandardView()

    ' There are  two views(ucDrumStandard and ucDrumStandardList) for the same viewmodel 

    If ParentContext.CurrentView.Uid = "ucDrumStandard" Then

        ' switch to ucDrumStandardGrid

        If ParentContext.ListOfViews.ContainsKey("ucDrumStandardGrid") Then

            ParentContext.CurrentView = (From obj As KeyValuePair(Of String, UIElement) In ParentContext.ListOfViews
                                    Where obj.Key = "ucDrumStandardGrid"
                                    Select obj.Value).FirstOrDefault
        Else

            Dim m_ucDrumStandardGrid = New ucDrumStandardGrid


            ParentContext.ListOfViews.Add("ucDrumStandardGrid", m_ucDrumStandardGrid)
            ParentContext.CurrentView = m_ucDrumStandardGrid

        End If

    ElseIf ParentContext.CurrentView.Uid = "ucDrumStandardGrid" Then

        ' switch to ucDrumStandard

        If ParentContext.ListOfViews.ContainsKey("ucDrumStandard") Then

            ParentContext.CurrentView = (From obj As KeyValuePair(Of String, UIElement) In ParentContext.ListOfViews
                                    Where obj.Key = "ucDrumStandard"
                                    Select obj.Value).FirstOrDefault
        Else

            Dim m_ucDrumStandard = New ucDrumStandard

            ParentContext.ListOfViews.Add("ucDrumStandard", m_ucDrumStandard)
            ParentContext.CurrentView = m_ucDrumStandard

        End If

    End If

End Sub

#End Region

最佳答案

在 MVVM 模式中,ViewModel 和 View 层之间的通信只能通过 Binding 和 Commands 来完成。 ViewModel 代码不应使用 FrameworkElements,所以是的,您的代码“破坏”了 MVVM 模式。

我假设你的 ParentContext 是一个 ViewModel 类应该有一个 CurrentView 属性,它是“页面”对象的 ViewModel 层的类型。

View 层中这些 ViewModel 对象的渲染应该使用 DataTemplate & Bindings 完成。我将添加一个小示例来说明所有这些。

// View 模型

public class AppVM : INotifyPropertyChanged {

    //your code...

    private PageVM _currentView;
    public PageVM CurrentView {
        get {return _currentView;}
        set {
            _currentView = value;
            OnPropertyChanged("CurrentView");
        }
    }
}

public class PageVM : INotifyPropertyChanged {
    //your "view" data visible in the UI
}

//XAML
<ContentControl Content="{Binding CurrentView, Mode=OneWay}">
    <ContentControl.Resources>
        <DataTemplate DataType="{x:Type ucDrumStandardVM}">
            <ucDrumStandard/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type ucDrumStandardListVM}">
            <ucDrumStandardList/>
        </DataTemplate>
    </ContentControl.Resources>
</ContentControl>

如果您真的想为两个“页面”保留相同的 ViewModel 对象,那么您必须使用触发器
<ContentControl Content="{Binding CurrentView, Mode=OneWay}">
    <ContentControl.Style>
        <Style TargetType="{x:Type ContentControl}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding CurrentView.Uid, Mode=OneWay}" Value="ucDrumStandard">
                    <Setter Property="ContentTemplate">
                        <DataTemplate>
                            <ucDrumStandard/>
                        </DataTemplate>
                    </Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding CurrentView.Uid, Mode=OneWay}" Value="ucDrumStandardGrid">
                    <Setter Property="ContentTemplate">
                        <DataTemplate>
                            <ucDrumStandardList/>
                        </DataTemplate>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Resources>
</ContentControl>

关于wpf - 这段代码会破坏 MVVM 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34808751/

相关文章:

wpf - WinRT (C#/XAML) 不模糊缩放

vb.net - 覆盖列表(Of)。添加行为

c# - 如何构建一个非常低分辨率的计时器?

c# - 使用 MVVM 将 RichTextBox 的内容保存到文件

android - MutableLivedata 观察者触发

c# - WPF Slider - 当值从 UI 更改时通知

c# - TFS C# - 加载 workItemStore 返回 null 或类型初始值设定项异常

.net - 为什么模块中的这个公共(public)函数无法访问

wpf - 使用 Linq to Entities 绑定(bind)到 List<T> 时显示组合框的选定值的问题

wpf - 将图像设置为 Button 的样式内容