2010-01-15 23 views
6

¿Cómo puedo enlazar a una propiedad de UserControl desde dentro de ResourceDictionary? Quiero un objeto declaro en mis recursos tenga la misma DataContext como el UserControl está contenida en:Enlazando a antepasados ​​dentro de un ResourceDictionary

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

En tiempo de ejecución se produce el error:

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

+0

Configuración de la DataContext directamente en el código subyacente funciona, pero me gustaría una solución XAML ... ((SomeClass) this.Resources [ "SomeClass"]) = DataContext modelo de vista.; –

+0

Creo que el contexto de herencia podría influir en este problema ... http://blogs.msdn.com/nickkramer/archive/2006/08/18/705116.aspx –

Respuesta

2

Mi solución fue establecer la DataContext del recurso en el código subyacente.

.xaml

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

.xaml.cs

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

Gracias por responder a su propia pregunta (en serio). Nunca he visto una solución solo XAML para este problema. También afecta a ContextMenu, MenuItem y MenuItem.Icon. Me vuelve loca. Esto parece frustrar el propósito de XAML. – kevinarpe

0

Creo que lo que' lo que estamos buscando es solo {Binding} que se une al DataContext heredado. He aquí un ejemplo, aunque un poco espectáculos extraños cómo se puede tomar un color a través de la unión a 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> 
+0

Lamentablemente, {Binding} no funciona para mí-- No se puede encontrar el elemento que proporciona DataContext. BindingExpression: (sin ruta); DataItem = null; el elemento objetivo es 'SomeClass' (Name = ''); target property es 'DataContext' (tipo 'Object') –

+0

¿Ha intentado no configurar DataContext en absoluto? Creo que su local: SomeClass heredaría el DataContext del UserControl. –

+0

Originalmente me encontré con este problema porque no configuré el DataContext en absoluto: http://stackoverflow.com/questions/2073170 –

0

Lo que yo haría es crear un comportamiento adjunto (ContextualizeResourceBehavior) en el control de usuario y especificar el recurso clave en ese comportamiento adjunto. El comportamiento buscaría el recurso (no estoy seguro de poder hacerlo en el archivo adjunto, si no fuera así, necesitaría conectar el evento Cargado) y transferir el contexto de datos.

0

cuando agrega su recurso al árbol visual, debe heredar el contexto de datos. pero ... eche un vistazo a element spy que podría hacer justo lo que necesita.

1

Al usar FindAncestor, el elemento de destino debe ser un descendiente (ya sea lógico o visual) de la fuente. Su objeto no aparece en el árbol visual o lógico, simplemente está en los recursos. Por lo tanto, no puede usar RelativeSource con FindAncestor para su objeto.

Aunque puede usar ElementName en su Enlace. Algo como esto debería 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> 
+3

Esto no funcionó para mí. El enlace no pudo encontrar el nombre del elemento utilizando x: Nombre o Nombre. –

0

Establecer x:Shared = "falso", esto va a clonar recursos en cada uso y que sea de un niño su elemento, permitiendo el uso de enlaces.

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