【问题标题】:WPF MVVM Navigate between Views on button clickWPF MVVM 在按钮单击时在视图之间导航
【发布时间】:2019-07-26 06:44:20
【问题描述】:

我正在尝试创建一个 WPF 应用程序,对于导航,我使用的是我在

找到的示例

https://rachel53461.wordpress.com/2011/12/18/navigation-with-mvvm-2/

现在,我需要在单击按钮时从一个 UserControl 导航到另一个。

有人可以指导我如何使用 MVVM 实现这一目标吗?或者我是否应该考虑使用一些导航框架。

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    这在一定程度上取决于上下文,但很多时候我使用的技术是在某个 ViewModel 中有一个名称类似于“MainContent”的对象(或某种抽象类)。这负责保存要在ContentControl 中显示的内容。

    我的 XAML 看起来像这样,其中 Type1ViewType2View 将是 UserControls(vw_Type1vw_Type2 是对其命名空间的引用),然后我将通过设置 @ 在它们之间导航987654328@ 到 Type1ViewModelType2ViewModel 的实例。

    <ContentControl Content="{Binding MainContent}">
        <ContentControl.Resources>
            <DataTemplate DataType="{x:Type vm_Type1:Type1ViewModel}">
                <vw_Type1:Type1View />
            </DataTemplate>
            <DataTemplate DataType="{x:Type vm_Type2:Type2ViewModel}">
                <vw_Type2:Type2View />
            </DataTemplate>
        </ContentControl.Resources>
    </ContentControl>
    

    这可能会通过ContentControl 之外的一个按钮(或以下示例中的两个按钮)来处理,该按钮向包含MainContent 的 ViewModel 发送一个命令,这只是更改了MainContent 属性,到Type1ViewModelType2ViewModel 的现有或新实例。例如:

    private Type1ViewModel _type1ViewModel;
    public Type1ViewModel Type1ViewModel
    {
        get { return _type1ViewModel; }
        set
        {
            if (_type1ViewModel != value)
            {
                _type1ViewModel = value;
                NotifyPropertyChanged();
            }
        }
    }
    
    private Type2ViewModel _type2ViewModel;
    public Type2ViewModel Type2ViewModel
    {
        get { return _type2ViewModel; }
        set
        {
            if (_type2ViewModel != value)
            {
                _type2ViewModel = value;
                NotifyPropertyChanged();
            }
        }
    }
    
    ...
    
    private ObservableObject _mainContent;
    public ObservableObject MainContent
    {
        get { return _mainContent; }
        set
        {
            if (_mainContent != value)
            {
                _mainContent = value;
                NotifyPropertyChanged();
            }
        }
    }
    
    ...
    
    public InternalDelegateCommand NavigateToType1Command => new InternalDelegateCommand(NavigateToType1);
    public InternalDelegateCommand NavigateToType2Command => new InternalDelegateCommand(NavigateToType2);
    
    ...
    
    private void NavigateToType1() => MainContent = Type1ViewModel;
    private void NavigateToType2() => MainContent = Type2ViewModel;
    

    所以要完成此示例的 XAML:

    <Button Content="Type 1" Command="{Binding NavigateToType1Command}" />
    <Button Content="Type 2" Command="{Binding NavigateToType2Command}" />
    <ContentControl Content="{Binding MainContent}">
        <ContentControl.Resources>
            <DataTemplate DataType="{x:Type vm_Type1:Type1ViewModel}">
                <vw_Type1:Type1View />
            </DataTemplate>
            <DataTemplate DataType="{x:Type vm_Type2:Type2ViewModel}">
                <vw_Type2:Type2View />
            </DataTemplate>
        </ContentControl.Resources>
    </ContentControl>
    

    (有关InternalDelegateCommand的信息,请参阅我对this question的回复。)

    【讨论】:

    • 感谢您的帮助。但我有点困惑 MainContent 需要驻留在哪里。现在,当我按照您的示例并单击按钮时,MainContent 为空且私有 void NavigateToType1() => MainContent = Type1ViewModel,此处 Type1ViewModel 为空。
    • 我发布的一段 C# 代码是 ViewModel 的部分视图,它是主视图的数据上下文(我发布的最后一段 XAML)。 Type1ViewModel 如果您还没有实例化它,它将为空。因此,您可以实例化它并将其保存在内存中(可能在构造函数中),或者您可以尝试private void NavigateToType1() =&gt; MainContent = new Type1ViewModel();
    猜你喜欢
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 2016-01-08
    • 2011-08-15
    • 1970-01-01
    相关资源
    最近更新 更多