2013-03-02 14 views
5

In Ordnung, das ist etwas im Zusammenhang mit dieser Frage: WPF Printing multiple pages from a single View ModelMVVM + + Usercontrol Abhängigkeitseigenschaft

Ich habe versucht, den Rat dort gegeben zu folgen, aber jetzt stecke ich bin.

Meine Anwendung verwendet MainView.xaml und das entsprechende MainViewViewModel.cs, ich verwende MVVM Light im Hintergrund.

jetzt - nach der Post - es scheint, ich habe zu tun, die folgenden:

  • eine Benutzersteuerung erstellen
  • einige Eigenschaften Expose von der Benutzersteuerung
  • Sicherstellen, dass das Ansichtsmodell zeigt diese Eigenschaften

Die Idee ist klar, aber ich bin fest, wenn Sie versuchen, sich gegenseitig zu benachrichtigen.

Meine Benutzersteuerung (UcTest.xaml) stellt eine Abhängigkeitseigenschaft:

public string SpecialText 
{ 
    get { return (string)GetValue(SpecialTextProperty); } 
    set 
    { 
     SetValue(SpecialTextProperty, value); 

    } 
} 

// Using a DependencyProperty as the backing store for SpecialText. This enables animation, styling, binding, etc... 
public static readonly DependencyProperty SpecialTextProperty = 
    DependencyProperty.Register("SpecialText", typeof(string), typeof(UcTest), new PropertyMetadata(new PropertyChangedCallback(SpecialTextChangedPropertyCallback))); 

private static void SpecialTextChangedPropertyCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
{ 
    // Do something 
    Debug.WriteLine("Ffgdgf"); 
} 

Okay, also ich habe jetzt eine Benutzersteuerung, die einige Abhängigkeitseigenschaften hat. Diese Eigenschaften sind jedoch vollständig von meinen ViewModel-Eigenschaften getrennt (das sind diejenigen, die angezeigt werden sollen).

Also im Grunde habe ich zwei Möglichkeiten:

  • Wie kann ich jetzt meine Viewmodel für die Usercontrol sagen, dass einige Eigenschaften geändert haben?
  • Gibt es eine Möglichkeit, die Abhängigkeitseigenschaften zu vergessen und direkt auf das Ansichtsmodell zuzugreifen?

Zusätzliche Informationen # 1: Ich habe ein (einfaches) Beispiel hochgeladen, was ich versuche, hier zu tun: Example Project. Ich möchte den Wert der Beschriftung in UserControl1 (über die Bindungseigenschaft in dem ViewModel für UserControl1) von meinem MainViewViewModel ändern.

+0

Verwenden Sie Datenbindung –

+1

Das würde bedeuten, dass mein UserControl INotifyPropertyChanged implementieren müsste, das ist im Grunde, was mein ViewModel tun sollte. –

Antwort

4

In Ordnung, nach Stunden googeln es scheint, dass die "richtige" Ansatz dazu ist, es überhaupt nicht zu tun. Der allgemeine Ansatz besteht darin, die Daten in Ihrem MainViewModel zu behalten und kein zusätzliches ViewModel für das UserControl zu verwenden (was ich ein wenig ... gut ... nicht so gut finde). Das Hauptproblem besteht darin, dass es keinen einfachen Mechanismus gibt, um die Daten von der Dependency-Eigenschaft zum ViewModel zu bekommen.

Zum Drucken bin ich jetzt wieder rein im Code.

+0

Dies kann für Fälle gelten, in denen Sie Tabulatorelemente in Benutzersteuerelemente aufteilen. Aber was ist mit allgemeinen Kontrollen, wie einem Dateibrowser, die mehrfach angezeigt werden? – bytecode77

+0

@Tom L. in Ihrer Situation, das Beste, was ich in der Lage war, ist, einen Datenkontext im Benutzersteuerelement nicht zu setzen, dann unter Windows laden die übergebenen Eigenschaften aus dem DP zu Variablen speichern, dann setzen Sie den Kontext auf eine neue Instanz Ihrer VM Legen Sie dann die richtigen Eigenschaften in der VM fest und fahren Sie fort. Es ist nicht ideal, aber es erledigt die Arbeit. Ich möchte in den Metadaten der DP angeben, in welchem ​​Kontext man die Bindungen bekommen soll. –

5

Sie würden normalerweise die Eigenschaft UserControl für die ViewModel-Eigenschaft bind. Eine bidirektionale Bindung funktioniert in beiden Richtungen, von ViewModel zu View und umgekehrt.

<Window x:Class="TestApplication.MainWindow" ...> 
    <Window.DataContext> 
     <local:MyViewModel/> 
    </Window.DataContext> 
    <Grid> 
     <local:UcTest SpecialText="{Binding MyViewModelProperty, Mode=TwoWay}"/> 
    </Grid> 
</Window> 

Für den Zugriff auf direkt mit dem Viewmodel-Objekt in dem obigen Beispiel, geben Sie einfach den DataContext Eigenschaft auf das Ansichtsmodell Typen des Usercontrol werfen könnten. Der DataContext wird vom MainWindow geerbt.

var viewModel = DataContext as MyViewModel; 
var property = viewModel.MyViewModelProperty; 

Sie könnte natürlich auch direkt eine spezialisierte Viewmodel-Instanz der DataContext Usercontrol zuordnen:

<local:UcTest SpecialText="{Binding MyViewModelProperty, Mode=TwoWay}"/> 
    <local:UcTest.DataContext> 
     <local:UserControlViewModel/> 
    </local:UcTest.DataContext> 
</local:UcTest> 

oder Sie können die Ansichtsmodell Instanz als eine Ressource in einem Ressourcenverzeichnis erstellen und zuweisen die DataContext wie folgt

<local:UcTest DataContext="{StaticResource MyUserControlViewModel}" 
       SpecialText="{Binding MyViewModelProperty, Mode=TwoWay}"/> 
+0

Hm, ich glaube ich kann dich missverstehen. Das Problem besteht darin, dass das UserControl über ein eigenes ViewModel verfügt, an das ich mich binden möchte. Oder denken Sie, dass es besser wäre, die Eigenschaften im MainViewModel zu behalten und einfach das UserControl ohne eigenes ViewModel zu verwenden? –

+0

Das hängt von Ihrem Anwendungsdesign ab. Beide sind gültige Lösung. Sie können auch die DataContext-Eigenschaft des UserControls direkt zuweisen. – Clemens

+1

Hm, nein .. Ich verstehe das nicht wirklich. Würde es Ihnen etwas ausmachen, ein Beispiel zu geben? Weil, sobald ich den DataContext für das UserControl zum UserControlViewModel ändere, kann ich keine weiteren Variablen zuweisen, da das UserControl über diese Eigenschaften nicht weiß. Wie kann ich "SpecialText" etwas zuweisen, wenn SpecialText keine DependencyProperty ist? –

Verwandte Themen