2010-05-11 5 views
2

J'ai un problème ennuyant avec la liaison WPF. Fondamentalement, je déclare un FrameworkElement dans les ressources de mon UserControl, mais cet élément ne semble pas être notifié lorsque le DataContext de l'UserControl parent change.Get notifié de DataContext modifié dans une ressource WPF

Fondamentalement, dans mon UserControl j'ai un popup dans le ItemTemplate pour un ItemsControl. Dans ce Popup, j'avais besoin de me lier à quelque chose dans ViewModel de la vue parente, donc j'ai trouvé ce que je pensais être un truc intelligent. Se inspirant de CollectionViewSource, je me suis dit que je venais de me lier le modèle de vue des parents à une ressource, et ensuite utiliser cette ressource pour se rendre à l'ViewModel du DataTemplate, comme ceci:

<UserControl.Resources> 
     <cont:ViewModelSource Source="{Binding}" x:Key="ParentViewModel"/> 
    </UserControl.Resources> 

Alors que plus tard je peux l'utiliser comme:

CommandParameter="{Binding ViewModel.OpenEntity, Source={StaticResource ParentViewModel}}" 

tout cela semble travailler sauf que le DataContext sur la ViewModelSource ne reçoit pas réinitialisée lorsque le DataContext du UserControl se réinitialiser. À l'heure actuelle, je fais ce travail de manière hackily: définir le DataContext de la ressource dans code-behind sur l'événement DataContextChanged de UserControl.

J'ai jeté un coup d'oeil dans Reflector pour voir comment CollectionViewSource fait cela, mais il ne semble pas faire quelque chose de spécial.

Quelqu'un sait pourquoi cela se passe ou comment je peux le réparer?

Répondre

2

J'ai eu le même problème et j'ai trouvé une solution.

J'ai d'abord essayé de définir mon ViewModel en tant que DataContext de mon élément racine. faux.

Ensuite, j'ai essayé de définir mon ViewModel en tant que ressource et de définir la source de liaison de mon élément racine à la ressource. faux.

Enfin, j'ai créé un IValueConverter pour convertir un modèle (qui est DataContext du contrôle) en un ViewModel. Ensuite, je lie DataContext de mon élément racine avec le convertisseur.

<UserControl.Resources> 

    <local:PersonToControllerConverter x:Key="PersonToControllerConverter"/> 

    <!--<local:PersonController x:Key="controller" 
     Value="{Binding}" 
     Parent="{Binding Path=DataContext,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}" 
     />--> 

</UserControl.Resources> 



<Border x:Name="root" BorderBrush="Black" BorderThickness="2" > 
    <Border.DataContext> 
     <MultiBinding Converter="{StaticResource PersonToControllerConverter}"> 
      <Binding/> 
      <Binding Path="DataContext" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}"/> 
     </MultiBinding> 
    </Border.DataContext> 

    <!--DataContext="{Binding Source={StaticResource controller}}">--> 

    <!--<Border.DataContext> 
     <local:PersonController 
        Value="{Binding}" 
        Parent="{Binding Path=DataContext,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}" 
        /> 
    </Border.DataContext>--> 

Je pense que lorsque le DataContext rompt la liaison dans un élément, lorsque les changements de DataContext sur un élément racine, il arrête sur la liaison brisée.

1

Peut-être que vous devez créer un objet intermédiaire qui implémentent l'interface INotifyPropertyChanged.

Questions connexes