MVVM: Comment passer le paramètre au constructeur de ViewModel

j'utilise le cadre lumineux MVVM de L. Bugnion.

Quelles sont certaines des approches recommandées pour transmettre des paramètres tels que L'ID du client au constructeur de ViewModel?

Modifier: Le paramètre dont j'ai besoin pour chaque modèle de vue n'est pas quelque chose qui est partagé entre les modèles. c'est quelque chose d'unique à chaque instance de viewmodel.

14
demandé sur Yeonho 2010-11-08 10:49:40

5 réponses

//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
    }
8
répondu Jgraham 2011-04-04 14:27:44

demandez tout ce que vous voulez, par injection, en utilisant des interfaces.

si vous avez des paramètres partagés entre les modèles, instanciez un singleton contenant les valeurs et exposez-les via ISomethingProvider et ISomethingEditor interfaces.

2
répondu Gone Coding 2010-11-08 08:58:33

pour moi, le but de L'utilisation de la lumière MVVM est d'éviter d'injecter quoi que ce soit dans le constructeur d'un modèle de vue. MVVM Light fournit un service de messagerie qui vous permet d'envoyer vos paramètres à un auditeur enregistré à l'intérieur du modèle View.

Par exemple, c'est mon point de Vue, le Modèle de mon WordWalkingStick projet à l'aide de VSTO et WPF:

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;
    }
}

vous pouvez voir que la lumière MVVM est messagerie (ne pas injecter) valeurs dans le constructeur (Messenger.Default.Register avec son Messenger.

2
répondu rasx 2010-11-08 20:20:45

Voici ce que je fais:

ViewModel doit faire preuve d'une fenêtre de la voiture avec la voiture de l'id passé en paramètre:

ViewModel -> message à codebehind pour voir ouvrir la fenêtre. Le Message envoie une pièce d'identité.

essentiellement en code derrière:

var vm = new viewmodel (id); var affichage = nouveau point de vue(); vue.datacontext = vm; vue.show ();

mon viewmodel a un constructeur qui prend un id.

2
répondu dnndeveloper 2010-11-11 15:37:14

dans le cas d'écrire des tests contre le viewmodel je crée parfois une surcharge du constructeur de viewmodel qui prend un ISomething comme paramètre. J'ai le constructeur par défaut appelez le second avec une implémentation par défaut de ISomething. Dans le cas du test j'appelle le constructeur avec une implémentation de test. Je sais que ce n'est pas la meilleure méthode, parce que ça crée une dépendance entre les deux classes... mais parfois, vous aurez à prendre le facile chemin...

public class SomeViewModel
{
  private ISomething internalSomething;

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

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

mise à Jour

créer une vue dans xaml peut être comme ceci:

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

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

  <Grid>
     ...
  </Grid>
</UserControl>
0
répondu Sorskoot 2010-11-09 08:53:37