634

Name有时,和属性似乎x:Name可以互换。

那么,它们之间的明确区别是什么,什么时候最好使用一种而不是另一种呢?

以错误的方式使用它们是否会对性能或内存产生影响?

4

15 回答 15

510

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

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

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

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

未来,XAML 将有更多使用 x:Name 的用途,例如允许您通过按名称引用其他对象来设置属性,但在 3.5 及之前的版本中,它仅用于创建字段。

是否应该使用其中一个实际上是一个风格问题,而不是技术问题。我会把它留给其他人推荐。

另见AutomationProperties.Name VS x:Name,AutomationProperties.Name 由辅助工具和一些测试工具使用。

于 2009-02-27T00:52:49.170 回答
102

它们不是同一件事。

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

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

因此,这也意味着x:Name可以在更广泛的对象上使用。这是一种使 xaml 中的任何内容都可以通过给定名称引用的技术。

于 2009-07-14T23:34:04.000 回答
46

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:Name是说使用具有x别名的命名空间。x 是默认值,大多数人都会保留它,但您可以将其更改为您喜欢的任何内容

xmlns:foo="http://schemas.microsoft.com/winfx/2006/xaml"

所以你的参考是foo:name

在 WPF 中定义和使用命名空间


好的,让我们换一种方式来看。假设您将一个按钮拖放到您的 Xaml 页面上。您可以参考这两种方式x:namename。所有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: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")]  
于 2009-02-26T10:36:02.990 回答
28

它们都是一样的,很多框架元素自己都暴露了一个 name 属性,但对于那些不这样做的人,你可以使用 x:name - 我通常只坚持使用 x:name 因为它适用于所有东西。

控件可以根据需要将名称自身公开为依赖属性(因为它们需要在内部使用该依赖属性),也可以选择不这样做。

此处此处的 msdn 中的更多详细信息:

一些 WPF 框架级应用程序可能能够避免使用任何 x:Name 属性,因为在 WPF 命名空间中为几个重要的基类(例如 FrameworkElement/FrameworkContentElement)指定的 Name 依赖项属性满足了同样的目的。仍然有一些常见的 XAML 和框架方案需要对没有 Name 属性的元素进行代码访问,尤其是在某些动画和情节提要支持类中。例如,如果您打算从代码中引用它们,则应在 XAML 中创建的时间线和转换上指定 x:Name。

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

于 2009-02-26T10:03:51.210 回答
13

如果您有自定义控件,X:Name 可能会导致内存问题。它将为 NameScope 条目保留一个内存位置。

我说除非必须,否则永远不要使用 x:Name。

于 2011-01-13T18:57:33.587 回答
11

姓名

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

x:姓名

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

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

于 2013-08-27T17:12:05.670 回答
8

唯一的区别是,如果您将用户控件用于同一程序集中的控件,则名称将无法识别您的控件,并且您将收到错误“使用 x:Name 用于同一程序集中的控件”。所以 x:Name 是 WPF 中命名控件的 WPF 版本。名称仅用作 Winform Legacy。他们想要区分 WPF 和 winforms 中控件的命名,因为他们使用 Xaml 中的属性来识别来自其​​他程序集的控件,他们使用 x: 表示控件名称。

请记住,不要仅仅为了保留它而为控件命名,因为它作为空白驻留在内存中,它会警告您名称已应用于控件但从未使用过。

于 2013-01-17T18:03:57.747 回答
7

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

Name意思是:设置这个对象的名称属性。

于 2015-01-20T13:04:52.340 回答
4

我总是使用 x:Name 变体。我不知道这是否会影响任何性能,我只是发现它更容易,原因如下。如果您有自己的用户控件驻留在另一个程序集中,那么“名称”属性并不总是足够的。这使得粘贴 x:Name 属性变得更容易。

于 2009-02-26T09:56:56.313 回答
3

它不是 WPF 项,而是标准 XML 项,BtBh已正确回答,x 指的是默认命名空间。在 XML 中,当您不使用命名空间作为元素/属性的前缀时,它假定您需要默认命名空间。所以打字Name只是x:Name. 有关 XML 命名空间的更多详细信息,请参见链接文本

于 2009-02-26T11:35:07.090 回答
2

指定的x:Name成为在处理 XAML 时在基础代码中创建的字段的名称,并且该字段包含对对象的引用。在 Silverlight 中,使用托管 API 创建此字段的过程由 MSBuild 目标步骤执行,这些步骤还负责连接 XAML 文件的部分类及其代码隐藏。此行为不一定是指定的 XAML 语言;这是 Silverlight在其编程和应用程序模型中使用x:Name的特定实现。

在 MSDN 上阅读更多...

于 2015-04-29T15:47:29.303 回答
2

当您在 XAML 中声明 Button 元素时,您指的是在 Windows 运行时中定义的称为 Button 的类。

Button 有许多属性,例如背景、文本、边距、......以及一个名为 Name 的属性。

现在,当您在 XAML 中声明一个 Button 时,就像创建一个碰巧有一个名为 Name 的属性的匿名对象。

通常,您不能引用匿名对象,但在 WPF 框架中,XAML 处理器允许您通过为 Name 属性提供的任何值来引用该对象。

到现在为止还挺好。

创建对象的另一种方法是创建命名对象而不是匿名对象。在这种情况下,XAML 命名空间有一个名为 Name 的对象的属性(并且因为它在 XAML 命名空间中,因此有 X:),您可以设置该属性,以便您可以识别您的对象并引用它。

结论:

Name 是特定对象的属性,但 X:Name 是该对象的一个​​属性(有一个定义通用对象的类)。

于 2015-08-24T01:36:31.103 回答
1

答案之一是 x:name 将在不同的程序语言(例如 c#)中使用,而 name 将用于框架。老实说,这就是我听起来的样子。

于 2013-11-15T05:49:48.593 回答
1

Name也可以使用带有内部文本的属性元素语法来设置,但这并不常见。相反,x:Name不能在XAML属性元素语法中设置,也不能在使用SetValue;的代码中设置。它只能使用对象的属性语法来设置,因为它是一个指令
IfName可作为类的属性使用,Name并且x:Name可以作为属性互换使用,但如果在同一元素上同时指定两者,则会导致解析异常。如果 XAML 是标记编译的,则异常将在标记编译时发生,否则在加载时发生。

于 2020-06-25T11:37:18.090 回答
0

我的研究是x:Name全局变量。但是,Name作为局部变量。这是否意味着 x:Name 您可以在 XAML 文件中的任何位置调用它,但 Name 不是。
例子:

<StackPanel>
<TextBlock Text="{Binding Path=Content, ElementName=btn}" />
<Button Content="Example" Name="btn" />
</StackPanel>
<TextBlock Text="{Binding Path=Content, ElementName=btn}" />

您不能使用 Name 的Binding属性ContentButton“btn”,因为它在外部StackPanel

于 2018-06-15T11:40:35.270 回答