如何在 UserControl 中实现 DependencyProperty,以更新 LostFocus 上的源代码



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

XAML (用户控件(:

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

代码隐藏(用户控件(:

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的新手,所以任何指导,建议,评论将不胜感激。

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

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

在这种情况下,我确实宁愿在 DP 元数据中使用 UpdateSourceTrigger 枚举而不是LostFocus事件处理程序,并摆脱所有冗余方法:如果可以的话,让 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.
}

相关内容

  • 没有找到相关文章

最新更新