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  也可以回传参数,有做出来的欢迎发来分享!

MvvmCross for WPF 支持子窗体显示、关闭、传参,布布扣,bubuko.com

时间: 2024-10-13 02:34:57

MvvmCross for WPF 支持子窗体显示、关闭、传参的相关文章

c#如何将子窗体显示到父窗体的容器(panel)控件中

如何将一个窗体显示到一个容器控件中,刚开始想的比较简单,用窗体容器控件添加一般控件的方法,试了一试,代码如下: Form2 frm = new Form2(); this.panel1.Controls.Add(frm); frm.Show(); 但是提示了一个错误:无法将顶级控件添加到控件. 原来窗体是一个顶级控件,是无法将一个顶级控件添加到一个容器中来的.最后在网上找了相关资料,只需要将代码改下即可,还是原来的思路,代码如下: Form2 frm = new Form2(); frm.Top

vue.js 1中父组件跳到子组件中并传参让子组件显示不同的内容

父组件中的点击跳转: <ul class="insurance-entry clearfloat"> <li v-link="{name:'productlist',params:{id:1}}">1</li> <li v-link="{name:'productlist',params:{id:2}}">2</li> <li v-link="{name:'product

ASP.NET WebAPI RC 竟然不支持最常用的json传参

壮士断腕(WCF Web API),为的是 ASP.NET Web API 的横空出世,再加上它的开放(开源),于是对之产生了一点点痴情,并写下了HttpClient + ASP.NET Web API, WCF之外的另一个选择.那时,ASP.NET Web API 还处于 beta 阶段,俗话说女大十八变,自然对 ASP.NET Web API RC 产生了憧憬... ASP.NET Web API RC 闪亮登场之后,还未一睹庐山真面目,就有人陆陆续续反馈之前博文中的示例代码在 ASP.NE

WPF制作子窗体的弹出动画效果

今天有幸被召回母校给即将毕业的学弟学妹们讲我这两年的工作史,看了下母校没啥特别的变化,就是寝室都安了空调,学妹们都非常漂亮而已..好了不扯蛋了,说下今天的主题吧.这些天我在深度定制语法高亮功能的同时发现了博客园提供的一些有意思的函数,甚至有几个博客园都没用到,我也不知道怎么才能触发那些功能..打开这个js就可以看到很多好用的东西了,虽然写的不怎么样,但是至少有这些功能. ps: 推荐安装一个代码格式化的插件,否则一坨看着蛋疼.比如第一个就是 log,方便调试. www.pinterest.com

winform 子窗体显示

Form child =new Form(); point p = new point(); p.x = (pform.width-child.width)/2; p.y = (pform.height-child.height)/2; child.location = p; child.toplevel =false; child.bringtofornt(); child.startposition = formstartposition.manual; child.show();

WPF制作子窗体的弹出动画效果住着卓专姿嘴

http://www.ebay.com/cln/t53_xljt/2015-01-30/166737013012 http://www.ebay.com/cln/flh_zrjl/2015-01-30/166845890016 http://www.ebay.com/cln/7vv_nlbh/2015-01-30/166696893018 http://www.ebay.com/cln/xh9_nzvt/2015-01-30/166543631019 http://www.ebay.com/cl

c# winform 窗体之间的传参

说起winform程序中窗体之间的参数互传,大家找度娘会找到很多方法: 1.在窗体类中创建全局变量,类型为公开.静态的: 2.在窗体类中定义狗仔函数: 3.通过实践来船体参数: 这三种思路完全来自于霖小屋的c# winform窗体之间传递参数问题总结,大家可以看看他的这篇博客学习学习. 下面我要给大家说的一种方法相对来说有点繁琐,但对于winform程序初学者来说绝对的受用.之前在度娘上寻找winform窗体的显示与隐藏受到点启发,本来winform程序创建新的窗体的时候是不带参数的,为了能够在

WPF 子窗体关闭,刷新父窗体

父窗体代码 private void DGUserEdit() { if(DGUser.SelectedItem!=null) { DataRow dr = (DGUser.SelectedItem as DataRowView).Row; Page.UserEdit UE = new UserEdit(UserGrade, dr["UserName"].ToString());//声明子窗体 UE.Closed += new EventHandler(UE_Closed);//注册关

window.open 打开子窗体,关闭全部的子窗体

需求:通过window.open方法打开了子窗体,当关闭主窗体时.子窗体应当也关闭. 实现思路: 1.打开子窗体函数window.open(url,winName)的第二个參数winName能够唯一标识打开的窗体.因此关闭子窗体仅仅须要使用winName.close()函数就可以. 2.一个页面可能有多个子窗体. 因此须要一个数组存储全部子窗体对象.关闭时,遍历数组就可以. 3.子窗体还能够再打开子窗体. 无限循环下去.因此须要推断. 此需求能够通过两个方法实现. 调用子窗体的关闭函数. 此方法