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

时间:2009-02-26 09:53:22

标签: .net wpf xaml name-attribute

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

那么,它们之间有什么明确的区别,何时优先使用另一个呢?

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

15 个答案:

答案 0 :(得分:448)

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

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

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

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

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

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

另请参阅AutomationProperties.Name VS x:Name,可访问性工具和一些测试工具使用AutomationProperties.Name。

答案 1 :(得分:77)

他们不是一回事。

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

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

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

答案 2 :(得分:33)

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

x:name 是对默认位于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:name

Define and Use Namespaces in WPF


好的,让我们以不同的方式看待这个。假设您将按钮拖放到Xaml页面上。您可以参考以下两种方式 x:name name 。所有 xmlns =“http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x =“http://schemas.microsoft.com/winfx/2006/xaml”是对多个名称空间的引用。由于 xaml 拥有控制命名空间(不是100%),演示文稿包含 FrameworkElement Button类的继承模式为:

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定义了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")]  

答案 3 :(得分:19)

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

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

msdn herehere中的详细信息:

  

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

     

如果名称可用作属性   可以使用类,名称和x:名称   可互换地作为属性,但是   如果两者都是错误的结果   在同一元素上指定。

答案 4 :(得分:9)

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

我说永远不要使用x:姓名,除非你必须。

答案 5 :(得分:7)

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

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

答案 6 :(得分:7)

命名

  1. 只能用于FrameworkElement和FrameworkContentElement;
  2. 的后代
  3. 可以通过SetValue()和类似属性从代码隐藏设置。
  4. <强> X:名称

    1. 几乎可以用于所有XAML元素;
    2. 无法设置 通过SetValue()进行代码隐藏;它只能使用属性设置 对象的语法,因为它是一个指令。
    3. 在XAML中为一个FrameworkElement或FrameworkContentElement使用这两个指令将导致异常:如果XAML是标记编译的,则在标记编译时将发生异常,否则它将在加载时发生。

答案 7 :(得分:5)

x:Name表示:在后面的代码中创建一个字段以保存对该对象的引用。

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

答案 8 :(得分:4)

我总是使用x:Name变体。 我不知道这是否会影响任何性能,我只是因为以下原因而发现它更容易。 如果你有自己的usercontrols驻留在另一个程序集中,那么“Name”属性并不总是足够的。这样就可以更容易地粘贴x:Name属性。

答案 9 :(得分:3)

它不是WPF项目,而是标准XML项目,而BtBh已正确回答它,x指的是默认名称空间。在XML中,如果没有使用命名空间为元素/属性添加前缀,则假定您需要默认命名空间。 因此,仅仅输入Name只不过是x:Name的简写。有关XML命名空间的更多详细信息,请访问link text

答案 10 :(得分:2)

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

答案 11 :(得分:2)

在XAML中声明一个Button元素时,你指的是一个名为Button的Windows运行时定义的类。

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

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

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

到目前为止一切顺利。

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

结论:

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

答案 12 :(得分:1)

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

<强> Read More on MSDN...

答案 13 :(得分:1)

也可以使用带有内部文本的属性元素语法来设置

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

答案 14 :(得分:0)

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

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

Binding Content Button StackPanel {{1}} {{1}} {{1}}名称为&#34; btn&#34;因为它在{{1}}

之外