我正在实现一个名为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
的新手,所以任何指导,建议,评论都将不胜感激。
答案 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.
}