通过MVVM LIGHT(WPF)导航UserControl

首先我为我不好的英语不是第一语言而道歉。

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

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

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

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

  • 由于没有人回答我的问题,所以我终于这么做了。 这可能不是最好的方式,但至少它运作良好。 我希望它能帮助像我这样挣扎着学习这种模式的新手:

    在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);
             }
         }  
    }
    

    显然将其绑定到Mainview(只是相关的代码):

    <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中用简单的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));
        }
    

    就这样。

    链接地址: http://www.djcxy.com/p/56185.html

    上一篇: Navigate through UserControl with MVVM LIGHT (WPF)

    下一篇: WPF mvvm switch view