2 Stimmen

Binding eines ContentControl an UserControl und Wiederverwendung derselben Instanz

Ich versuche, den Inhalt einer ContentControl an eine UserControl zu binden, die ich in meinem ViewModel instantiiert habe. Ich kann die Methode mit der Bindung an ein ViewModel verwenden und dann die UserControl als DataTemplate des ViewModels festlegen, da ich den Inhalt der ContentControl häufig ändern muss, unter Verwendung derselben Instanz der UserControls/Ansichten, und die Ansichten nicht jedes Mal neu instanzieren möchte, wenn ich sie neu binde.

Wenn ich jedoch die UserControl-Eigenschaft auf eine UserControl-Instanz setze und dann die Ansicht gerendert/datengebunden wird, erhalte ich: Muss das angegebene untergeordnete Element vom aktuellen übergeordneten Visual trennen, bevor es an das neue übergeordnete Visual angefügt wird. Obwohl ich diese UserControl zuvor nirgendwo hinzugefügt habe, habe ich diese Instanz nur erstellt und im Speicher behalten.

Gibt es einen besseren Weg, um zu erreichen, was ich tue?

Im ViewModel

public class MyViewModel : INotifyPropertyChanged
{
    //...

    private void LoadApps()
    {
        var instances = new List
                          {
                              new Instance1View(),
                              new Instance2View(),
                              new Instance3View(),
                          };
        SwitchInstances(instances);
    }

    private void SwitchInstances(List instances)
    {
        CenterApp = instances[0];
    }

    //...

    private UserControl _centerApp;
    public UserControl CenterApp
    {
        get { return _centerApp; }

        set
        {
            if (_centerApp == value)
            {
                return;
            }

            _centerApp = value;
            OnPropertyChanged("CenterApp");
        }
    }

    //...
}

In der View.xaml

4voto

Viv Punkte 16874

Zu lang für einen Kommentar.

Aufbauend auf dem, was @Kent in Ihrem Kommentar gesagt hat, Der ganze Sinn von MVVM ist es, das View-Modell von view-bezogenen Dingen (Steuerelementen) zu trennen, die die Testfähigkeit von GUI-Anwendungen blockieren. Daher führt die Verwendung eines UserControl / Button / eines beliebigen grafischen, view-bezogenen Elements das gesamte Prinzip von MVVM ad absurdum.

Sie sollten, wenn Sie MVVM verwenden, seinen Standards entsprechen und dann Ihr Problem neu angehen.

  1. Mit MVVM haben Sie normalerweise 1 Ansicht <-> 1 Ansichtsmodell
  2. Die Ansicht kennt ihr Ansichtsmodell (normalerweise durch DataContext). Umgekehrt sollte dies nicht codiert werden.
  3. Sie versuchen, die Logik zur Steuerung der Ansicht im Ansichtsmodell zu platzieren, um die Testlogik zu ermöglichen (Befehle und INPC-Eigenschaften)

... und noch einige mehr. Es ist ziemlich spezifisch in Bezug darauf, dass das Ansichtsmodell keine view-bezogenen Dinge hat, z.B. nicht einmal Eigenschaften im Ansichtsmodell wie Sichtbarkeit. Normalerweise haben Sie ein bool und verwenden dann einen Konverter in der Ansicht, um es in ein Sichtbarkeit-Objekt umzuschalten.

Es würde Ihnen sicherlich helfen, sich etwas mehr über MVVM zu informieren,

Nun etwas, um Ihr aktuelles Problem anzusprechen:

Folgen Sie einer MVVM-Struktur,

  • Main: MyViewModel
  • Leiten Sie alle Instanz-View-Modelle von einem Basis-View-Modell ab, um sie in einer Liste zu halten.
  • Liste oder halten Sie individuell Instance1ViewModel, Instance2ViewModel, Instance3ViewModel in MyViewModel (Erstellen Sie es entweder selbst oder lassen Sie es vom IOC-Container injizieren)
  • Lassen Sie MyViewModel eine Eigenschaft wie Ihr gepostetes Beispiel exponieren:

Beispiel:

// ViewModelBase ist die Basisklasse für alle Instanz-View-Modelle
private ViewModelBase _currentFrame;
public ViewModelBase CurrentFrame {
  get {
    return _currentFrame;
  }

  private set {
    if (value == _currentFrame)
      return;
    _currentFrame = value;
    OnPropertyChanged(() => CurrentFrame);
  }
}
  • In Ihrer MyView.xaml View-Datei sollten Sie(Nicht zwingend auf oberster Ebene) den DataContext in der obersten Ebene auf Ihr MyViewModel setzen
  • Ihr View-XAML kann dann deklariert werden wie:

Beispiel:

...

...
  • Das ist alles!. Jetzt müssen Sie nur die CurrentFrame-Eigenschaft in Ihrem Ansichtsmodell wechseln und sie auf eines der drei Instanz-View-Modelle zeigen lassen und die Ansicht wird entsprechend aktualisiert.

Dies bringt Ihnen eine MVVM-konforme Anwendung. Für Ihr anderes Problem, keine Ansichten dynamisch neu erstellen zu müssen basierend auf den DataTemplates, könnten Sie den vorgeschlagenen Ansätzen hier folgen und sie für Ihre eigene Verwendung erweitern.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X