2011-07-26 47 views
0

我正在創建一個自定義控件,其中包含PasswordBox。如何將我的自定義控件的DependencyProperty連接到PasswordBoxPassword屬性?WP7自定義控件綁定內部控件

從我看到的所有示例中,使用TemplateBinding將模板中的密碼掛鉤到模板中應該可以做到,但這似乎不起作用。我錯過了什麼?

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) 
     { 
     } 
    } 
} 

回答

0

無論我做什麼,我都無法使其工作。我所做的就是在代碼中設置一些僞裝。

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

你必須使用RelativeSource bindings,爲它工作。或者您必須將您的UserControl的DataContext設置爲this

+0

是不是使用與TemplateBinding相同的RelativeSource? '{Binding RelativeSource = {RelativeSource TemplatedParent}}'http://msdn.microsoft.com/en-us/library/ms742882.aspx –

0

TemplateBinding沒問題。你需要以某種方式設置綁定源(例如通過提到的DataContext或者簡單地在Xaml中使用Text屬性),但是由於省略了這些代碼,我無法判斷問題出在哪裏。

我不知道這個班的目的是什麼,但可能在標準PasswordBox中添加了一些功能。我會盡可能保持兩個實現類似。我的意思是文本屬性應該被稱爲密碼等。

關於更多的評論:提交的模板不需要網格。除非你有使用它的額外理由,否則刪除它 - 它只會增加布局的複雜性。請注意,密碼框的默認模板已包裝在同一個網格中...

+0

什麼代碼被省略? –

+0

在這種情況下,我將它命名爲「文本」以減少混淆。 –

+0

@omitted代碼:當然使用PasswordBoxTest的代碼。如果你不提供完整的信息,我們如何能說出「似乎沒有工作」?你的代碼看起來沒問題,因此問題一定在缺失部分。 –