2009-05-14 7 views
0

Ich habe ein UserControl (a) mit einem Stackpanel, dessen ItemSource auf eine Auflistung festgelegt ist. Das StackPanel enthält dann eine Gruppe von UserControl (b), die ein paar Schaltflächen und ein DataGrid-Steuerelement enthalten. Gibt es einen Weg aus dem Code im UserControl (b), um auf Eigenschaften im Code hinter dem übergeordneten UserControl (a) zuzugreifen.WPF-Zugriffsinformationen aus dem enthaltenden Steuerelement

Wenn UserControl (a) in ein Fenster geladen wird, wird ein Parameter übergeben, der angibt, ob das Formular als schreibgeschützt betrachtet wird oder nicht. Ich möchte die Sichtbarkeit der Schaltflächen in Usercontrol (b) an die Eigenschaft readonly im Codebehind des übergeordneten UserControl (a) binden.

Antwort

2

Normalerweise würde ich mit WPF vorschlagen, dass Sie das Model-View-ViewModel-Muster implementieren (siehe MSDN).

Mit diesem Muster erstellen Sie ein ViewModel mit allen Daten, die Sie binden möchten. Dies würde als Datenkontext für die Benutzersteuerung (a) festgelegt werden. Dieses Steuerelement würde dann alle Steuerelemente an Eigenschaften im Datenkontext binden.

Die untergeordnete (b) Benutzersteuerung würde diesen Datenkontext erben und könnte daher seine Steuerelemente an die gleichen Eigenschaften binden, die (a) verwendet werden. Dies liegt daran, dass Datenkontexte in der logischen (und visuellen) Struktur bis zu dem Zeitpunkt, an dem sie überschrieben werden, vererbt werden.

Also für Sie würde ich ein ViewModel erstellen, das die Eigenschaft ReadOnly enthält. Sie können dieses ViewModel-Objekt dann als Datenkontext für die Benutzersteuerung (a) festlegen. Die (b) Benutzersteuerung erbt denselben Datenkontext, da sie unter der Benutzersteuerungshierarchie (a) liegt. Dadurch können Sie die Steuerelemente innerhalb von (b) an dieselben Eigenschaften wie (a) binden, wie unten gezeigt.

Um den Datenkontext in der Ansicht Code-Behind einzustellen, mache ich etwas wie diesen Konstruktor unten gezeigt.

public MyView(IMyViewModel viewModel) 
{ 
    InitializeComponent(); 
    DataContext = viewModel; 
} 

MyView ist die Klasse, die in Ihrer Instanz von UserControl erbt. Sie müssen das Ansichtsmodell nicht so verwenden, wie ich es getan habe. Ich verwende Unity, um das Ansichtsmodell in die Ansichten einzufügen, die automatisch erstellt werden, seit ich Prism verwende, aber Sie können es einfach als normales Objekt erstellen und zuweisen zum Datenkontext.

Beachten Sie, dass ich auch den Befehl an die Schaltfläche mit dem Datenkontext gebunden habe, da ich diese normalerweise auch über das ViewModel verfügbar mache. Dies ist einfach, wenn Sie eine Wrapperklasse erstellen, die ICommand und Proxys für einen Delegaten implementiert. Siehe DelegateCommand blog article oder sehen Sie sich die DelegateCommand-Klasse in Prism an, wenn Sie interessiert sind.

Wenn Sie aus irgendeinem Grund den Datenkontext außer Kraft setzen, was passieren kann, wenn Sie eine Master-/Detailansicht verwenden, in der Sie den Datenkontext des Detailbereichs der Ansicht als aktuell ausgewähltes Element in der Liste ändern, können Sie weiterhin Greifen Sie auf den übergeordneten Datenkontext zu, indem Sie eine relative Quellbindung verwenden.

z.

<ComboBox Grid.Row="1" Grid.Column="1" x:Name="Unit" IsReadOnly="True" 
     ItemsSource="{Binding Path=DataContext.AvailableUnits, RelativeSource= 
        {RelativeSource Mode=FindAncestor, 
            AncestorType={x:Type Window}}}" 
     DisplayMemberPath="Name" SelectedItem="{Binding Unit}" /> 

Notiere die Itemssource-Bindung verwendet eine relativ Quelle das übergeordnete Fenster zu finden und binden dann an eine Eigenschaft es ist Datacontext. Ich habe auch die ItemsSource-Bindung innerhalb der Anführungszeichen über mehrere Zeilen aufgeteilt, um Klarheit zu schaffen, aber tue das nicht in deinem XAML, ich bin mir nicht sicher, ob es dort funktionieren wird (nicht versucht zu sehen, ob Markup-Erweiterungen tolerant gegenüber Leerzeichen sind).

Verwandte Themen