【问题标题】:How to pass Data to different Views in MVVM Light?如何将数据传递给 MVVM Light 中的不同视图?
【发布时间】:2013-08-07 19:21:28
【问题描述】:

我有点不清楚如何将数据传递给其他视图。我收集到有 3 种方法可以做到这一点,但我不确定如何做到其中的 2 种。

  1. 通过 Messenger 发送数据(不确定您是否可以发送对象,否则如果您必须发送大约 10 条数据或类似的东西,我会看到事情变得非常混乱)。

  2. 以某种方式通过新视图模型的构造函数传递数据。我说“不知何故”,因为我不清楚在使用 IOC 容器(在这种情况下是内置容器)时如何做到这一点。

  3. 通过参数传递数据。我看过一些教程,它们向您展示了如何为 windows phone 进行导航,但没有一个真正谈论参数传递。我猜这仍然是一个选择。

据我所知,选项 1 是一种老式的做法。选项 2 似乎是一种更新且更好的方法,但我找不到任何关于人们展示如何做到这一点的示例。

我不知道该怎么做,因为 Ioc 应该创建视图的实例,那么当数据不存在时如何将数据传递给它?

【问题讨论】:

    标签: windows-phone-7 mvvm mvvm-light


    【解决方案1】:

    我这样做的两种主要方法是:

    1)使用信使:

    发送者类:

    public class TrafficLight
    {
        public string Color{get;set;}
        public TimeSpand Duration{get;set;}
    }
    public class TrafficLightService
    {
         public void SendLight(TrafficLight light)
         {
             Messenger.Default.Send(light);
         }
    }
    

    接收者:

    public class MyViewModel
    {
         public MyViewModel()
         {
            Messenger.Default.Register<TrafficLight>(DoSomethingWithTrafficLight);
         }
         private void DoSomethingWithTrafficLight(TrafficLight light)
         {
         }
    }
    

    这里发生的是源对象使用 Messenger 作为事件代理。对象 A 不需要知道对象 B,它们都只需要知道信使。

    2)

    只需使用依赖注入:

         public class TrafficLight
            {
                public string Color{get;set;}
                public TimeSpand Duration{get;set;}
            }
        public class LightEventArgs:EventArgs
        {
            public LightEventArgs(TrafficLight light)
            {
                _light=light;
            }
            public TrafficLight Light{get{return _light;}}
        }
    
            public interface ITrafficLightService
            {
                void SendLight(TrafficLight light);
                public event EventHandler<LightEventArgs> TrafficLightSet;
            }
            public class TrafficLightService
            {
                 public void SendLight(TrafficLight light)
                 {
                     Messenger.Default.Send(light);
                 }
                 public event EventHandler<LightEventArgs> TrafficLightSet;
            }
    
    public class TrafficLightSenderViewModel
    {
        public TrafficLightSenderViewModel(ITrafficLightService trafficLightService)
        {
            _trafficLightService=trafficLightService;
            _trafficLightService.Send(new TrafficLight{Color="Red"});
        }
    }
    
    public class TrafficLightReceiverViewModel
    {
        public TrafficLightReceiverViewModel(ITrafficLightService trafficLightService)
        {
            _trafficLightService=trafficLightService;
            _trafficLightService.TrafficLightSet+= TrafficLightNotification;
        }
    
        private void TrafficLightNotification(TrafficLightEventArgs args)
        {
             DoSomethingWithTheLight(args.Light);
        }
    }
    
    public class ViewModelLocator
    {
        public ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
    
            if (ViewModelBase.IsInDesignModeStatic)
            {
                SimpleIoc.Default.Register<ITrafficLightService, Design.TrafficLightService>();
            }
            else
            {
                SimpleIoc.Default.Register<ITrafficLightService, TrafficLightService>();         
            }
    
            SimpleIoc.Default.Register<TrafficLightSenderViewModel>();
            SimpleIoc.Default.Register<TrafficLightReceiverViewModel>();
        }
    
        public MainViewModel Sender
        {
            get { return SimpleIoc.Default.GetInstance<TrafficLightSenderViewModel>(); }
        }
        public MainViewModel Receiver
        {
            get { return SimpleIoc.Default.GetInstance<TrafficLightReceiverViewModel>(); }
        }
    }
    

    这是一个更大、更复杂的例子。

    让我们一步一步来:

    1. 在 MVVM Light 中,我们将 ViewModelLocator 用于两件事:1) 注册我们所有的视图模型和服务。
    2. 提供一种方法以允许视图在 XAML 中获取视图模型

    当我们尝试解析 ViewModel 时

    SimpleIoc.Default.GetInstance<TrafficLightReceiverViewModel>();
    

    SimpleIoc 查看视图模型是否有任何依赖关系。在我们的例子中,我们需要一个 ITrafficLightService 用于我们的两个视图模型。发生的情况是 SimpleIoc 查看它是否可以解析该类,并在此过程中检查 ITrafficLightService 是否还有任何需要解析的依赖项。如果 SimpleIoc 可以解决实例化视图模型所需的依赖链,它会这样做,然后交还一个完全构建的对象。

    【讨论】:

    • 哇没想到依赖方式会这么长?这就是现在的首选方式??????我有很多问题,但目前我无法编译您的代码,直到那时我将等待问题。我得到类型“MvvmLight1.Model.LightEventArgs”不能用作泛型类型或方法“System.EventHandler”中的类型参数“TEventArgs”。没有从“MvvmLight1.Model.LightEventArgs”到“System.EventArgs”的隐式引用转换。
    • LightEventArgs 需要从 EventArgs 继承。 DI 是我的首选方式,因为它提供了许多好处:易于单元测试,它为我提供了可重用组件的集合,并且我没有隐藏类所具有的任何依赖项。如果我要快速淘汰一个应用程序(实用程序/等),我将使用方法 1。对于有前途的应用程序,我使用方法 2,因为它更易于维护和测试。
    • 我会试一试,看看效果如何。我只是对您需要使用事件感到惊讶,并认为它会更多地通过构造函数或其他方式注入模型。
    猜你喜欢
    • 1970-01-01
    • 2015-01-20
    • 2016-11-09
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多