2011-07-26 4 views
0

Je crée un contrôle personnalisé qui contient un PasswordBox. Comment puis-je connecter un DependencyProperty de mon contrôle personnalisé à la propriété Password du PasswordBox? De tous les exemples que je vois, le fait d'accrocher le mot de passe dans le modèle en utilisant TemplateBinding devrait faire l'affaire, mais cela ne semble pas fonctionner. Qu'est-ce que je rate?Contrôle interne WP7 Contrôle interne de liaison

generic.xaml

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:CustomControlBinding="clr-namespace:CustomControlBinding"> 

    <Style TargetType="CustomControlBinding:PasswordBoxTest"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="CustomControlBinding:PasswordBoxTest"> 
        <Grid Background="Transparent"> 
         <PasswordBox Password="{TemplateBinding Text}" /> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

</ResourceDictionary> 

PasswordBoxTest.cs

namespace CustomControlBinding 
{ 
    public class PasswordBoxTest : Control 
    { 
     public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(PasswordBoxTest), new PropertyMetadata(OnTextPropertyChanged)); 

     public string Text 
     { 
      get { return GetValue(TextProperty) as string; } 
      set { SetValue(TextProperty, value); } 
     } 

     public PasswordBoxTest() 
     { 
      DefaultStyleKey = typeof(PasswordBoxTest); 
     } 

     public override void OnApplyTemplate() 
     { 
      base.OnApplyTemplate(); 
     } 

     private static void OnTextPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
     { 
     } 
    } 
} 

Répondre

0

Je n'ai pas réussi à faire fonctionner ce que je fais. Ce que j'ai fait à la place, c'est de mettre en place une fausse liaison dans le code.

namespace CustomControlBinding 
{ 
    public class PasswordBoxTest : Control 
    { 
     private PasswordBox passwordBox; 
     private string passwordSetBeforeTemplateApplied; 

     public static readonly DependencyProperty PasswordProperty = DependencyProperty.Register("Password", typeof(string), new PropertyMetadata(OnPasswordPropertyChanged)); 

     public string Password 
     { 
      get { return GetValue(PasswordProperty) as string; } 
      set { SetValue(PasswordProperty, value); } 
     } 

     public PasswordBoxTest() 
     { 
      DefaultStyleKey = typeof(PasswordBoxTest); 
     } 

     public override void OnApplyTemplate() 
     { 
      base.OnApplyTemplate(); 

      passwordBox = (PasswordBox)GetTemplateChild("PasswordElement"); 
      passwordBox.PasswordChanged += PasswordBoxPasswordChanged; 
      if(!string.IsNullOrEmpty(passwordSetBeforeTemplateApplied)) 
      { 
       passwordBox.Password = passwordSetBeforeTemplateApplied; 
      } 
     } 

     public static void OnPasswordPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      ((WatermarkPasswordBox)d).OnPasswordChanged(d, e); 
     } 

     private void OnPasswordChanged( DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      if(passwordBox == null) 
      { 
       passwordSetBeforeTemplateApplied = Password; 
       return; 
      } 

      if(Password != passwordBox.Password) 
      { 
       passwordBox.Password = Password; 
      } 
     } 

     private void PasswordBoxPasswordChanged(object sender, RoutedEventArgs e) 
     { 
      if(passwordBox.Password != Password) 
      { 
       Password = passwordBox.Password; 
      } 
     }  
    } 
} 
0

Vous devez utiliser RelativeSource bindings, pour que cela fonctionne. Ou vous devez définir le DataContext de votre UserControl sur this.

+0

L'utilisation de RelativeSource n'est-elle pas la même que celle de TemplateBinding? '{Reliant RelativeSource = {RelativeSource TemplatedParent}}' http://msdn.microsoft.com/en-us/library/ms742882.aspx –

0

TemplateBinding est ok. Vous devez définir la source de liaison (par exemple via DataContext ou simplement en utilisant l'attribut Text), mais je ne peux pas juger d'où vient le problème puisque vous avez omis ce code.

Je ne sais pas quel est le but de cette classe, mais probablement ajouter quelques fonctionnalités à la PasswordBox standard. Je garderais les deux implémentations aussi similaires que possible. Ce que je veux dire la propriété de texte doit être appelée mot de passe, etc

Sur plus de remarque: Le modèle présenté n'a pas besoin de la grille. À moins que vous n'ayez une raison supplémentaire de l'utiliser, supprimez-le - cela ajoute simplement à la complexité de la mise en page. Notez que le modèle par défaut du PasswordBox est déjà enveloppé dans une grille identique ...

+0

Quel code est omis? –

+0

Je l'ai appelé "Texte" pour être moins déroutant dans ce cas. –

+0

@omitted code: Le code utilisant PasswordBoxTest, bien sûr. Comment pouvons-nous dire ce qui "ne semble pas fonctionner", si vous ne fournissez pas d'informations complètes? Votre code semble correct, d'où le problème doit être dans la partie manquante. –

Questions connexes