使用MVVM LIGHT(WPF)浏览UserControl

时间:2016-02-05 10:34:45

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:5)

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

将一个CurrentViewModel对象放在MainViewModel中:

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中使用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>();
}

&#34;孩子&#34; View Model通过消息与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));
    }

这就是全部。