Domanda

Come posso associare alla proprietà di un UserControl dal di dentro la sua ResourceDictionary? Voglio un oggetto dichiaro le mie risorse per avere lo stesso DataContext come UserControl è contenuto in:

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

In fase di runtime ottengo l'errore:

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

È stato utile?

Soluzione

La mia soluzione era quella di impostare il DataContext della risorsa nel code-behind.

XAML

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

.xaml.cs

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

Altri suggerimenti

Quando si utilizza FindAncestor, l'elemento di destinazione deve essere un discendente (sia logico o visiva) della sorgente. Il vostro oggetto non compare né nella struttura ad albero visuale o logico, è semplicemente nelle risorse. Quindi non è possibile utilizzare RelativeSource con FindAncestor per l'oggetto.

È possibile utilizzare ElementName nel Binding però. Qualcosa del genere dovrebbe funzionare:

<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: Shared = "False", questo sarà clonare risorsa ogni uso e ne fanno un figlio del vostro elemento, consentendo l'utilizzo di attacchi.

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

Penso che quello che stai cercando è solo {} rilegatura che si lega al DataContext ereditato. Ecco un esempio, anche se un po 'strano mostra come si può afferrare un colore attraverso il legame al 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>

Quello che vorrei fare è quello di creare un comportamento allegato (ContextualizeResourceBehavior) sul controllo utente e specificare la chiave di risorsa su quel comportamento allegato. Il comportamento sarebbe occhiata la risorsa (non sono sicuro si sarebbe in grado di farlo da allegare, se non si avrebbe bisogno di collegare evento Loaded) e trasferire il contesto dati.

quando si aggiunge la risorsa per l'albero visuale dovrebbe ereditare il contesto dati. ma ... dare un'occhiata al elemento spia potrebbe solo fare ciò che è necessario.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top