MvvmCross for WPF 支持子窗体显示、关闭、传参

最近在做 PCL(Portable Class Library)平台的项目,所以发一下自己遇到的问题

MvvmCross 是 PCL 平台的一个 MVVM 框架

地址:https://github.com/MvvmCross/MvvmCross

支持的平台:

  • Silverlight for WP7, WP8
  • Mono for Android (or Xamarin.Android)
  • MonoTouch for iOS (or Xamarin.iOS)
  • the WinRT XAML framework for Windows 8 Store apps.
  • WPF
  • Mono for Mac (or Xamarin.Mac)

 

在使用过程中首先遇到了弹出子窗体的问题,需要写一个类继承 MvxWpfViewPresenter

显示子窗体时重写 Present 方法

参考了一个列子:https://gist.github.com/cureos/6053471  ,还有朋友尚仔的大力帮助

关闭子窗体时, 再重写 ChangePresentation 方法就可以了

在WPF项目中加入下边代码就可以了

代码如下:

 1 public class MvxWindowViewPresenter : MvxWpfViewPresenter

 2      {

 3          private readonly ContentControl _contentControl;

 4  

 5          private FrameworkElement _frameworkElement;

 6          public MvxWindowViewPresenter(ContentControl contentControl)

 7          {

 8              _contentControl = contentControl;

 9          }

10  

11          public override void Present(FrameworkElement frameworkElement)

12          {

13              _frameworkElement = frameworkElement;

14              var window = frameworkElement as Window;

15              if (window == null)

16              {

17                  _contentControl.Content = frameworkElement;

18              }

19              else

20              {

21                  window.Owner = _contentControl as Window;

22                  window.ShowDialog();

23              }

24          }

25  

26          public override void ChangePresentation(MvxPresentationHint hint)

27          {

28              IMvxWpfView view;

29              var closeHint = hint as MvxClosePresentationHint;

30              if (closeHint != null

31                  && (view = _frameworkElement as IMvxWpfView) != null

32                  && ReferenceEquals(closeHint.ViewModelToClose, view.ViewModel))

33              {

34                  (_frameworkElement as Window).Close();

35              }

36  

37              base.ChangePresentation(hint);

38          }

39      }

 

写一个子窗体继承自 IMvxWpfView ,因为会监测这个接口

 1 public class SubWindow: IMvxWpfView

 2     {

 3         private IMvxViewModel _viewModel;

 4 

 5         public IMvxViewModel ViewModel

 6         {

 7             get { return _viewModel; }

 8             set

 9             {

10                 _viewModel = value;

11                 DataContext = value;

12             }

13         }

14 

15         private int myVar;

16 

17         public int MyProperty

18         {

19             get { return myVar; }

20             set { myVar = value; }

21         }

22         

23     }


显示子窗体:

1 ShowViewModel<SubViewModel>();

(SubViewModel为要显示的子窗体的ViewModel)

关闭子窗体:

1 Close(this);

 

当需要传参时,分为2种

一、从MainViewModel   to  SubViewModel

1 ShowViewModel<SubViewModel>(new { id= Id});

id 为子窗体中接受参数的名称

Id 为主窗体中要传递的参数的名称

同时子窗体中要写一个接收参数的方法

1 public void Init(int Id)

2   {

3         Id= id;

4   }

这样就把参数从MainViewModel 传到了 SubViewModel

二、从SubViewModel   to  MainViewModel

这时就需要用到 MvvmCross 框架支持的插件 Plugins 中的 Messager

首先在 Core 项目中的 App.cs 中重写一个方法,把插件注册进来

 1 public override void LoadPlugins(IMvxPluginManager pluginManager)

 2          {

 3              base.LoadPlugins(pluginManager);

 4  

 5              if (pluginManager == null)

 6              {

 7                  return;

 8              }

 9  

10              pluginManager.EnsurePluginLoaded<PluginLoader>();

11          }

其次写一个 Message 继承 MvxMessage

 1 public class XXXMessage : MvxMessage

 2      {

 3          public XXXMessage(object sender, int id)

 4              : base(sender)

 5          {

 6              Id= id;

 7          }

 8  

 9          public int Id{ get; private set; }

10      }

再在 MainViewModel 中声明一个字段,并在构造中实例化Messager

 1 private readonly MvxSubscriptionToken _token;

 2  

 3          public MainViewModel()

 4          {

 5              var messenger = Mvx.Resolve<IMvxMessenger>();

 6              _token = messenger.Subscribe<XXXMessage>(OnXXXMessage);

 7          }

 8  

 9          private void OnXXXMessage(XXXMessage XXXMessage)

10          {

11              if (XXXMessage == null)

12              {

13                  return;

14              }

15              // TODO

16          }

最后在 SubViewModel 中需要回传参数的地方把参数传回来

1 var messenger = Mvx.Resolve<IMvxMessenger>();            

2 messenger.Publish<XXXMessage>(new XXXMessagethis, id));


如此就可以在MvvmCross 中就可以显示子窗体、关闭子窗体、ViewModel 之间互相传参

Tips:据说 Service 和 Settings  也可以回传参数,有做出来的欢迎发来分享!

 

你可能感兴趣的:(WPF)