WPF TextBox绑定用户控件依赖属性时Setter未触发问题求助
问题原因
WPF依赖属性系统在通过绑定赋值时,会直接调用底层的SetValue方法,不会走你定义的CLR属性包装器的set逻辑,所以你写在set里的正则校验代码根本没有被触发。而普通CLR属性+INotifyPropertyChanged的模式下,绑定更新一定会走属性的setter,所以逻辑能正常运行。
解决方案
依赖属性的自定义校验、值变更处理逻辑,需要放在注册依赖属性时指定的PropertyChangedCallback回调中执行,调整后的代码如下:
// 按WPF规范命名依赖属性:属性名+Property后缀 public static readonly DependencyProperty TextProperty = DependencyProperty.Register( nameof(Text), typeof(string), typeof(FormatBox), // 指定属性变更回调,同时设置默认双向绑定,符合输入控件的使用习惯 new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnTextChanged)); // CLR包装器只保留标准的GetValue/SetValue,不要添加任何自定义逻辑 public string Text { get => (string)GetValue(TextProperty); set => SetValue(TextProperty, value); } // 属性变更回调,在这里实现校验逻辑 private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var currentControl = (FormatBox)d; var inputValue = e.NewValue as string ?? string.Empty; // 正则校验不通过则清空文本 if (!Regex.IsMatch(inputValue, currentControl.RegexString ?? string.Empty)) { currentControl.Text = string.Empty; } }
原有XAML代码不需要做任何修改,即可实现失焦校验清空的需求。
补充说明
WPF官方开发规范明确要求:依赖属性的CLR包装器只能包含GetValue和SetValue调用,禁止在包装器中添加任何额外逻辑,所有自定义处理都要通过依赖属性注册时的回调方法实现。
内容的提问来源于stack exchange,提问作者Rattlesneak
相关产品推荐
相关产品推荐

