Name
有时,和属性似乎x:Name
可以互换。
那么,它们之间的明确区别是什么,什么时候最好使用一种而不是另一种呢?
以错误的方式使用它们是否会对性能或内存产生影响?
Name
有时,和属性似乎x:Name
可以互换。
那么,它们之间的明确区别是什么,什么时候最好使用一种而不是另一种呢?
以错误的方式使用它们是否会对性能或内存产生影响?
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 由辅助工具和一些测试工具使用。
它们不是同一件事。
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:Name是说使用具有x别名的命名空间。x 是默认值,大多数人都会保留它,但您可以将其更改为您喜欢的任何内容
xmlns:foo="http://schemas.microsoft.com/winfx/2006/xaml"
所以你的参考是foo:name
好的,让我们换一种方式来看。假设您将一个按钮拖放到您的 Xaml 页面上。您可以参考这两种方式x:name和name。所有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。
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")]
它们都是一样的,很多框架元素自己都暴露了一个 name 属性,但对于那些不这样做的人,你可以使用 x:name - 我通常只坚持使用 x:name 因为它适用于所有东西。
控件可以根据需要将名称自身公开为依赖属性(因为它们需要在内部使用该依赖属性),也可以选择不这样做。
一些 WPF 框架级应用程序可能能够避免使用任何 x:Name 属性,因为在 WPF 命名空间中为几个重要的基类(例如 FrameworkElement/FrameworkContentElement)指定的 Name 依赖项属性满足了同样的目的。仍然有一些常见的 XAML 和框架方案需要对没有 Name 属性的元素进行代码访问,尤其是在某些动画和情节提要支持类中。例如,如果您打算从代码中引用它们,则应在 XAML 中创建的时间线和转换上指定 x:Name。
如果 Name 可用作类的属性,则 Name 和 x:Name 可以作为属性互换使用,但如果在同一元素上同时指定两者,则会导致错误。
如果您有自定义控件,X:Name 可能会导致内存问题。它将为 NameScope 条目保留一个内存位置。
我说除非必须,否则永远不要使用 x:Name。
姓名:
x:姓名:
在 XAML 中对一个 FrameworkElement 或 FrameworkContentElement 使用这两个指令将导致异常:如果 XAML 是标记编译的,则异常将在标记编译时发生,否则在加载时发生。
唯一的区别是,如果您将用户控件用于同一程序集中的控件,则名称将无法识别您的控件,并且您将收到错误“使用 x:Name 用于同一程序集中的控件”。所以 x:Name 是 WPF 中命名控件的 WPF 版本。名称仅用作 Winform Legacy。他们想要区分 WPF 和 winforms 中控件的命名,因为他们使用 Xaml 中的属性来识别来自其他程序集的控件,他们使用 x: 表示控件名称。
请记住,不要仅仅为了保留它而为控件命名,因为它作为空白驻留在内存中,它会警告您名称已应用于控件但从未使用过。
x:Name
意思是:在后面的代码中创建一个字段来保存对这个对象的引用。
Name
意思是:设置这个对象的名称属性。
我总是使用 x:Name 变体。我不知道这是否会影响任何性能,我只是发现它更容易,原因如下。如果您有自己的用户控件驻留在另一个程序集中,那么“名称”属性并不总是足够的。这使得粘贴 x:Name 属性变得更容易。
指定的x:Name成为在处理 XAML 时在基础代码中创建的字段的名称,并且该字段包含对对象的引用。在 Silverlight 中,使用托管 API 创建此字段的过程由 MSBuild 目标步骤执行,这些步骤还负责连接 XAML 文件的部分类及其代码隐藏。此行为不一定是指定的 XAML 语言;这是 Silverlight在其编程和应用程序模型中使用x:Name的特定实现。
当您在 XAML 中声明 Button 元素时,您指的是在 Windows 运行时中定义的称为 Button 的类。
Button 有许多属性,例如背景、文本、边距、......以及一个名为 Name 的属性。
现在,当您在 XAML 中声明一个 Button 时,就像创建一个碰巧有一个名为 Name 的属性的匿名对象。
通常,您不能引用匿名对象,但在 WPF 框架中,XAML 处理器允许您通过为 Name 属性提供的任何值来引用该对象。
到现在为止还挺好。
创建对象的另一种方法是创建命名对象而不是匿名对象。在这种情况下,XAML 命名空间有一个名为 Name 的对象的属性(并且因为它在 XAML 命名空间中,因此有 X:),您可以设置该属性,以便您可以识别您的对象并引用它。
结论:
Name 是特定对象的属性,但 X:Name 是该对象的一个属性(有一个定义通用对象的类)。
答案之一是 x:name 将在不同的程序语言(例如 c#)中使用,而 name 将用于框架。老实说,这就是我听起来的样子。
Name
也可以使用带有内部文本的属性元素语法来设置,但这并不常见。相反,x:Name
不能在XAML
属性元素语法中设置,也不能在使用SetValue
;的代码中设置。它只能使用对象的属性语法来设置,因为它是一个指令。
IfName
可作为类的属性使用,Name
并且x:Name
可以作为属性互换使用,但如果在同一元素上同时指定两者,则会导致解析异常。如果 XAML 是标记编译的,则异常将在标记编译时发生,否则在加载时发生。
我的研究是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
属性Content
为Button
“btn”,因为它在外部StackPanel