标题说明了一切.有时似乎Name
和x:Name
属性是可以互换的.
那么,它们之间的确切差异是什么,何时优先使用一个而不是另一个?
以错误的方式使用它们是否有任何性能或内存影响?
在XAML中确实只有一个名字x:Name
.诸如WPF之类的框架可以选择将其属性之一映射到XAML x:Name
,方法是使用RuntimeNamePropertyAttribute
指定其中一个类属性的类作为映射到XAML的x:Name属性.
这样做的原因是允许在运行时已经具有"Name"概念的框架,例如WPF.例如,在WPF中,FrameworkElement
引入了Name属性.
通常,类不需要存储名称x:Name
以供使用.x:Name
XAML的所有方法都是生成一个字段,用于将值存储在类后面的代码中.运行时对该映射的作用取决于框架.
那么,为什么有两种方法可以做同样的事情呢?简单的答案是因为有两个概念映射到一个属性.WPF需要在运行时保留的元素的名称(可以通过Bind使用),而XAML需要知道您希望类代码后面的字段可以访问哪些元素.WPF通过将Name属性标记为x:Name的别名来将这两者联系在一起.
将来,XAML将有更多用于x:Name的功能,例如允许您通过按名称引用其他对象来设置属性,但在3.5和之前,它仅用于创建字段.
你是否应该使用其中一个是真正的风格问题,而不是技术问题.我会把这个留给其他人推荐.
另请参见AutomationProperties.Name VS x:名称,AutomationProperties.Name由辅助功能工具和一些测试工具使用.
它们不是同一件事.
x:Name
是一个xaml概念,主要用于引用元素.当您为元素提供x:Name xaml属性时,"指定的内容x:Name
将成为处理xaml时在底层代码中创建的字段的名称,并且该字段包含对该对象的引用." (MSDN)因此,它是设计器生成的字段,默认情况下具有内部访问权限.
Name
是a的现有字符串属性FrameworkElement
,以xaml属性的形式列为任何其他wpf元素属性.
因此,这也意味着x:Name
可以用于更广泛的物体.这是一种允许xaml中的任何内容被给定名称引用的技术.
x:Name和Name引用不同的名称空间.
x:name是对Xaml文件顶部默认定义的x命名空间的引用.
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
只是说Name使用下面的默认命名空间.
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
x:名称是说使用具有x别名的命名空间.x是默认值,大多数人都会离开它,但您可以将其更改为您喜欢的任何内容
xmlns:foo="http://schemas.microsoft.com/winfx/2006/xaml"
所以你的参考将是foo:name
在WPF中定义和使用命名空间
好的,让我们以不同的方式看待这个.假设您将按钮拖放到Xaml页面上.您可以参考这两种方式x:名称和名称.所有xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 和 xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"都是对多个名称空间的引用.由于xaml持有Control名称空间(不是100%),并且表示包含FrameworkElement,因此Button类具有以下的继承模式:
Button : ButtonBase ButtonBase : ContentControl, ICommandSource ContentControl : Control, IAddChild Control : FrameworkElement FrameworkElement : UIElement, IFrameworkInputElement, IInputElement, ISupportInitialize, IHaveResources
因此,可以预期从FrameworkElement继承的任何内容都可以访问其所有公共属性.所以在Button的情况下,它从FrameworkElement获取其Name属性,位于层次结构树的最顶层. 所以你可以说x:Name或Name,他们都将从FrameworkElement访问getter/setter.
MSDN参考
WPF定义了XAML处理器使用的CLR属性,以便将多个CLR命名空间映射到单个XML命名空间.所述XmlnsDefinitionAttribute属性被放置在产生该组件的源代码的程序集的水平.WPF程序集源代码使用此属性将各种常见名称空间(如System.Windows和System.Windows.Controls)映射到http://schemas.microsoft.com/winfx/2006/xaml/presentation名称空间.
所以程序集属性看起来像:
PresentationFramework.dll - XmlnsDefinitionAttribute:
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "System.Windows")] [assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "System.Windows.Data")] [assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "System.Windows.Navigation")] [assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "System.Windows.Shapes")] [assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "System.Windows.Documents")] [assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "System.Windows.Controls")]
它们都是同一个东西,很多框架元素本身都公开了一个名称属性,但是对于那些不能使用x:name的东西 - 我通常只是坚持使用x:name,因为它适用于所有东西.
控件可以将名称本身公开为依赖属性,如果他们愿意(因为他们需要在内部使用该依赖属性),或者他们可以选择不这样做.
msdn的更多细节在这里和这里:
某些WPF框架级应用程序可能能够避免使用x:Name属性,因为在WPF名称空间中为几个重要基类(如FrameworkElement/FrameworkContentElement)指定的Name依赖项属性满足了此相同的目的.仍然存在一些常见的XAML和框架场景,其中代码访问没有Name属性的元素是必需的,最明显的是在某些动画和故事板支持类中.例如,如果要从代码中引用它们,则应在时间轴上指定x:名称和在XAML中创建的转换.
如果Name可用作类的属性,则Name和x:Name可以互换使用作为属性,但如果在同一元素上指定了两者,则会产生错误.
X:如果您有自定义控件,名称可能会导致内存问题.它将保留NameScope条目的内存位置.
我说永远不要使用x:名字,除非你必须这样做.
唯一的区别是,如果您将用户控件用于来自Same Assembly的控件,那么Name将不会识别您的控件,并且您将收到错误"使用x:同一程序集中控件的名称".所以x:Name是WPF中命名控件的WPF版本.名称仅用作Winform Legacy.他们希望区分WPF和winforms中控件的命名,因为他们使用Xaml中的属性来识别来自其他组件的控件x:for controls of control.
请记住,不要为控件添加一个名称,因为它保留在内存中作为空白,它会给出一个警告,即Name已经应用于控件但它从未使用过.
名称:
只能用于FrameworkElement和FrameworkContentElement的后代;
可以通过SetValue()和类似属性从代码隐藏设置.
x:姓名:
可用于几乎所有XAML元素;
不能通过SetValue()从代码隐藏设置; 它只能使用对象的属性语法设置,因为它是一个指令.
在XAML中为一个FrameworkElement或FrameworkContentElement使用这两个指令将导致异常:如果XAML是标记编译的,则在标记编译时将发生异常,否则它将在加载时发生.
x:Name
意思是:在后面的代码中创建一个字段来保存对该对象的引用.
Name
表示:设置此对象的name属性.