2010-12-08 8 views
1

J'ai créé un contrôle personnalisé dans WPF et je n'arrive pas à le lier correctement. Si je définis explicitement la valeur de la propriété dans le code, tout fonctionne correctement.Problème de liaison WPf

Voici le XAML pour le TextBox dans mon contrôle:

<TextBox Name="txtText" Grid.Row="0" Grid.Column="0" IsReadOnly="True" Text="{Binding Text, Mode=OneWay}" /> 

et les propriétés pertinentes du code sont à l'origine comme suit:

public static readonly DependencyProperty TextConverterProperty = DependencyProperty.Register("TextConverter", typeof(IValueConverter), typeof(Selector)); 
public static readonly DependencyProperty EntityIdProperty = DependencyProperty.Register("EntityId", typeof(long), typeof(Selector)); 

public string Text 
{ 
    get 
    { 
     string result = this.EntityId.ToString(); 

     if (this.TextConverter != null) 
     { 
      result = this.TextConverter.Convert(result, null, null, null) as string; 
     } 

     return result; 
    } 
} 

public long EntityId 
{ 
    get 
    { 
     return (long)this.GetValue(EntityIdProperty); 
    } 
    set 
    { 
     this.SetValue(EntityIdProperty, value); 

     this.OnPropertyChanged("Text"); 
     this.OnPropertyChanged("EntityId"); 
    } 
} 

public IValueConverter TextConverter 
{ 
    get 
    { 
     return this.GetValue(TextConverterProperty) as IValueConverter; 
    } 
    set 
    { 
     this.SetValue(TextConverterProperty, value); 
    } 
} 

Et maintenant la mise en œuvre de XAML dans ma page:

<controls:Selector x:Name="txtReferringCase" EntityId="{Binding ReferringDACaseId}" TextConverter="{StaticResource daCaseNumberConverter}" Grid.Column="5" Grid.Row="0" Grid.ColumnSpan="3" ButtonClicked="txtReferringCase_ButtonClicked" /> 

Maintenant, voici la partie étrange. Je peux régler la DataContext pour la page et rien ne se passe, mais quand je décommenter la ligne commentée, le texte apparaît dans mon contrôle utilisateur sans problème:

_caseScreen = new DACaseScreen(itemId); 
this.DataContext = _caseScreen; 
//this.txtReferringCase.EntityId = _caseScreen.ReferringDACaseId; 

EDIT: Une autre chose que j'oublié de mentionner .. Si j'atteins un point d'arrêt et que je vérifie les propriétés EntityId et Text du contrôle, ils affichent tous les deux les valeurs auxquelles je m'attendrais. Il semble que l'interface utilisateur ne soit pas mise à jour.

+0

Que pensez-vous qu'il arrivera lorsque vous modifierez 'DataContext'? – Jon

Répondre

1

accesseurs et de mutateurs pour DependencyProperties doivent seulement appeler GetValue et SetValue parce que XAML ne les utilise pas, ils ne sont pour plus de commodité. Si vous voulez un comportement supplémentaire, enregistrez votre DependencyProperty en transmettant un gestionnaire de changement qui fait ce que vous voulez.

public static readonly DependencyProperty EntityIdProperty = DependencyProperty.Register("EntityId", typeof(long), typeof(Selector),new UIPropertyMetadata(EntityIdChanged)); 

public long EntityId 
{ 
    get 
    { 
     return (long)this.GetValue(EntityIdProperty); 
    } 
    set 
    { 
     this.SetValue(EntityIdProperty, value); 
    } 
} 

private static void EntityIdChanged(object sender, DependencyPropertyChangedEventArgs e) 
{ 
    var control = (Selector)sender; 
    control.OnPropertyChanged("Text"); 
} 

Vous n'avez pas besoin d'appeler PropertyChanged pour des propriétés de dépendance. J'ai également besoin de changer la liaison txtText dans votre UserControl en réglant la source sur le contrôle lui-même et non sur DataContext, mais si vous définissez la propriété dans le code, cela devrait fonctionner. Vous pouvez renommer votre contrôle car il existe un contrôle intégré appelé Selector mais ce n'est pas si important.

+0

Parfait. Je vous remercie! –

0

Votre interface utilisateur ne sera pas mise à jour jusqu'à ce que vous effectuez un appel OnPropertyChanged. Le réglage DataContext ne déclenchera pas cela.

En outre, vous faites:

public static readonly DependencyProperty TextConverterProperty = DependencyProperty.Register("TextConverter", typeof(IValueConverter), typeof(Selector)); 
public static readonly DependencyProperty EntityIdProperty = DependencyProperty.Register("EntityId", typeof(long), typeof(Selector)); 

Mais vous n'enregistrer la dépendance du texte, ne TextConverter et entityID. Signification, votre OnPropertyChanged ne fonctionnera pas (?) (Ou avez-vous simplement oublier de montrer que la ligne ici :))

+0

Le texte n'a pas de dépendance si vous ne liez pas ** à ** it. Vous pouvez déclencher OnPropertyChanged sur "Texte" même si ce n'est pas une propriété de dépendance – Vitalik