Ich habe eine, ListBox
die an eine untergeordnete Sammlung in einem ViewModel gebunden ist. Die Listbox-Elemente werden in einer Datenvorlage basierend auf einer Eigenschaft im übergeordneten ViewModel gestaltet:
<Style x:Key="curveSpeedNonConstantParameterCell">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=DataContext.CurveSpeedMustBeSpecified,
ElementName=someParentElementWithReferenceToRootDataContext}"
Value="True">
<Setter Property="Control.Visibility" Value="Hidden"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
Ich erhalte folgenden Ausgabefehler:
System.Windows.Data Error: 39 : BindingExpression path error:
'CurveSpeedMustBeSpecified' property not found on
'object' ''BindingListCollectionView' (HashCode=20467555)'.
BindingExpression:Path=DataContext.CurveSpeedMustBeSpecified;
DataItem='Grid' (Name='nonConstantCurveParametersGrid');
target element is 'TextBox' (Name='');
target property is 'NoTarget' (type 'Object')
Wenn ich also den Bindungsausdruck so ändere, "Path=DataContext.CurrentItem.CurveSpeedMustBeSpecified"
funktioniert er, aber nur solange der Datenkontext des übergeordneten Benutzersteuerelements a ist BindingListCollectionView
. Dies ist nicht akzeptabel, da der Rest des Benutzersteuerelements automatisch an die Eigenschaften von CurrentItem
on the BindingList
gebunden wird.
Wie kann ich den Bindungsausdruck innerhalb des Stils angeben, damit er funktioniert, unabhängig davon, ob der übergeordnete Datenkontext eine Sammlungsansicht oder ein einzelnes Element ist?
Sie können verwenden
RelativeSource
, um das übergeordnete Element wie folgt zu finden:Weitere Informationen zu finden Sie in dieser SO-Frage
RelativeSource
.quelle
Mode=FindAncestor
dass es funktioniert, aber dies funktioniert und ist in einem MVVM-Szenario viel besser, da es die Benennung von Steuerelementen vermeidet.Binding="{Binding Path=DataContext.CurveSpeedMustBeSpecified, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:YourParentElementType}}}"
RelativeSource vs. ElementName
Diese beiden Ansätze können das gleiche Ergebnis erzielen:
RelativeSrouce
Diese Methode sucht nach einem Steuerelement vom Typ Fenster (in diesem Beispiel) im visuellen Baum. Wenn es gefunden wird, können Sie im Grunde genommen
DataContext
über das Steuerelement auf das Steuerelement zugreifenPath=DataContext....
. Die Vorteile dieser Methode sind, dass Sie nicht an einen Namen gebunden sein müssen und sie dynamisch ist. Änderungen an Ihrem visuellen Baum können sich jedoch auf diese Methode auswirken und sie möglicherweise beschädigen.Elementname
Diese Methode bezieht sich auf eine feste statische Aufladung.
Name
Solange Ihr Gültigkeitsbereich dies erkennen kann, ist alles in Ordnung. Sie sollten sich an Ihre Namenskonvention halten, um diese Methode natürlich nicht zu brechen. Der Ansatz ist sehr einfach und Sie müssen nur angeben aName="..."
für Ihr Window / UserControl.Obwohl alle drei Typen (
RelativeSource, Source, ElementName
) in der Lage sind, dasselbe zu tun, sollte gemäß dem folgenden MSDN-Artikel jeder besser in seinem eigenen Fachgebiet verwendet werden.Gewusst wie: Geben Sie die Bindungsquelle an
Die kurze Beschreibung der einzelnen Elemente sowie einen Link zu weiteren Details finden Sie in der Tabelle unten auf der Seite.
quelle
Ich habe nach einer ähnlichen Vorgehensweise in WPF gesucht und diese Lösung erhalten:
Ich hoffe das funktioniert für jemand anderen. Ich habe einen Datenkontext, der automatisch auf die ItemsControls gesetzt wird, und dieser Datenkontext hat zwei Eigenschaften:
MyItems
- eine Sammlung - und einen Befehl 'CustomCommand'. Aufgrund derItemTemplate
Verwendung von aDataTemplate
ist dieDataContext
der oberen Ebenen nicht direkt zugänglich. Die Problemumgehung zum Abrufen des DC des übergeordneten Elements besteht darin, einen relativen Pfad zu verwenden und nachItemsControl
Typ zu filtern .quelle
Das Problem ist, dass ein DataTemplate nicht Teil eines Elements ist, das auf es angewendet wird.
Dies bedeutet, wenn Sie an die Vorlage binden, binden Sie an etwas, das keinen Kontext hat.
Wenn Sie jedoch ein Element in die Vorlage einfügen, erhält dieses Element, wenn es auf das übergeordnete Element angewendet wird, einen Kontext, und die Bindung funktioniert dann
Das wird also nicht funktionieren
aber das funktioniert perfekt
Denn nachdem die Datenvorlage angewendet wurde, wird das Gruppenfeld im übergeordneten Element abgelegt und hat Zugriff auf seinen Kontext
Sie müssen also nur den Stil aus der Vorlage entfernen und in ein Element in der Vorlage verschieben
Beachten Sie, dass der Kontext für ein Elementsteuerelement das Element und nicht das Steuerelement ist, dh ComboBoxItem für ComboBox, nicht die ComboBox selbst. In diesem Fall sollten Sie stattdessen die Steuerelemente ItemContainerStyle verwenden
quelle
Ja, Sie können es mit dem
ElementName=Something
von Juve vorgeschlagenen lösen .ABER!
Wenn ein untergeordnetes Element (für das Sie diese Art der Bindung verwenden) ein Benutzersteuerelement ist, das denselben Elementnamen verwendet, den Sie im übergeordneten Steuerelement angegeben haben, wird die Bindung an das falsche Objekt gesendet !!
Ich weiß, dass dieser Beitrag keine Lösung ist, aber ich dachte, jeder, der den ElementName in der Bindung verwendet, sollte dies wissen, da es sich um einen möglichen Laufzeitfehler handelt.
quelle