Frage

ich brauche, um herauszufinden, wie man zwischen Viewmodel zu kommunizieren. Ich bin neu so mvvm bitte Art sein.

Hier ist ein verdummtes Beispiel

Klassendefinitionen (davon ausgehen, dass ich das Child.PropertyChanged Ereignis in der ParentViewModel angeschlossen haben):

public class ParentViewModel : ViewModelBase
{
    public ChildViewModel Child { get; set; }
}

public class ChildViewModel : ViewModelBase
{
    String _FirstName;
    public String FirstName 
    {
        get { return _FirstName; }
        set
        {
            _FirstName = value;
            OnPropertyChanged("FirstName");
        }
    }
}

Hier ist, was Sie im Ressourcenverzeichnis finden Sie unter

<DataTemplate DataType="{x:Type vm:ParentViewModel}">
    <vw:ParentView/>
</DataTemplate>

<DataTemplate DataType="{x:Type vm:ChildViewModel}">
    <vw:ChildView/>
</DataTemplate>

und der Code-behind des ChildView:

public partial class ChildView : UserControl
{
    public QueueView()
    {
        InitializeComponent();
        DataContext = new ChildViewModel();
    }
}

Das offensichtliche Problem ist, dass, wenn die ChildView (über Auswahl aus der Datatemplate) instanziiert wird es eine neue ChildViewModel Klasse erstellt und die ParentViewModel haben keinen Zugriff auf sie.

Wie kann ich die Datacontext der Ansicht sein, das ursprüngliche Ansichtsmodell instanziiert, dass die Datatemplate verursacht ausgewählt werden?

Eine offensichtliche Lösung ist, die Eigenschaften in dem ChildViewModel in die ParentViewModel mmerge, aber ich würde es eher trennen, weil für die Wiederverwendung.

Ich bin sicher, die Antwort trivial ist, ich möchte nur wissen, was es ist. :)

Vielen Dank im Voraus.

War es hilfreich?

Lösung

Sie sollten einfach entfernen Sie die Zeile:

DataContext = new ChildViewModel();

Die DataContext der Ansicht wird automatisch von WPF eingestellt werden. DataTemplates hat immer ihren Datenkontext auf die Daten für die Vorlage festgelegt (in diesem Fall des Ansichtsmodell):

<DataTemplate DataType="{x:Type vm:ChildViewModel}">
    <vw:ChildView/>
</DataTemplate>

Das Endergebnis ist, dass Sie die Ansicht Modellobjekte separat aufbauen können (beide Eltern und Kind-Klassen) und sie dann später anzeigen, indem Sie sie einfach in Inhaltssteuer anschließen.

Andere Tipps

Der einfachste Weg zwischen Viewmodels mit dem MVVM Ansatz zu kommunizieren, ist der Mediator-Muster (Eventaggregator in Prism) zu verwenden. Ein gutes Beispiel für diesen Ansatz kann in den folgenden Links zu sehen:

  1. MVVM Mediator-Muster von Sacha Barber
  2. MVVM + Mediator von Marlon Grech

Auch die MVVM Besuche Probe Projektrahmen.

Angenommen, Sie haben ein Ticket System gespeichert haben, die eine QueueViewModel verwendet.

public class QueueViewModel : INotifyPropertyChanged
{
    public ParentType Parent { get; set; }

    public QueueViewModel(ParentType parent)
    {
        this.Parent = parent;
        foreach (ChildType child in Parent)
        {
            child.PropertyChanged += delegate(object sender,
                PropertyChangedEventArgs e)
            {
                if (e.PropertyName != "IsSelected")
                    return;

                //do something like this:
                Parent.IsSelected = AllChildrenAreSelected();
            };
        }
    }

}

public class ParentType : INotifyPropertyChanged
{
    private bool _isSelected;

    public IList<ChildType> Children { get; set; }
    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            _isSelected = value;
            OnPropertyChanged("IsSelected");
        }
    }
}

public class ChildType : INotifyPropertyChanged
{
    private string _name;
    private bool _isSelected;

    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged("Name");
        }
    }

    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            _isSelected = value;
            OnPropertyChanged("IsSelected");
        }
    }
}

- Queue-Ansicht Teil

<StackPanel>
<CheckBlock Text="{Binding Path=Parent.Name}" 
            IsChecked="{Binding Parent.IsSelected}"/>
<ItemsControl ItemsSource="{Binding Path=Parent.Children}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>                                    
            <CheckBox Content="{Binding Path=Name}"
                      IsChecked="{Binding Path=IsSelected, Mode=TwoWay}"/>
        </DataTemplate>
    <ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top