首页 > 代码库 > MvvmCross for WPF 支持子窗体显示、关闭、传参
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 else20 {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 != null31 && (view = _frameworkElement as IMvxWpfView) != null32 && 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 MyProperty18 {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 // TODO16 }
最后在 SubViewModel 中需要回传参数的地方把参数传回来
1 var messenger = Mvx.Resolve<IMvxMessenger>(); 2 messenger.Publish<XXXMessage>(new XXXMessagethis, id));
如此就可以在MvvmCross 中就可以显示子窗体、关闭子窗体、ViewModel 之间互相传参
Tips:据说 Service 和 Settings 也可以回传参数,有做出来的欢迎发来分享!