问答中心分类: WPF在 WPF 中,x:Name 和 Name 属性有什么区别?
0
匿名用户 提问 1小时 前

有时似乎Namex:Name属性可以互换。
那么,它们之间的明确区别是什么,什么时候最好使用一种而不是另一种呢?
以错误的方式使用它们是否会对性能或内存产生影响?

Ortund 回复 1小时 前

回应建议使用x:Name一直都很好。我只需要将其更改为Name否则我无法在我的 .xaml.cs 代码中引用该控件,因此我将假设它不再是一直正常工作的情况。

14 Answers
0
Kenan E. K. 回答 1小时 前

它们不是同一件事。
x:Name是一个 xaml 概念,主要用于引用元素。当您为元素提供 x:Name xaml 属性时,“指定的x:Name成为在处理 xaml 时在基础代码中创建的字段的名称,并且该字段包含对该对象的引用。" (MSDN) 因此,它是设计器生成的字段,默认情况下具有内部访问权限。
Name是 a 的现有字符串属性FrameworkElement,以 xaml 属性的形式列为任何其他 wpf 元素属性。
因此,这也意味着x:Name可用于更广泛的对象。这是一种使 xaml 中的任何内容都可以通过给定名称引用的技术。

Drew Noakes 回复 1小时 前

那么为什么 Name 或 x:Name 可以与 Binding.ElementName 一起使用呢?似乎 x:Name 属性不仅用于在生成的代码中命名字段,而且在运行时在元数据中也可用。

Kenan E. K. 回复 1小时 前

它是一个生成的字段,类似于 WinForms 编辑器的设计属性中的字段名称。在那里,您在属性列表中放置一个名称,它成为一个字段的名称。这是相同的行为。当然,它在运行时可用,因为它是编译到后面代码中的内部字段。 Binding.ElementName 检查任何一种情况,即 xaml 编辑器“神奇”,x:Name 本身并不神奇。

bitbonk 回复 1小时 前

无论您使用 x:Name 还是 Name,都会生成一个字段。对于从 FrameworkElement 派生的所有类型(您在 XAML 中使用的大多数类型都是),x:Name 和 Name 之间没有区别,只有一个例外:如果您想给出一个UserControl一个名字并且 UserControl 在您也想使用它的同一个程序集中声明你必须使用x:Name因为 XAML 解析器的限制。

0
cgreeno 回答 1小时 前

x:Name 和 Name 引用不同的命名空间。
x:名称是对 Xaml 文件顶部默认定义的 x 命名空间的引用。

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

只是说姓名使用下面的默认命名空间。

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

x:名称是说使用具有X别名。 x 是默认值,大多数人都会保留它,但您可以将其更改为您喜欢的任何内容

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

所以你的参考是富:名称
在 WPF 中定义和使用命名空间

好的,让我们换一种方式来看。假设您将一个按钮拖放到您的 Xaml 页面上。您可以参考这两种方式x:名称姓名.全部xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"are 是对多个命名空间的引用。自从xml持有控制命名空间(不是 100%)和介绍持有框架元素按钮类具有以下继承模式:

Button : ButtonBase
ButtonBase : ContentControl, ICommandSource
ContentControl : Control, IAddChild
Control : FrameworkElement
FrameworkElement : UIElement, IFrameworkInputElement, 
                    IInputElement, ISupportInitialize, IHaveResources

因此,正如人们所期望的那样,从 FrameworkElement 继承的任何东西都可以访问其所有公共属性。因此,对于 Button,它从 FrameworkElement 获取其 Name 属性,位于层次结构树的最顶端。所以你可以说x:名称或者姓名他们都将从 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")]
Drew Noakes 回复 1小时 前

我不认为这是真的http://schemas.microsoft.com/winfx/2006/xaml持有Control因为您可以直接在 XAML 中使用它而无需“x”命名空间:<Control />

0
Steven Robbins 回答 1小时 前

它们都是一样的,很多框架元素自己都暴露了一个 name 属性,但对于那些不这样做的人,你可以使用 x:name – 我通常只坚持使用 x:name 因为它适用于所有东西。
控件可以根据需要将名称自身公开为依赖属性(因为它们需要在内部使用该依赖属性),也可以选择不这样做。
更多细节在 msdn这里这里

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

Drew Noakes 回复 1小时 前

如果没有区别,那么为什么会有两种方法来做同样的事情呢?这两种方式都存在于 WPF 的第一个版本中。

Drew Noakes 回复 1小时 前

@Steve,我没有对这个问题的任何答案投反对票,尽管到目前为止它们都不是非常合适的。

Steven Robbins 回复 1小时 前

我看不出一个不仅可以为您提供答案,而且还可以为您提供指向 MSDN 以获取有关该主题的更多信息的链接的答案是不合适的吗? 🙂

Drew Noakes 回复 1小时 前

@Steve您的原始答案没有解决我的问题,因此我发表了评论。我不是在寻找盲目的“这样做”,而是一个有见地的答案,它解释了为什么存在两种方式,即使其中一种方式一直有效。技术上正确!=适当。你的更新好多了。

Vegar 回复 1小时 前

这里的答案大致相同:wpfwiki.com/WPF%20Q16.4.ashxx:Name 为控件提供了在代码隐藏中使用的名称。某些类将提供名称属性用于相同目的。对于这些类,x:name 和 name 没有区别。

0
scott 回答 1小时 前

如果您有自定义控件,X:Name 可能会导致内存问题。它将为 NameScope 条目保留一个内存位置。
我说除非必须,否则永远不要使用 x:Name。

MachinusX 回复 1小时 前

同意。在一个有大量内存泄漏的信息亭应用程序上工作,而之前的开发团队的解决方案只是强制重启。许多泄漏很容易识别。然而,在修复了通过 IntelliTrace 和 JustTrace 找到的那些之后,一些 refs 仍然避开了隐式和显式垃圾收集。我读:support.scichart.com/index.php?/News/NewsItem/View/21/…发现减少 x:Name 进一步提高了性能。

Adam Caviness 回复 1小时 前

据我了解,这会影响两个都 姓名x:名称因为两者都添加到 NameScope。如果您的元素需要名称,则无法绕过它。您可以通过以下方式在没有名称的元素上复制代码FrameworkElement.RegisterName("elementname").但是,如果你打电话FrameworkElement.UnregisterName("elementname")它可以“取消引用”。

0
Oleksandr Zolotarov 回答 1小时 前

姓名

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

x:名称

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

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