【问题标题】:Navigate through UserControl with MVVM LIGHT (WPF)使用 MVVM LIGHT (WPF) 在 UserControl 中导航
【发布时间】:2016-02-05 10:34:45
【问题描述】:

首先,我很抱歉我的英语很差,这不是我的第一语言。

我是 MVVM 的新手,所以我的问题可能是一个非常新手的问题;)

我在使用 WPF 和 MVVM LIGHT 在 C# 应用程序中切换视图时遇到了一些问题。我已经阅读了很多文章,但我仍然无法弄清楚如何以干净的方式做到这一点。

所以这是我的问题:什么是实现 MainWindows 中包含的 UserControl 之间导航的最佳方式,假设:

  • 我为每个 UserControl 和 Main Windows 一个 ViewModel。
  • 用于在用户控件之间切换的按钮包含在 UserControl 本身中
  • 我有一个 ViewModelLocator
  • 有时我需要销毁/重新创建 userControl 的 ViewModel
  • 我想尊重 MVVM 模式。
  • 我想保持简单

【问题讨论】:

标签: c# wpf xaml user-controls mvvm-light


【解决方案1】:

由于没有人回答我的问题,这就是我最终所做的。 这可能不是最好的方法,但至少效果很好。 我希望它能帮助像我这样正在努力学习这种模式的新手:

在 MainViewModel 中放置一个 CurrentViewModel 对象:

public class MainViewModel : ViewModelBase,IMainViewModel
{ 
    /* Other piece of code */

    private ViewModelBase _currentViewModel;

     public ViewModelBase CurrentViewModel
     {
         get
         {
             return _currentViewModel;
         }
         set
         {
             _currentViewModel = value;
             RaisePropertyChanged(() => CurrentViewModel);
         }
     }  
}

显然将此绑定到主视图(仅相关代码):

<UserControl Content="{Binding Path=CurrentViewModel}"/>

将 DataTemplate 放入 App.xaml:

  <Application.Resources>
        <ResourceDictionary>
            <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
            <DataTemplate DataType="{x:Type localViewModel:HomeViewModel }">
                <localView:AccueilView/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type localViewModel:ErrorViewModel }">
                <localView:ErrorView/>
            </DataTemplate>
        </ResourceDictionary>
    </Application.Resources>

在 ViewModelLocator 中使用 Simple IOC 注册 ViewModel:

if (ViewModelBase.IsInDesignModeStatic)
{
    SimpleIoc.Default.Register<IHomeViewModel, DesignHomeViewModel>();
}
else
{
    SimpleIoc.Default.Register<IHomeViewModel, HomeViewModel>();
}

将ViewModelLocator中所有ViewModel的getter设置为Static(仅举一个例子)

public static IHomeViewModel Home
{
    get{return ServiceLocator.Current.GetInstance<IHomeViewModel>();}
}

由于它是静态的,您可以从 MainViewModel 访问所需的 ViewModel:

public class MainViewModel : ViewModelBase,IMainViewModel
{
        public ViewModelBase HomeVM
        {
            get
            {
                return (ViewModelBase)ViewModelLocator.Home;
            }
        }
}

提供取消注册 ViewModel 并重新创建它的能力:

public static void CleanUpHome()
{
    SimpleIoc.Default.Unregister<HomeViewModel>();
    SimpleIoc.Default.Register<IHomeViewModel, HomeViewModel>();
}

“子”视图模型通过消息与 MainViewModel 通信:

public class ErrorViewModel : ViewModelBase, IErrorViewModel
{     
    /*Other piece of code */

        public void HomeReturn()
        {
            var msg = new ChangeView(ChangeView.EnumView.Home);
            Messenger.Default.Send<ChangeView>(msg);
            ViewModelLocator.CleanUpErrors();
        }
}

MainViewModel 注册到消息并处理它:

public class MainViewModel : ViewModelBase,IMainViewModel
{
    public MainViewModel()
    {
        Messenger.Default.Register<ChangeView>(this, (action) => ReceiveMessage(action));
        CurrentViewModel = HomeVM;
    }

    private void ReceiveMessage(ChangeView viewName)
    {
        switch (viewName.switchView)
        {
            case ChangeView.EnumView.Home:
                CurrentViewModel = HomeVM;
                break;
            case ChangeView.EnumView.Error:
                CurrentViewModel = ErrorVM;
                break;
            }
        Messenger.Default.Unregister<ChangeView>(this, (action) => ReceiveMessage(action));
    }

就是这样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多