我正在实现一个名为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.
}