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

有时,Namex:Name属性似乎是可以互换的。

那么,它们之间的决定性区别是什么?什么时候使用一种比另一种更可取?

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

144642 次浏览
我总是使用x:Name变量。 我不知道这是否会影响性能,我只是觉得它更容易,原因如下。 如果您有自己的用户控件驻留在另一个程序集中,只有“Name”属性并不总是足够的。这使得使用x:Name属性更加简单

它们都是一样的东西,很多框架元素本身公开了name属性,但对于那些不公开的元素,你可以使用x:name -我通常只使用x:name,因为它适用于任何东西。

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

msdn 在这里在这里中有更多细节:

一些WPF框架级的应用程序 也许可以避免使用任何 x:Name属性,因为Name 指定的依赖属性 在WPF命名空间中 的重要基类 FrameworkElement / FrameworkContentElement 满足同样的目的。有 仍然是一些常见的XAML和框架 代码访问的场景 元素没有Name属性 是必要的,尤其是在某些情况下 动画和故事板支持 类。例如,你应该 在时间轴上指定x:名称和 在XAML中创建的转换,如果您 打算从代码中引用它们

如果Name作为属性可用 可以使用class、Name和x:Name 可以互换为属性,但是an 如果两者都是,则会产生错误

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"

所以你的参考将是foo:名字

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


好,我们换个角度看。假设您将一个按钮拖放到Xaml页面上。你可以用x:名字的名字两种方式引用它。所有xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation " xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"是对多个命名空间的引用。因为xaml拥有控制命名空间(不是100%),演讲拥有FrameworkElement按钮类有一个继承模式:

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 Reference

WPF定义了一个CLR属性,XAML处理器使用该属性将多个CLR名称空间映射到单个XML名称空间。XmlnsDefinitionAttribute属性位于生成程序集的源代码中的程序集级别。WPF程序集源代码使用此属性映射各种公共名称空间,例如System。Windows和System.Windows。控件,到http://schemas.microsoft.com/winfx/2006/xaml/presentation命名空间。

所以程序集属性看起来像这样:

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")]

这不是一个WPF项,而是一个标准的XML项,BtBh已经正确回答了它,x指的是默认的命名空间。在XML中,如果不给元素/属性加上名称空间前缀,则假定您需要默认名称空间。 因此,键入Name只不过是x:Name的简写。关于XML名称空间的更多细节可以在链接文本

中找到

在XAML中实际上只有一个名称,x:Name。一个框架,比如WPF,可以通过在类上使用RuntimeNamePropertyAttribute来将它的一个属性映射到XAML的x:Name属性,从而有选择地将它的一个属性映射到XAML的x:Name

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

一般来说,类不需要存储名称,以便x:Name可用。对于XAML来说,x:Name意味着生成一个字段来存储类后面的代码中的值。运行时对映射的处理依赖于框架。

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

在未来,XAML会有更多x:Name的用途,比如允许你通过名称引用其他对象来设置属性,但在3.5和更早的版本中,它只用于创建字段。

你应该使用其中一种还是另一种实际上是一个风格问题,而不是技术问题。我将把这个留给其他人来推荐。

参见AutomationProperties。名称VS x:名称, AutomationProperties。可访问性工具和一些测试工具使用Name。

它们不是一回事。

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

NameFrameworkElement的现有字符串属性,以xaml属性的形式列出任何其他wpf元素属性。

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

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

我建议除非迫不得已,否则不要使用x:Name。

唯一的区别是,如果你从相同的程序集使用用户控件到一个控件中,那么Name将不会识别你的控件,你将得到一个错误“使用x:名称用于相同程序集中的控件”。 所以x:Name是WPF中命名控件的WPF版本。Name只是用作Winform Legacy。他们想在WPF和winforms中区分控件的命名,因为他们使用Xaml中的属性来标识控件与其他程序集,他们使用x:表示控件的名称。< / p >

请记住,不要为控件命名,因为它在内存中是空白的,它会给你一个警告,说明名称已应用于控件,但它从未使用过。

# EYZ0:

  1. 只能用于FrameworkElement和FrameworkContentElement的后代;
  2. 可以通过SetValue()和property-like在代码后面设置。

# EYZ0:

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

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

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

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

Name表示:设置该对象的name属性。

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

Read More on MSDN

当您在XAML中声明Button元素时,您引用的是在windows运行时中定义的一个名为Button的类。

按钮有很多属性,如背景,文本,边距,.....和一个名为Name的属性。

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

一般来说,你不能引用一个匿名对象,但是在WPF框架中,XAML处理器允许你通过给Name属性的任何值来引用该对象。

到目前为止一切顺利。

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

结论:

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

我的研究是x:Name作为全球变量。但是,Name作为当地的变量。这是否意味着x:Name可以在XAML文件的任何地方调用,但Name不能。
例子:< / p >
<StackPanel>
<TextBlock Text="{Binding Path=Content, ElementName=btn}" />
<Button Content="Example" Name="btn" />
</StackPanel>
<TextBlock Text="{Binding Path=Content, ElementName=btn}" />

你不能Binding属性ContentButton名称是“btn”,因为它在StackPanel之外

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