Question

Comment puis-je lier à la propriété d'un UserControl à partir de son ResourceDictionary? Je veux un objet que je déclare dans mes ressources pour avoir le même DataContext que le UserControl est contenu dans:

<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>

Lors de l'exécution, je reçois l'erreur:

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')

Était-ce utile?

La solution

Ma solution était de mettre la DataContext de la ressource dans le code-behind.

XAML

<local:SomeType x:Key="SomeKey" SomeProperty="{Binding ... }" />

.xaml.cs

public SomeControl()
{
    InitializeComponent();
    ((SomeType)this.Resources["SomeKey"]).DataContext = this;
}

Autres conseils

Lors de l'utilisation FindAncestor, l'élément-cible doit être un descendant (soit logique ou visuel) de la source. Votre objet ne figure pas dans l'arbre soit visuel ou logique, il est tout simplement dans les ressources. Donc, vous ne pouvez pas utiliser RelativeSource avec FindAncestor pour votre objet.

Vous pouvez utiliser ElementName dans votre Binding bien. Quelque chose comme cela devrait fonctionner:

<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: Partagé = "Faux", ce clonera ressource sur chaque utilisation et en faire un enfant de votre élément, ce qui permet l'utilisation de liaisons.

<local:SomeClass
            x:Key="SomeClass"
            x:Shared="False"
            DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />

Je pense que ce que vous cherchez est juste {} La liaison qui se lie au DataContext hérité. Voici un exemple, si un peu étrange montre comment vous pouvez saisir une couleur en se liant à la DataContext:

<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>

Ce que je voudrais faire est de créer un comportement attaché (ContextualizeResourceBehavior) sur le contrôle de l'utilisateur, et spécifier la clé des ressources sur ce comportement attaché. Le comportement de la ressource serait lookup (pas sûr que vous seriez en mesure de le faire lors du rattachement, si vous auriez pas besoin de brancher événement Loaded) et transférer le contexte de données.

lorsque vous ajoutez votre ressource à l'arbre visuel, il devrait hériter du contexte de données. mais ... un coup d'oeil à il pourrait tout simplement faire ce que vous avez besoin.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top