2010-11-08 290 views
14

我正在使用L. Bugnion的MVVM Light Framework。
什么是推荐的方法来传递参数,如客户的ID到ViewModel的构造函数?MVVM:如何将参数传递给ViewModel的构造函数

编辑: 我需要的每个ViewModel的参数不是跨模型共享的。它对每个视图模型实例都是唯一的。

回答

2

请求任何你想要的,通过注入,使用接口。

如果您有跨模型共享设置,实例包含值独立的,并通过ISomethingProviderISomethingEditor接口揭露他们。

+0

感谢您的回复。但是,每个ViewModel所需的参数不是跨模型共享的。它对每个viewmodel实例都是唯一的,例如客户详细信息ViewModel的客户ID。 – Yeonho 2010-11-08 23:42:18

0

在针对视图模型编写测试的情况下,我有时会创建视图模型构造函数的重载,该视图模型构造函数将ISomething作为参数。我有默认的构造函数调用第二个默认实现ISomething。在测试的情况下,我使用测试实现调用构造函数。我知道这是不是最好的方法,因为它创建了两个类之间的依赖关系......但有时你必须采取简单的路径...

public class SomeViewModel 
{ 
    private ISomething internalSomething; 

    public void SomeViewModel():this(new Something()){} 

    public void SomeViewModel(ISomething something) 
    { 
    this.internalSomething = something; 
    }  
} 

更新

创建在XAML视图可以是这样的:

<UserControl xmlns="...." 
      xmlns:Example="SomeNamespace"> 

    <UserControl.DataContext> 
    <Example:SomeViewModel /> 
    </UserControl.DataContext> 

    <Grid> 
    ... 
    </Grid> 
</UserControl> 
+0

如何在运行时实例化ViewModel,并将其与视图配对? – Yeonho 2010-11-09 00:19:52

+0

如果使用MvvmLight中的ModelViewLocator,则不需要进行任何更改。对于非常简单的项目,我有时会在xaml中创建视图模型。 我会将它添加到帖子中... – Sorskoot 2010-11-09 07:57:14

2

对我使用MVVM光整点是为了避免注射任何东西到一个视图模型的构造。 MVVM Light提供了一种消息传送功能,允许您将参数发送给查看模型中的中的注册的听众。

例如,这是使用VSTO和WPF我WordWalkingStick的项目我的视图模型:

using System; 
using System.Xml.Linq; 
using GalaSoft.MvvmLight.Messaging; 

namespace Songhay.Wpf.WordWalkingStick.ViewModels 
{ 
    using Songhay.Office2010.Word; 
    using Songhay.OpenXml; 
    using Songhay.OpenXml.Models; 
    using Songhay.Wpf.Mvvm; 
    using Songhay.Wpf.Mvvm.ViewModels; 

    /// <summary> 
    /// View Model for the default Client 
    /// </summary> 
    public class ClientViewModel : ViewModelBase 
    { 
     /// <summary> 
     /// Initializes a new instance of the <see cref="ClientViewModel"/> class. 
     /// </summary> 
     public ClientViewModel() 
     { 
      if(base.IsInDesignMode) 
      { 
       #region 

       this._flatOpcSourceString = ApplicationUtility 
        .LoadResource(
new Uri("/Songhay.Wpf.WordWalkingStick;component/PackedFiles/FlatOpcToHtml.xml", 
         UriKind.Relative)); 
       this._xhtmlSourceString = ApplicationUtility 
        .LoadResource(
new Uri("/Songhay.Wpf.WordWalkingStick;component/PackedFiles/FlatOpcToHtml.html", 
         UriKind.Relative)); 

       #endregion 
      } 
      else 
      { 
       this._flatOpcSourceString = "Loading…"; 
       this._xhtmlSourceString = "Loading…"; 

       //Receive MvvmLight message: 
       Messenger.Default.Register(this, 
        new Action<GenericMessage<TransformationMessage>>(
       message => 
       { 
        var tempDocFolder = 
Environment.ExpandEnvironmentVariables("%UserProfile%/Desktop/"); 
        var inputPath = tempDocFolder + "temp.docx"; 
        var outputPath = tempDocFolder + "temp.html"; 

        var flatOpcDoc = 
          XDocument.Parse(message.Content.TransformationResult); 
        OpenXmlUtility.TransformFlatToOpc(flatOpcDoc, inputPath); 

        this.FlatOpcSourceString = flatOpcDoc.Root.ToString(); 

        var settings = new SonghayHtmlConverterSettings() 
        { 
         PageTitle = "My Page Title " + DateTime.Now.ToString("U"), 
         UseEntityMap = false 
        }; 

        OpenXmlUtility.WriteHtmlFile(inputPath, outputPath, settings); 

        var xhtmlDoc = XDocument.Load(outputPath); 
        this.XhtmlSourceString = xhtmlDoc.Root.ToString(); 

       })); 
      } 
     } 

     /// <summary> 
     /// Gets or sets the flat opc source string. 
     /// </summary> 
     /// <value>The flat opc source string.</value> 
     public string FlatOpcSourceString 
     { 
      get 
      { 
       return _flatOpcSourceString; 
      } 
      set 
      { 
       _flatOpcSourceString = value; 
       base.RaisePropertyChanged("FlatOpcSourceString"); 
      } 
     } 

     /// <summary> 
     /// Gets or sets the XHTML source string. 
     /// </summary> 
     /// <value>The XHTML source string.</value> 
     public string XhtmlSourceString 
     { 
      get 
      { 
       return _xhtmlSourceString; 
      } 
      set 
      { 
       _xhtmlSourceString = value; 
       base.RaisePropertyChanged("XhtmlSourceString"); 
      } 
     } 

     string _flatOpcSourceString; 
     string _xhtmlSourceString; 
    } 
} 

你可以看到,MVVM Light是消息(未注射)值到构造函数(Messenger.Default.Register)与其Messenger

+0

我需要将参数发送到ViewModel的某个实例,例如客户详细信息ViewModel的客户ID。如何使用messenger将消息发送到特定的ViewModel实例? – Yeonho 2010-11-08 23:46:18

+0

我不确定您的具体情况是否可以解决。它看起来像消息传递可以驱动视图模型中的内部功能,可以由客户ID驱动。在我看来,消息传递不必知道特定的实例,但消息调用的代码可以做到。 – rasx 2010-11-09 02:26:29

+0

你应该能够使用令牌做特定于实例的消息传递,但是我个人建议使用注入参数。 – jpierson 2014-08-12 04:24:14

2

这里是我做的:

视图模型需要显示与作为参数传递的车ID车窗:

视图模型 - >消息代码隐藏的视图中打开窗口。消息发送ID。

在本质上后面的代码:

变种VM =新视图模型(ID); var view = new view(); view.datacontext = vm; view.show();

我的viewmodel有一个构造函数,它需要一个id。

+0

我认为如果你要走“轻”路线,这是最好的选择。除此之外,我建议您只在设计模式下在ServiceLocator中注册该类,以便提供设计时间数据。 – 2013-11-04 18:18:37

8
//Create a container class to pass via messenger service 
    public class CarSelectedArgs 
    { 
     #region Declarations 

     public Car Car { get; set; } 

     #endregion 

     #region Constructor 

     public CarSelectedArgs(Car car) 
     { 
     Car = car; 
     } 

     #endregion 
    } 


    //example of view model sending message. 
    public class SendingViewModel : ViewModelBase 
    { 
     private Car _car; 
     public Car SelectedCar 
     { 
     get { return _car; } 
     set 
     { 
      _car = value; 
      if (value != null) 
      { 
      //messenger will notify all classes that have registered for a message of this type 
      Messenger.Default.Send(new CarSelectedArgs(value)); 
      } 
     } 
     } 
    } 


    //Example of ViewModel registering to recieve a message 
    public class SampleViewModel : ViewModelBase 
    { 
     #region Constructor 

     public SampleViewModel() 
     { 
     Messenger.Default.Register<CarSelectedArgs>(this, OnCarSelected); 
     } 
     #endregion 

     #region LocalMethods 

     void OnCarSelected(CarSelectedArgs e) 
     { 

     var NewCar = e.Car; 
     } 

     #endregion 
    } 
相关问题