在WPF中,x:Name和Name属性之间有什么区别?

Dre*_*kes 554 .net wpf xaml name-attribute

标题说明了一切.有时似乎Namex:Name属性是可以互换的.

那么,它们之间的确切差异是什么,何时优先使用一个而不是另一个?

以错误的方式使用它们是否有任何性能或内存影响?

chu*_*ckj 465

在XAML中确实只有一个名字x:Name.诸如WPF之类的框架可以选择将其属性之一映射到XAML x:Name,方法是使用RuntimeNamePropertyAttribute指定其中一个类属性的类作为映射到XAML的x:Name属性.

这样做的原因是允许在运行时已经具有"Name"概念的框架,例如WPF.例如,在WPF中,FrameworkElement引入了Name属性.

通常,类不需要存储名称x:Name以供使用.x:NameXAML的所有方法都是生成一个字段,用于将值存储在类后面的代码中.运行时对该映射的作用取决于框架.

那么,为什么有两种方法可以做同样的事情呢?简单的答案是因为有两个概念映射到一个属性.WPF需要在运行时保留的元素的名称(可以通过Bind使用),而XAML需要知道您希望类代码后面的字段可以访问哪些元素.WPF通过将Name属性标记为x:Name的别名来将这两者联系在一起.

将来,XAML将有更多用于x:Name的功能,例如允许您通过按名称引用其他对象来设置属性,但在3.5和之前,它仅用于创建字段.

你是否应该使用其中一个是真正的风格问题,而不是技术问题.我会把这个留给其他人推荐.

另请参见AutomationProperties.Name VS x:名称,AutomationProperties.Name由辅助功能工具和一些测试工具使用.

  • 我不认为这两者在一般情况下是可以互换的.命名用户控件需要`x:Name`,因为`Name`不会创建在代码隐​​藏中识别的字段.不过,我仍然不知道为什么会这样. (9认同)
  • 他们不是,也不是暗示他们这样做.在WPF中,如果一个元素具有"Name"属性,那么它们意味着相同的东西.如果元素没有`Name`属性,则必须使用`x:Name`. (4认同)
  • 在Visual Studio 2010中,通过设计器编辑XAML时,将设置Name属性(而不是x:Name).似乎MS鼓励使用Name over x:Name,所以我猜这是事实上的标准. (2认同)
  • @Libor 今天,对于派生自 `FrameworkElement` 的任何类型(包括您在 XAML **包括 UserControl** 中使用的大多数类型)使用 `Name` 或 `x:Name` 绝对没有区别,成员将在任何情况下都能正确生成)。这是因为 `FrameworkElement` 是用 `[RuntimeNameProperty("Name")]` 修饰的。 (2认同)

Ken*_* K. 86

它们不是同一件事.

x:Name是一个xaml概念,主要用于引用元素.当您为元素提供x:Name xaml属性时,"指定的内容x:Name将成为处理xaml时在底层代码中创建的字段的名称,并且该字段包含对该对象的引用." (MSDN)因此,它是设计器生成的字段,默认情况下具有内部访问权限.

Name是a的现有字符串属性FrameworkElement,以xaml属性的形式列为任何其他wpf元素属性.

因此,这也意味着x:Name可以用于更广泛的物体.这是一种允许xaml中的任何内容被给定名称引用的技术.

  • 那么为什么Name或x:Name可以与Binding.ElementName一起使用?似乎x:Name属性不仅用于在生成的代码中命名字段,而且在运行时也可用于元数据. (4认同)
  • 它是一个生成的字段,类似于 WinForms 编辑器的“设计”属性中的“名称”字段。您可以在属性列表中放置一个名称,它就成为字段的名称。这是相同的行为。当然,它在运行时可用,因为它是编译到后面代码中的内部字段。Binding.ElementName 检查任一情况,即 xaml 编辑器“神奇”,x:Name 本身并不神奇。 (2认同)

cgr*_*eno 37

x:Name和Name引用不同的名称空间.

x:name是对Xaml文件顶部默认定义的x命名空间的引用.

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Run Code Online (Sandbox Code Playgroud)

只是说Name使用下面的默认命名空间.

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Run Code Online (Sandbox Code Playgroud)

x:名称是说使用具有x别名的命名空间.x是默认值,大多数人都会离开它,但您可以将其更改为您喜欢的任何内容

xmlns:foo="http://schemas.microsoft.com/winfx/2006/xaml"
Run Code Online (Sandbox Code Playgroud)

所以你的参考将是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
Run Code Online (Sandbox Code Playgroud)

因此,可以预期从FrameworkElement继承的任何内容都可以访问其所有公共属性.所以在Button的情况下,它从FrameworkElement获取其Name属性,位于层次结构树的最顶层. 所以你可以说x:NameName,他们都将从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")]  
Run Code Online (Sandbox Code Playgroud)


Ste*_*ins 20

它们都是同一个东西,很多框架元素本身都公开了一个名称属性,但是对于那些不能使用x:name的东西 - 我通常只是坚持使用x:name,因为它适用于所有东西.

控件可以将名称本身公开为依赖属性,如果他们愿意(因为他们需要在内部使用该依赖属性),或者他们可以选择不这样做.

msdn的更多细节在这里这里:

某些WPF框架级应用程序可能能够避免使用x:Name属性,因为在WPF名称空间中为几个重要基类(如FrameworkElement/FrameworkContentElement)指定的Name依赖项属性满足了此相同的目的.仍然存在一些常见的XAML和框架场景,其中代码访问没有Name属性的元素是必需的,最明显的是在某些动画和故事板支持类中.例如,如果要从代码中引用它们,则应在时间轴上指定x:名称和在XAML中创建的转换.

如果Name可用作类的属性,则Name和x:Name可以互换使用作为属性,但如果在同一元素上指定了两者,则会产生错误.

  • @Steve你的原始答案没有解决我的问题,因此我的评论.我不是在寻找盲目信仰"这样做",而是一个有见地的答案,解释了为什么存在两种方式,即使其中一种方法始终有效.技术上正确!=合适.您的更新要好得多. (4认同)
  • 如果没有区别,那么为什么有两种方法可以做同样的事情呢?两种方式都存在于WPF的第一个版本中. (3认同)

小智 10

X:如果您有自定义控件,名称可能会导致内存问题.它将保留NameScope条目的内存位置.

我说永远不要使用x:名字,除非你必须这样做.

  • 据我了解,这会影响 _both_ **Name** 和 **x:Name**,因为两者都添加到 NameScope 中。如果您的元素需要名称,则无法绕过它。您可以通过 [`FrameworkElement.RegisterName("elementname")`](https://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.registername(v = vs.110).aspx)。但是,如果您调用 [`FrameworkElement.UnregisterName("elementname")`](https://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.unregistername(v=vs.110).aspx ) 它可以被“取消引用”。 (2认同)

小智 7

唯一的区别是,如果您将用户控件用于来自Same Assembly的控件,那么Name将不会识别您的控件,并且您将收到错误"使用x:同一程序集中控件的名称".所以x:Name是WPF中命名控件的WPF版本.名称仅用作Winform Legacy.他们希望区分WPF和winforms中控件的命名,因为他们使用Xaml中的属性来识别来自其​​他组件的控件x:for controls of control.

请记住,不要为控件添加一个名称,因为它保留在内存中作为空白,它会给出一个警告,即Name已经应用于控件但它从未使用过.


Ale*_*yov 7

名称:

  1. 只能用于FrameworkElement和FrameworkContentElement的后代;
  2. 可以通过SetValue()和类似属性从代码隐藏设置.

x:姓名:

  1. 可用于几乎所有XAML元素;
  2. 不能通过SetValue()从代码隐藏设置; 它只能使用对象的属性语法设置,因为它是一个指令.

在XAML中为一个FrameworkElement或FrameworkContentElement使用这两个指令将导致异常:如果XAML是标记编译的,则在标记编译时将发生异常,否则它将在加载时发生.


BIB*_*NJU 5

x:Name 意思是:在后面的代码中创建一个字段来保存对该对象的引用.

Name 表示:设置此对象的name属性.