zoukankan      html  css  js  c++  java
  • Mvvm Light页面间发送消息

      使用Messenger类

             this.Frame.Navigate(typeof(BlankPage2));
                Messenger.Default.Send<object>("dfsdfd");

                Messenger.Default.Register<string>(this,                

        m => {                  

                    if (m!=null)

          {

          DialogResult = m.ToString();

          }

          }

      );

    ,继续写点东西吧,弄个比较实在点的实例出来,这个实例非常的简单,就是页面通过点击一个按钮,弹出一个ChildWindow 来进行选择某条记录,然后将在Page中获取ChildWindow中选择的记录。

     

    假设调用ChildWindow的页面(page) Parent,对应的VM  ParentViewModel

    被调用的ChildWindow 的页面为 (childwindow)Child 对应的VM ChildViewModel

    既然用MVVM模式,那么在ChildWindow中也要使用MVVM模式,now begin

     

    实现思路如下:

     

    1 ParentOnNavigatedTo中注册消息,在该消息的会调函数中打开Child

     

    // parent.cs

    protected override void OnNavigatedTo(NavigationEventArgs e)

     {

      Messenger.Default.Register<NotificationMessage>(this, "OpenChildWindow", OpenChildWindow);

            }

            // 回调

            private void OpenChildWindow(NotificationMessage childWindowName)

            {

                string strChildWindowName = childWindowName.Notification;

                switch (strChildWindowName)

                {

                    case "Child":

                        ChildWindows. Child child = new ChildWindows. Child ();

                        child.Show();

                        break;

                }

            }

    你可能会问,为什么要在.cs 中写代码呢,为什么不在VM的构造函数中写呢,其实是有原因的,我们想想VM的好处之一就是可以将View  业务逻辑彻底的分开,例如以后想要将silverlight项目修改成WPF的项目,我们只需要简单的将WPFView绑定一下就OK了,但是VM不是万能的,我们在silverlight项目中独有的一些东西怎么能够替换到WPF中呢,例如ChildWindow,如果我们见ChildWindow的打开事件写到的ViewModel中,那么以后移植就会有花费更多的额外劳动,所以就将ChildWindow 的打开写在了Parent.cs中,也许你会问,那么直接在ButtonClick事件中写不就完事了吗,其实也未必不可,但是以后的附加工作也会很多,你从Child中选择的记录怎样提交到ParentViewModel中?别忘了,我们应用的还是MVVM模式。

     

    2 既然是选择某条记录,那么就可以这样的往下推,既然是要选择记录,那么在ChildViewModel 中就要有一个备选的集合属性 ,怎样获取的我就不管了,如:

      Private ObservableCollection<User> _userInfos;

          public ObservableCollection<User> UserInfos

            {

                get

                {

                    return _userInfos;

                }

                set

                {

                    if (_userInfos== value)

                    {

                        return;

                    }

                    _userInfos = value;

                    RaisePropertyChanged(“UserInfos”);

                }

            }

    既然有集合,那么就要有选择项的

       Public User UserInfoSelect  // 属性传递

     

    额,childwindow 中好像准备的差不多了

     

    那么在ParentViewMode中该做些什么呢?当然,首先得有个接收选中的记录的属性吧,和ChildViewModel 中的相同。

       Public User UserInfoSelect  // 属性接收

    额,那么他们怎样的进行传递呢?消息啊,这时候消息派上用场了,在ParentViewModel的构造中,我们注册一个消息。

    Messenger.Default.Register<GenericMessage<UserInfo>>(this, "GetUserInfo", GetUserInfo);

     

    // 回调

    Private void GetUserInfo(GenericMessage<UserInfo> userInfo)

    {

    if (userInfo.Content != null)

             this.UserInfoSelect  = userInfo.Content;

    }

    在接下来就是一个连线的过程了,首先我们在ParentViewModel 弹出选择窗体的事件中通知消消息OpenChildWindow à消息接收到之后调用回调函数弹出ChildàChildViewModel中获取选择的记录给UserInfoSelectà通知消息GetUserInfo,并且传递UserInfoSelectàParentViewModel获取消息,调用回调方法,获取Child中选择的记录。Ok,工作以完成。

     

    那么接下来就要说一些注意的事情了,既然有注册了消息,还有回调函数,就会出现多次被执行的情况(多次注册一个消息而没有注销),那么我们就要记住一定要在适当的位置注销消息,例如在ChildClosing事件中注销事件,或者在PageOnNavigatedFrom(NavigationEventArgs e)中写注销消息。

    注销消息如下:

    Messenger.Default.Unregister<GenericMessage<UserInfo>>( "GetUserInfo");

    其实为什么不在ViewModel 中弹出窗体,其实还有一个原因,就是如果我们要在ViewModel中弹出窗体,那么我们就要知道UI中的Child,这也就是说ViewModel要引用UI,这样做就有些

  • 相关阅读:
    java不定参数列表---乔老师没讲,但是传智有讲
    java数据库连接模板代码通用收集
    java数据库连接模板代码通用收集
    BZOJ2060: [Usaco2010 Nov]Visiting Cows 拜访奶牛
    BZOJ1598: [Usaco2008 Mar]牛跑步
    BZOJ1710: [Usaco2007 Open]Cheappal 廉价回文
    manacher模板
    BZOJ1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
    BZOJ1753: [Usaco2005 qua]Who's in the Middle
    BZOJ1828: [Usaco2010 Mar]balloc 农场分配
  • 原文地址:https://www.cnblogs.com/gengyuanchao/p/2875601.html
Copyright © 2011-2022 走看看