WP7自定义控件绑定内部控件

时间:2011-07-26 03:56:31

标签: silverlight windows-phone-7

我正在创建一个自定义控件,其中包含PasswordBox。如何将DependencyProperty我的自定义控件与Password的{​​{1}}属性相关联?

从我看到的所有示例中,使用PasswordBox将模板中的密码挂钩应该可以解决问题,但这似乎不起作用。我错过了什么?

generic.xaml

TemplateBinding

PasswordBoxTest.cs

<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>

3 个答案:

答案 0 :(得分:0)

您必须使用RelativeSource bindings才能使用它。或者您必须将UserControl的DataContext设置为this

答案 1 :(得分:0)

TemplateBinding没问题。你需要以某种方式设置绑定源(例如通过提到的DataContext或简单地使用Text属性在Xaml中),但是由于你省略了这段代码,我无法判断问题出在哪里。

我不知道这个类的目的是什么,但可能在标准PasswordBox中添加了一些功能。我会尽可能保持两种实现方式相似。我的意思是Text属性应该被称为密码等。

更多评论:提供的模板不需要网格。除非你有额外的理由使用它,否则删除它 - 它只会增加布局的复杂性。请注意,PasswordBox的默认模板已包含在相同的Grid ...

答案 2 :(得分: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;
            }
        }    
    }
}