2013-08-06 48 views
0

我有点不清楚如何将数据传递给其他视图。我收集了3种方法来做到这一点,但我不知道如何去做2个。如何将数据传递给MVVM Light中的不同视图?

  1. 通过信使发送数据(不知道你是否可以发送对象,否则我可以看到事情变得相当混乱,如果你有像10个数据或类似的东西一起发送)。

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

  3. 通过参数传递数据。我看过一些教程,告诉你如何做windows电话的导航,但没有人真正谈论参数传递。我猜这仍然是一个选择。

从我听说的是,选项1是一种旧的做法。选项2似乎是一个更新的方式,更好的方式来做到这一点,但我找不到任何示范如何去做的例子。

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

回答

2

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

1)使用Messenger:

发件人类:

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光中,我们使用ViewModelLocator 2件事情:1)注册所有我们的ViewModels和服务。
  2. 提供一种方法,使视图在XAML

得到一个视图模型当我们试图解决一个ViewModel

SimpleIoc.Default.GetInstance<TrafficLightReceiverViewModel>(); 

SimpleIoc着眼于视图模型是否有任何相关性。在我们的情况下,我们需要为我们的视图模型提供ITrafficLightService。会发生什么情况是SimpleIoc会查看它是否可以解析该类,并在此过程中检查ITrafficLightService是否有任何需要解析的依赖关系。如果SimpleIoc可以解决实例化视图模型所需的依赖关系链,它会这样做,然后交回完全构建的对象。

+0

哇,不觉得依赖的方式会这么长吗?那现在是首选的方式吗?我有很多问题,但目前我无法让你的代码编译,直到那时我才会等待问题。我得到类型'MvvmLight1.Model.LightEventArgs'不能用作通用类型或方法'System.EventHandler '中的类型参数'TEventArgs'。没有从'MvvmLight1.Model.LightEventArgs'到'System.EventArgs'的隐式引用转换。 – xiao

+0

LightEventArgs需要从EventArgs继承。 DI是我首选的方式,因为它提供了许多好处:它很容易进行单元测试,它给了我可重用组件的集合,并且我没有隐藏任何类的依赖关系。如果我快速地将应用程序甩出(实用程序/等),我将使用方法1.对于具有未来的应用程序,我使用方法2,因为它具有更好的可维护性和可测试性。 –

+0

我会尝试一下,看看它是否有效。我只是很惊讶,你需要使用事件,并认为它会更多地通过构造函数或其他东西注入模型。 – xiao

相关问题