2011-09-27 7 views
12

tengo un básico UserControl que establece su DataContext a sí mismo para facilitar la unión:DataContext de ajuste dentro de control de usuario está afectando fijaciones en los padres

<UserControl x:Class="MyControlLib.ChildControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 

      DataContext="{Binding RelativeSource={RelativeSource Self}}"> 

</UserControl> 

Esto se utiliza en un archivo XAML padres así:

<UserControl x:Class="MyControlLib.ParentControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:ctrl="clr-namespace:MyControlLib"> 

      <ctrl:ChildControl x:Name="ChildName" 
           PropertyOnChild="{Binding PropertyInParentContext}"/>    
</UserControl> 

Por alguna razón, esto da un error de enlace que parece indicar que el DataContext del control principal se está viendo afectado por el control secundario que establece su propio DataContext.

System.Windows.Data Error: 40 : BindingExpression path error: 'PropertyInParentContext' property not found on 'object' ''ChildControl' (Name='ChildName')'. BindingExpression:Path=PropertyInParentContext; DataItem='ChildControl' (Name='ChildName'); target element is 'ChildControl' (Name='ChildName'); target property is 'PropertyOnChild' (type 'whatever')

¿Por qué es "PropertyInParentContext" está buscando en el control secundario en lugar de en DataContext de los padres?

Si quito el

DataContext="{Binding RelativeSource={RelativeSource Self}} 

del control de control, entonces las cosas funcionan de cómo iba a esperar.

¿Me falta algo obvio aquí?

Respuesta

11

La declaración de su control y la creación de instancias básicamente manipulan el mismo objeto, todas las propiedades que se establecen en la declaración también se establecen en cada instancia. Así que si las propiedades eran "visible" por así decirlo:

<UserControl x:Class="MyControlLib.ParentControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:ctrl="clr-namespace:MyControlLib"> 
    <ctrl:ChildControl x:Name="ChildName" 
         DataContext="{Binding RelativeSource={RelativeSource Self}}" 
         PropertyOnChild="{Binding PropertyInParentContext}"/> 
</UserControl> 

Es por eso que no se establece la DataContext de UserControls, se anulará el DataContext heredada (e incluso ocultar el hecho de que existe un contexto diferente) . Si desea enlazar a las propiedades del UserControl en su declaración, asigne un nombre al control y use en su lugar los enlaces ElementName o RelativeSource.

+0

Gracias, estaba malinterpretando el alcance de las vinculaciones y su publicación lo explicó bastante bien. Estaba pensando que el XAML de un UserControl es autónomo, como en una plantilla, pero creo que todo es solo parte del documento. – GazTheDestroyer

5

Self significa que el UserControl, por lo que cuando se establece el DataContext a Self, se está ajustando el DataContext al objeto UserControl.

La sintaxis correcta para enlazar a un DataContext de un Control sería {Binding RelativeSource={RelativeSource Self}, Path=DataContext}, sin embargo, dado que el ParentCon hereda el DataContext, este enlace es totalmente innecesario en cualquier situación.

Además, si enlaza su DataContext al DataContext, básicamente creará un bucle donde un valor está vinculado a sí mismo.

+0

Sí, eso era exactamente lo que intentaba hacer: configurar el DataContext en UserControl. No entendí que esto afectaría las declaraciones vinculantes en el control "principal". – GazTheDestroyer

Cuestiones relacionadas