ItemsControl中所有TextBox为何共用最后添加的ValidationRule?
问题分析与解决方案
问题根源
你遇到的核心问题是:MinMaxChangeCallback中通过binding.ParentBinding获取的是DataTemplate里定义的共享Binding实例——ItemsControl生成的所有TextBox2都会复用这个Binding对象。当你修改它的ValidationRules时,所有TextBox的验证规则都会被最后一次设置的规则覆盖,导致第一个TextBox错误使用了第二个的验证规则。
解决方案
不要修改共享的ParentBinding,而是为每个TextBox2创建独立的Binding副本,替换原有的Text绑定后,再给这个独立Binding添加专属的验证规则。
修改后的代码
TextBox2类修改
public class TextBox2 : TextBox { public static readonly DependencyProperty MinProperty = DependencyProperty.Register( nameof(Min), typeof(double?), typeof(TextBox2), new PropertyMetadata(null, MinMaxChangeCallback)); public double? Min { get => (double?)GetValue(MinProperty); set => SetValue(MinProperty, value); } public static readonly DependencyProperty MaxProperty = DependencyProperty.Register( nameof(Max), typeof(double?), typeof(TextBox2), new PropertyMetadata(null, MinMaxChangeCallback)); public double? Max { get => (double?)GetValue(MaxProperty); set => SetValue(MaxProperty, value); } private static void MinMaxChangeCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { var textBox2 = (TextBox2)d; if (textBox2.Min == null || textBox2.Max == null) return; var originalBindingExpr = textBox2.GetBindingExpression(TextProperty); if (originalBindingExpr == null) return; // 创建原Binding的独立副本,确保每个TextBox拥有专属Binding实例 var newBinding = new Binding { Path = originalBindingExpr.ParentBinding.Path, Mode = originalBindingExpr.ParentBinding.Mode, UpdateSourceTrigger = originalBindingExpr.ParentBinding.UpdateSourceTrigger, ValidatesOnDataErrors = originalBindingExpr.ParentBinding.ValidatesOnDataErrors, ValidatesOnExceptions = originalBindingExpr.ParentBinding.ValidatesOnExceptions // 若原Binding有Converter、StringFormat等属性,需在此一并复制 }; // 添加当前TextBox专属的验证规则 var minMaxValidationRule = new MinMaxValidationRule((double)textBox2.Min, (double)textBox2.Max) { ValidatesOnTargetUpdated = true }; newBinding.ValidationRules.Add(minMaxValidationRule); // 替换原绑定,使当前TextBox使用独立的Binding textBox2.SetBinding(TextProperty, newBinding); } }
补充说明
如果原Text绑定还包含Converter、StringFormat等自定义属性,需要在创建Binding副本时同步复制这些属性,保证原有功能不受影响。修改后每个TextBox2的Text绑定都是独立实例,各自的验证规则互不干扰,会严格使用自身的Min/Max参数进行校验。
内容的提问来源于stack exchange,提问作者Muhammad Sulaiman
相关产品推荐
相关产品推荐

