MvvmCross for WPF 支持子窗體顯示、關閉、傳參

最近在作 PCL(Portable Class Library)平臺的項目,因此發一下本身遇到的問題git

MvvmCross 是 PCL 平臺的一個 MVVM 框架github

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

支持的平臺:app

  • 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 方法ide

參考了一個列子:https://gist.github.com/cureos/6053471  ,還有朋友尚仔的大力幫助this

關閉子窗體時, 再重寫 ChangePresentation 方法就能夠了spa

在WPF項目中加入下邊代碼就能夠了插件

代碼以下:code

 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種

1、從MainViewModel   to  SubViewModel

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

id 爲子窗體中接受參數的名稱

Id 爲主窗體中要傳遞的參數的名稱

同時子窗體中要寫一個接收參數的方法

1 public void Init(int Id)
2   {
3         Id= id;
4   }

這樣就把參數從MainViewModel 傳到了 SubViewModel

2、從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  也能夠回傳參數,有作出來的歡迎發來分享!

相關文章
相關標籤/搜索