2011-07-26 49 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的代码。如果你不提供完整的信息,我们如何能说出“似乎没有工作”?你的代码看起来没问题,因此问题一定在缺失部分。 –