119 votes

Accès au DataContext parent à partir du DataTemplate

J'ai un ListBox qui se lie à une collection enfant sur un ViewModel. Les éléments de la boîte de liste sont stylisés dans un modèle de données basé sur une propriété du ViewModel parent :

<Style x:Key="curveSpeedNonConstantParameterCell">
   <Style.Triggers>
      <DataTrigger Binding="{Binding Path=DataContext.CurveSpeedMustBeSpecified, 
          ElementName=someParentElementWithReferenceToRootDataContext}" 
          Value="True">
          <Setter Property="Control.Visibility" Value="Hidden"></Setter>
      </DataTrigger>
   </Style.Triggers>
</Style>

J'obtiens l'erreur de sortie suivante :

System.Windows.Data Error: 39 : BindingExpression path error: 
 'CurveSpeedMustBeSpecified' property not found on 
   'object' ''BindingListCollectionView' (HashCode=20467555)'. 
 BindingExpression:Path=DataContext.CurveSpeedMustBeSpecified; 
 DataItem='Grid' (Name='nonConstantCurveParametersGrid');
 target element is 'TextBox' (Name=''); 
 target property is 'NoTarget' (type 'Object')

Donc si je change l'expression de liaison en "Path=DataContext.CurrentItem.CurveSpeedMustBeSpecified" cela fonctionne, mais seulement si le contexte de données du contrôle utilisateur parent est un BindingListCollectionView . Ceci n'est pas acceptable car le reste du contrôle de l'utilisateur se lie aux propriétés de l'objet CurrentItem sur le BindingList automatiquement.

Comment puis-je spécifier l'expression de liaison à l'intérieur du style pour qu'elle fonctionne indépendamment du fait que le contexte de données parent soit une vue de collection ou un élément unique ?

0voto

Lumo Points 508

Oui, vous pouvez le résoudre en utilisant le ElementName=Something comme le suggère la Juve.

MAIS !

Si un élément enfant (sur lequel vous utilisez ce type de liaison) est un contrôle utilisateur qui utilise le même nom d'élément que celui que vous spécifiez dans le contrôle parent, alors la liaison va vers le mauvais objet !

Je sais que ce message n'est pas une solution, mais j'ai pensé que tous ceux qui utilisent le nom de l'élément dans la liaison devraient le savoir, car il s'agit d'un bogue d'exécution possible.

<UserControl x:Class="MyNiceControl"
             x:Name="TheSameName">
   the content ...
</UserControl>

<UserControl x:Class="AnotherUserControl">
        <ListView x:Name="TheSameName">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <MyNiceControl Width="{Binding DataContext.Width, ElementName=TheSameName}" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
</UserControl>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X