0

我正在实现一个UserControl名为 PhoneBox,它包含一个单一的TextBox、一些自定义逻辑,并且有一个名为 PhoneNo 的 DependencyProperty。LostFocus它将在带有for的双向绑定场景中使用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事件处理程序设置属性值(进而更新源)的方式是否合适?有没有更合适的方法来做到这一点?我是这个DependencyProperty东西的新手,所以任何指导,建议,评论将不胜感激。

4

2 回答 2

1

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

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

于 2012-08-25T07:25:06.713 回答
0

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

}
于 2012-07-19T07:52:44.173 回答