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的绑定关联逻辑。
结合示例分析
在你的测试场景中:
- 使用
Name="bindingGroup"时,BindingGroup的业务名称被设置为bindingGroup,第二个TextBox的绑定声明BindingGroupName=bindingGroup,因此该绑定的源对象object2会被关联到这个BindingGroup,加上StackPanel的DataContextobject1,Items集合最终包含两个对象。 - 替换为
x:Name="bindingGroup"后,BindingGroup的Name属性实际为空,第二个TextBox的绑定无法找到匹配的BindingGroup,因此只有StackPanel默认关联的object1被纳入Items集合,导致仅存在一个对象。
补充说明
并非所有控件的Name属性都和x:Name等价:只有当控件的Name属性被设计为映射到XAML命名范围时(比如多数UI控件),两者才会表现出类似的效果,但BindingGroup的Name是独立的业务属性,完全不参与XAML命名逻辑,因此会出现这种行为差异。
内容的提问来源于stack exchange,提问作者EldHasp
相关产品推荐
相关产品推荐

