You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 18:22:44