Pergunta

Como posso ligar a um UserControlpropriedade de dentro de sua ResourceDictionary? Eu quero um objeto que declaro em meus recursos para ter o mesmo DataContext Enquanto o UserControl está contido em:

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

Em tempo de execução, recebo o erro:

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

Foi útil?

Solução

Minha solução alternativa era definir o DataContext do recurso no código-behind.

.xaml

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

.xaml.cs

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

Outras dicas

Ao usar o FindAncestor, o elemento de destino precisa ser um descendente (lógico ou visual) da fonte. Seu objeto não aparece na árvore visual ou lógica, está simplesmente nos recursos. Portanto, você não pode usar o RelativeRce com o FindAncestor para o seu objeto.

Você pode usar o ElementName em sua ligação. Algo assim deve funcionar:

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

Definir X: compartilhado= "Falso", isso clonará o recurso de cada uso e o tornará um filho do seu elemento, permitindo o uso de ligações.

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

Eu acho que o que você está procurando é apenas {binding} que se liga ao datacontext herdado. Aqui está um exemplo, embora um pouco estranho mostre como você pode pegar uma cor através da ligação ao 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>

O que eu faria é criar um comportamento anexado (contextualizeSourceBeHavior) no controle do usuário e especificar a chave do recurso nesse comportamento anexado. O comportamento procuraria o recurso (não tenho certeza se você seria capaz de fazê -lo, se não precisará conectar o evento carregado) e transferir o contexto de dados.

Quando você adiciona seu recurso à árvore visual, ele deve herdar o contexto de dados. Mas ... dê uma olhada em elemento espião Pode fazer o que você precisa.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top