2011-09-27 1 views
12

J'ai un UserControl de base qui définit sa DataContext à lui-même pour faciliter la liaison:Réglage DataContext dans UserControl affecte les liaisons dans les parents

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

Il est utilisé dans un fichier XAML parent comme ceci:

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

Pour une raison quelconque, cela génère une erreur de liaison qui semble indiquer que le DataContext du contrôle parent est affecté par le paramètre de contrôle enfant 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')

Pourquoi « PropertyInParentContext » être à la recherche dans le contrôle des enfants plutôt que dans DataContext du parent?

Si je supprime le

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

du contrôle des enfants, alors les choses fonctionnent comment j'attendre.

Est-ce que je manque quelque chose d'évident ici?

Répondre

11

La déclaration de votre contrôle et l'instanciation sont fondamentalement la manipulation du même objet, toutes les propriétés qui sont définies dans la déclaration sont également définies sur chaque instance. Donc, si les propriétés étaient « visibles » pour ainsi dire:

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

C'est pourquoi vous ne définissez pas la DataContext de UserControls, il remplacera le hérité DataContext (et même obscurcir le fait qu'il ya un autre contexte) . Si vous souhaitez lier aux propriétés du UserControl dans sa déclaration, nommez le contrôle et utilisez à la place ElementName ou RelativeSource -bindings.

+0

Merci, je me méprenais sur la portée des fixations et votre post l'expliquait plutôt bien. Je pensais que le XAML d'un UserControl est autonome, comme dans un modèle, mais je suppose que tout cela fait partie du document. – GazTheDestroyer

5

Self signifie que le UserControl, donc lorsque vous définissez la DataContext-Self, vous définissez la DataContext à l'objet UserControl.

La syntaxe correcte pour la liaison à DataContextDataContext d'un contrôle serait {Binding RelativeSource={RelativeSource Self}, Path=DataContext}, cependant puisque le DataContext est hérité par le parent, cette liaison est totalement inutile dans toute situation.

En outre, si vous liez votre DataContext à Self.DataContext, vous créez essentiellement une boucle dans laquelle une valeur est liée à elle-même.

+0

Oui, c'était exactement ce que j'essayais de faire - définir le DataContext à UserControl. Je n'ai pas compris que cela affecterait les instructions de liaison dans le contrôle "parent". – GazTheDestroyer

Questions connexes