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

x:Name与Name在WPF BindingGroup中的行为差异及文档查询

以下是测试用的完整代码:

XAML代码

<Window x:Class="ValidatingMultipleValues.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ValidatingMultipleValues"
        xmlns:src="clr-namespace:ValidatingMultipleValues"
        mc:Ignorable="d"
        Title="Validating Multiple Values" Height="220.233" Width="597.261" SizeToContent="WidthAndHeight">
    <StackPanel>
        <StackPanel.Resources>
            <src:Type1 x:Key="object1" />
            <src:Type2 x:Key="object2" />
        </StackPanel.Resources>

        <StackPanel Name="sp1"
              Margin="5"
              DataContext="{Binding Source={StaticResource object1}}"
              Validation.ValidationAdornerSite="{Binding ElementName=label1}"
              Orientation="Horizontal"
              HorizontalAlignment="Center">

            <StackPanel.BindingGroup>
                <BindingGroup Name="bindingGroup">
                    <BindingGroup.ValidationRules>
                        <src:BindingGroupValidationRule ValidatesOnTargetUpdated="True" />
                    </BindingGroup.ValidationRules>
                </BindingGroup>
            </StackPanel.BindingGroup>

            <TextBlock Text="First string" />

            <TextBox Width="150"
             Text="{Binding Path=PropertyA}" />

            <TextBlock Text="Second string" />

            <TextBox Width="150"
             Text="{Binding Source={StaticResource object2}, 
      Path=PropertyB, BindingGroupName=bindingGroup, 
      TargetNullValue=please enter a string}" />

        </StackPanel>

        <Label Name="label1"
         Content="{Binding ElementName=sp1, Path=(Validation.Errors)[0].ErrorContent}"
         Margin="5"
         Foreground="Red"
         HorizontalAlignment="Center" />

        <Button HorizontalAlignment="Center"
          Click="Button_Click"
          IsDefault="True">
            _Submit
        </Button>

        <StackPanel Orientation="Horizontal">
            <TextBlock Text="First string:"
               FontWeight="Bold" />
            <TextBlock Text="{Binding Source={StaticResource object1}, 
      Path=PropertyA, TargetNullValue=--}" />
        </StackPanel>

        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Second string:"
               FontWeight="Bold" />
            <TextBlock Text="{Binding Source={StaticResource object2}, 
      Path=PropertyB, TargetNullValue=--}" />
        </StackPanel>
    </StackPanel>
</Window>

C#代码

using System.Diagnostics;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace ValidatingMultipleValues
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }


        private void Button_Click(object sender, RoutedEventArgs e)
        {
            sp1.BindingGroup.UpdateSources();
        }
    }


    public class Type1
    {
        public string PropertyA { get; set; }

        public Type1()
        {
            PropertyA = "Default Value";
        }
    }

    public class Type2
    {
        public string PropertyB { get; set; }

        public Type2()
        {
        }
    }

    public class BindingGroupValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            BindingGroup bg = value as BindingGroup;

            Type1 object1 = null;
            Type2 object2 = null;

            foreach (object item in bg.Items)
            {
                if (item is Type1)
                {
                    object1 = item as Type1;
                }

                if (item is Type2)
                {
                    object2 = item as Type2;
                }
            }

            if (object1 == null || object2 == null)
            {
                return new ValidationResult(false, "BindingGroup did not find source object.");
            }

            string string1 = bg.GetValue(object1, "PropertyA") as string;
            string string2 = bg.GetValue(object2, "PropertyB") as string;

            if (string1 != string2)
            {
                return new ValidationResult(false, "The two strings must be identical.");
            }

            return ValidationResult.ValidResult;
        }
    }
}

BindingGroup 中 Name 与 x:Name 行为差异的官方说明及原因

核心差异本质

BindingGroup.Name与XAML的x:Name是完全独立的两个概念,作用毫无重叠:

  • BindingGroup.Name是业务标识属性,用于将指定BindingGroupName的绑定与该BindingGroup关联,进而把绑定的源对象纳入BindingGroup.Items集合。
  • x:Name是XAML语言标识,仅用于在代码后台生成对象引用字段,方便直接访问XAML对象,不参与任何BindingGroup的业务逻辑。

官方文档依据

WPF官方文档明确区分了两者的定位:

  • BindingGroup.Name:专门用于设置BindingGroup的业务名称,绑定通过声明BindingGroupName属性匹配对应的BindingGroup,从而将自身的源对象加入到该BindingGroup的Items集合中。
  • x:Name:属于XAML命名空间的基础特性,仅负责为XAML对象生成运行时可引用的后台字段,完全不涉及BindingGroup的绑定关联逻辑。

结合示例分析

在你的测试场景中:

  1. 使用Name="bindingGroup"时,BindingGroup的业务名称被设置为bindingGroup,第二个TextBox的绑定声明BindingGroupName=bindingGroup,因此该绑定的源对象object2会被关联到这个BindingGroup,加上StackPanel的DataContextobject1,Items集合最终包含两个对象。
  2. 替换为x:Name="bindingGroup"后,BindingGroup的Name属性实际为空,第二个TextBox的绑定无法找到匹配的BindingGroup,因此只有StackPanel默认关联的object1被纳入Items集合,导致仅存在一个对象。

补充说明

并非所有控件的Name属性都和x:Name等价:只有当控件的Name属性被设计为映射到XAML命名范围时(比如多数UI控件),两者才会表现出类似的效果,但BindingGroup的Name是独立的业务属性,完全不参与XAML命名逻辑,因此会出现这种行为差异。


内容的提问来源于stack exchange,提问作者EldHasp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 14:54:52