2011-01-07 14 views
1

Der Punkt von dem, was ich tue, ist, dass es viele Dinge im Viewmodel geben muss, aber wenn die View geladen wurde, nicht im Konstruktor. Ich könnte Ereignishandler verkabeln und Nachrichten senden, aber das scheint mir irgendwie schlampig zu sein. Ich implementiere eine Basisansicht und ein Basisansichtsmodell, in denen diese Logik enthalten ist, so dass alle meine Ansichten es hoffnungsvoll standardmäßig erhalten.mit EventToCommand & PassEventArgsToCommand :: Wie bekomme ich Absender oder besser Metapher?

Vielleicht kann ich nicht einmal bekommen, was ich will: der Absender. Ich dachte nur, dass RoutedEventArgs.OriginalSource das sein sollte?

[Bearbeiten] In der Zwischenzeit habe ich einen EventHandler in der XAML.cs angeschlossen, und natürlich OriginalSource ist auch Null. Also muss ich wirklich wissen, ob es möglich ist, einen Verweis auf die Ansicht/den Absender im Command zu bekommen? [/ Edit]

Meine Implementierung erfordert, dass eine Hilfsklasse für meine Viewmodels, die für die Erstellung von 'windows' zuständig ist, das 'host' Steuerelement kennt, dem alle Fenster hinzugefügt werden. Ich bin offen für Vorschläge, dies außerhalb des Bereichs von EventTocommand zu erreichen. :)

(der Code für Unloaded ist das gleiche)

#region ViewLoadedCommand 
    private RelayCommand<RoutedEventArgs> _viewLoadedCommand = null; 
    /// <summary> 
    /// Command to handle the control's Loaded event. 
    /// </summary> 
    public RelayCommand<RoutedEventArgs> ViewLoadedCommand 
    { 
     get 
     { 
      // lazy-instantiate the RelayCommand on first usage 
      if (_viewLoadedCommand == null) 
      { 
       _viewLoadedCommand = new RelayCommand<RoutedEventArgs>(
        e => this.OnViewLoadedCommand(e)); 
      } 
      return _viewLoadedCommand; 
     } 
    } 
    #endregion ViewLoadedCommand 


    #region View EventHandlers 
    protected virtual void OnViewLoadedCommand(RoutedEventArgs e) 
    { 
     EventHandler handler = ViewLoaded; 
     if (handler != null) 
     { 
      handler(this, e); 
     } 
    } 
    #endregion 

Antwort

2

Joe,

Meine Haltung auf MVVM ist:
Ausblick: weiß über ViewModel
ViewModel: weiß über Model (hat keine Kenntnis von View)
Modell: enthält Daten. (hat keine Kenntnis von ViewModel, View)

Wenn ich in Ihrer Situation wäre, würde ich die Basis ViewModel implementieren eine benutzerdefinierte Schnittstelle IViewModel. (In der Tat, ich habe eine IViewModel-Schnittstelle, die durch meine public abstract class ViewModelBase und all meine Viewmodel implementiert ViewModelBase erben.)

public interface IViewModel 
{ 
    void Load(); 
    void UnLoad(); 
    // other Properties, Methods, etc. 
} 
public abstract class ViewModelBase : IViewModel 
{ 
    public virtual/*or abstract*/ void Load() 
    { 
     // code 
    } 
} 

dann in Ihrer Ansicht:

this.Loaded += (o, e) => { if(ViewModel != null) { ViewModel.Load(); } } 

schließlich unter bestimmten Ansichten zu unterscheiden und/oder ViewModels verwende ich einen öffentlichen String Token (Guid-generiert).

3

Ich versuche, diese Probleme mit geraden XAML und Befehlen, wenn möglich zu lösen. Ich habe den EventToCommand in der Ansicht (UserControl) selbst so verwendet:

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="Loaded"> 
    <mvvmlight:EventToCommand Command="{Binding LoadCommand}" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers>