2010-01-11 5 views
1

J'utilise un pattern viewmodel, mon DataContext pour mon contrôle utilisateur personnalisé est en fait un wrapper viewmodel pour les données réelles.Comment définir DataContext sans effacer les propriétés de dépendance?

Mon contrôle personnalisé peut contenir des instances hiérarchiques du contrôle personnalisé.

Je configure un DependencyProperty dans le contrôle personnalisé pour le vrai morceau de données, avec l'espoir de créer un nouveau viewmodel pour ces données lorsqu'il est défini par liaison, puis de définir le datacontext du contrôle utilisateur au nouveau viewmodel. Cependant, il semble que la définition de la propriété DataContext entraîne l'invalidation de mes données réelles DependencyProperty et leur définition à null. Quelqu'un sait-il comment contourner cela, ou plutôt comment utiliser les viewmodels?

échantillons Parage de ce que je suis en train de faire:

Le contrôle de l'utilisateur:

public partial class ArchetypeControl : UserControl 
{ 
    public static readonly DependencyProperty ArchetypeProperty = DependencyProperty.Register(
     "Archetype", 
     typeof(Archetype), 
     typeof(ArchetypeControl), 
     new PropertyMetadata(null, OnArchetypeChanged) 
    ); 

    ArchetypeViewModel _viewModel; 

    public Archetype Archetype 
    { 
     get { return (Archetype)GetValue(ArchetypeProperty); } 
     set { SetValue(ArchetypeProperty, value); } 
    } 

    private void InitFromArchetype(Archetype newArchetype) 
    { 
     if (_viewModel != null) 
     { 
      _viewModel.Destroy(); 
      _viewModel = null; 
     } 

     if (newArchetype != null) 
     { 
      _viewModel = new ArchetypeViewModel(newArchetype); 

      // calling this results in OnArchetypeChanged getting called again 
      // with new value of null! 
      DataContext = _viewModel; 
     } 
    } 

    // the first time this is called, its with a good NewValue. 
    // the second time (after setting DataContext), NewValue is null. 
    static void OnArchetypeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 
    { 
     var control = (ArchetypeControl)obj; 

     control.InitFromArchetype(args.NewValue as Archetype); 
    } 
} 

Le viewmodel:

class ArchetypeComplexPropertyViewModel : ArchetypePropertyViewModel 
{ 
    public Archetype Value { get { return Property.ArchetypeValue; } } 
} 

Le XAML:

<Style TargetType="{x:Type TreeViewItem}"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding ViewModelType}" Value="{x:Type c:ArchetypeComplexPropertyViewModel}"> 
       <Setter Property="Template" Value="{StaticResource ComplexPropertyTemplate}" /> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 

<ControlTemplate x:Key="ComplexPropertyTemplate" TargetType="{x:Type TreeViewItem}"> 
     <Grid> 
      <c:ArchetypeControl Archetype="{Binding Value}" /> 
     </Grid> 
    </ControlTemplate> 

Ce problème a été mentionné dans le commentaires de Cannot databind DependencyProperty mais jamais résolus

+0

Le fait de mélanger un ensemble de liaisons de l'extérieur (implicitement en utilisant un DataContext) et de définir un nouveau DataContext ne fonctionne pas, comme vous l'avez découvert. Voir aussi http://stackoverflow.com/questions/25672037/how-to-correctly-bind-to-a-dependency-property-of-a-usercontrol-in-a-mvvm-framew –

Répondre

1

En faisant cela:

<c:ArchetypeControl Archetype="{Binding Value}" /> 

vous liez votre Archetype propriété à la propriété appelée Value sur votre contexte de données. En modifiant votre contexte de données au nouveau ArchetypeViewModel, vous effectuez une nouvelle évaluation de la liaison. Vous devez vous assurer que le nouvel objet ArchetypeViewModel possède une propriété non nulle Value. Sans voir le plus de votre code (en particulier, les définitions de ArchetypeComplexPropertyViewModel et ArchetypePropertyViewModel) je ne peux pas vraiment dire quelle est la cause de cela.

Questions connexes