Die Bindung an Vorfahren aus einem Resource
-
20-09-2019 - |
Frage
Wie kann ich binden an einer Immobilie UserControl
aus seiner ResourceDictionary
? Ich möchte ein Objekt in meinem Ressourcen erklären die gleiche DataContext
haben, wie die UserControl
es in enthalten ist:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Some.Namespace"
DataContext="{Binding Path=ViewModel, RelativeSource={RelativeSource Self}}">
<UserControl.Resources>
<local:SomeClass
x:Key="SomeClass"
DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
</UserControl.Resources>
</UserControl>
Zur Laufzeit ich den Fehler:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='UserControl', AncestorLevel='1''. BindingExpression:Path=DataContext; DataItem=null; target element is 'SomeClass' (Name=''); target property is 'DataContext' (type 'Object')
Lösung
Meine Abhilfe war die DataContext
der Ressource in dem Code-Behind zu setzen.
XAML
<local:SomeType x:Key="SomeKey" SomeProperty="{Binding ... }" />
.xaml.cs
public SomeControl()
{
InitializeComponent();
((SomeType)this.Resources["SomeKey"]).DataContext = this;
}
Andere Tipps
Wenn FindAncestor verwendet, muss das Zielelement einen Nachkommen (entweder logischen oder visuellen) der Quelle sein. Ihr Objekt nicht erscheint entweder in der visuellen oder logischen Struktur, es ist einfach in den Ressourcen. So kann man nicht mit Relative FindAncestor für Ihr Objekt verwenden.
Sie können den Elementnamen in Ihrem Binding obwohl verwenden. So etwas sollte funktionieren:
<UserControl x:Name="userControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Some.Namespace"
DataContext="{Binding Path=ViewModel, RelativeSource={RelativeSource Self}}">
<UserControl.Resources>
<local:SomeClass
x:Key="SomeClass"
DataContext="{Binding Path=DataContext, ElementName=userControl}" />
</UserControl.Resources>
</UserControl>
x: Geteilt = "False", dieser Wille Klon Ressource auf jede Verwendung und es ist ein Kind von Ihrem Elemente machen, so dass Nutzung von Bindungen.
<local:SomeClass
x:Key="SomeClass"
x:Shared="False"
DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
Ich denke, was Sie suchen gerade ist {Binding}, welche bindet an die geerbte Datacontext. Hier ist ein Beispiel, wenn auch ein seltsames zeigt biss, wie Sie eine Farbe, die durch die Bindung an den Datacontext greifen können:
<Window x:Class="AncestorBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Blue" />
</Window.Resources>
<StackPanel>
<Button DataContext="{Binding Source={StaticResource MyBrush}}" Content="My Button">
<Button.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{Binding}" />
</Style>
</Button.Resources>
</Button>
</StackPanel>
</Window>
Was ich tun würde, ist ein angeschlossenes Verhalten (ContextualizeResourceBehavior) auf der Benutzerkontrolle zu erstellen, und geben Sie den Ressourcenschlüssel an diesem angebracht Verhalten. Das Verhalten würde Lookup die Ressource (nicht sicher, Sie wären in der Lage, es auf anhängen zu tun, wenn du nicht auf Loaded-Ereignis anschließen müssten) und den Datenkontext übertragen.
Wenn Sie Ihre Ressource der visuellen Struktur hinzufügen, sollte es den Datenkontext erben. aber ... haben Sie einen Blick auf Element Spion es könnte nur das tun, was Sie brauchen.