如何在UserControl中实现更新LostFocus源代码的DependencyProperty?

时间:2012-07-19 02:47:44

标签: wpf user-controls dependency-properties updatesourcetrigger

我正在实现一个名为PhoneBox的UserControl,它包含一个TextBox,一些自定义逻辑,并且有一个名为PhoneNo的DependencyProperty。它用于双向绑定方案,LostFocus用于UpdateSourceTrigger。所以我写了下面的代码 -

XAML(UserControl):

<StackPanel>
    <TextBox Name="txtPhone" MinWidth="120" MinHeight="23" LostFocus="txtPhone_LostFocus" GotFocus="txtPhone_GotFocus"/>
</StackPanel>  

Code-Behind(UserControl):

public partial class PhoneBox : UserControl
{
    //Some Code

    static PhoneBox()
    {
        FrameworkPropertyMetadata phoneNoMetadata =
            new FrameworkPropertyMetadata(new PropertyChangedCallback(OnPhoneNoChanged),
                                          new CoerceValueCallback(CoercePhoneNoValue));
        PhoneNoProperty = DependencyProperty.Register("PhoneNo", typeof (string), typeof (PhoneBox),
                                                       phoneNoMetadata,
                                                       new ValidateValueCallback(ValidatePhoneNoValue));
    }

    public readonly static DependencyProperty PhoneNoProperty;
    public string PhoneNo
    {
        get { return (string)GetValue(PhoneNoProperty); }
        set { SetValue(PhoneNoProperty, value); }
    }

    private static void OnPhoneNoChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        PhoneBox phoneBox = (PhoneBox)d;
        string newValue = (string)e.NewValue;

        phoneBox.txtPhone.Text = newValue;
    }

    private static object CoercePhoneNoValue(DependencyObject d, object basevalue)
    {
        return basevalue;
    }

    private static bool ValidatePhoneNoValue(object value)
    {
        return true;
    }

    private void txtPhone_LostFocus(object sender, RoutedEventArgs e)
    {
        this.SetValue(PhoneNoProperty, this.txtPhone.Text);
    }

    private void txtPhone_GotFocus(object sender, RoutedEventArgs e)
    {
        if (!String.IsNullOrEmpty(txtPhone.Text))
            this.txtPhone.Text = this.FilterText(txtPhone.Text);
    }

    private string FilterText(string text)
    {
        //Some cutom logic
    }

    //Some more Code
}  

XAML(消费者):

<pbc:PhoneBox PhoneNo="{Binding Path=User.Phone, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>  

有效。但我的问题是,我使用txtPhone_LostFocus事件处理程序设置proerty值(以及反过来更新源)的方式是否合适?有没有更合适的方法来做到这一点?我是这个DependencyProperty的新手,所以任何指导,建议,评论都将不胜感激。

2 个答案:

答案 0 :(得分:1)

处理这种情况的WPF方法是在UserControl的DependencyProperty和UserControl的XAML文件中声明的TextBox之间建立绑定。这也是您设置LostFocus UpdateSourceTrigger的地方(您不必这样做,因为它是默认行为)。您将在TextBox(即UserControl内)声明绑定,因此使用UserControl的客户端代码可以自由地在PhoneNo属性上设置另一个绑定(从UserControl外部)。另外,如果你的CoerceValue回调只返回基值,那么最好从一开始就不用它。

这可能是大卫最初的意思......

答案 1 :(得分:0)

在这种情况下,我确实宁愿在DP元数据中使用UpdateSourceTrigger枚举而不是LostFocus EventHandler,并且摆脱所有冗余方法:让WPF做这些事情总是更好如果可以的话,对你来说:它会更好更快地完成它们。

另外在这种情况下,我个人觉得在元数据中读取比在lostFocus方法中容易得多。但我觉得这是一个品味问题。

编辑不,不,我理解你的意思,但我可能不会在答案中明白自己。这大致是我要做的(只是为了给你一个提示,需要在你的情况下进行一些调整):

public partial class PhoneBox : UserControl
{
    public static readonly DependencyProperty PhoneNoProperty = DependencyProperty.Register(
        "PhoneNo",
        typeof (string),
        typeof (PhoneBox),
        new UIPropertyMetadata(UpdateSourceTrigger.LostFocus),
        new ValidateValueCallback(ValidatePhoneNoValue));

    public string PhoneNo
    {
        get { return (string)GetValue(PhoneNoProperty); }
        set { SetValue(PhoneNoProperty, value); }
    }

// ... your code here.

}