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

In WPF, what are the differences between the x:Name and Name attributes?

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

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

使用错误的方法是否会影响性能或内存?


在XAML中实际上只有一个名称,即x:Name。框架(如wpf)可以选择将其属性之一映射到xaml的x:Name,方法是在类上使用RuntimeNamePropertyAttribute,该类指定其中一个类属性作为xaml的x:name属性的映射。

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

一般来说,类不需要存储x:Name的名称即可使用。所有用于XAML的x:Name方法都是生成一个字段,将值存储在代码隐藏类中。运行时对该映射所做的操作依赖于框架。

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

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

你应该使用一个还是另一个确实是一个风格问题,而不是技术问题。我会把它留给别人推荐。

另请参见automationproperties.name与x:name、automationproperties.name由辅助工具和一些测试工具使用。


他们不是一回事。

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

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

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


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

x:name是对x命名空间的引用,默认情况下该命名空间是在xaml文件的顶部定义的。

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

只是说名称使用了下面的默认名称空间。

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

x:name表示使用具有x别名的命名空间。X是默认值,大多数人都会离开它,但你可以将它改为你喜欢的任何东西。

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

所以你的推荐人是foo:name

在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%),而presentation包含frameworkelement,button类的继承模式为:

1
2
3
4
5
6
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:

1
2
3
4
5
6
7
8
9
10
11
[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,因为它适用于所有内容。

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

有关详细信息,请参阅此处和此处的msdn:

Some WPF framework-level applications
might be able to avoid any use of the
x:Name attribute, because the Name
dependency property as specified
within the WPF namespace for several
of the important base classes such as
FrameworkElement/FrameworkContentElement
satisfies this same purpose. There are
still some common XAML and framework
scenarios where code access to an
element with no Name property is
necessary, most notably in certain
animation and storyboard support
classes. For instance, you should
specify x:Name on timelines and
transforms created in XAML, if you
intend to reference them from code.

If Name is available as a property on
the class, Name and x:Name can be used
interchangeably as attributes, but an
error will result if both are
specified on the same element.


x:name如果有自定义控件,可能会导致内存问题。它将为名称作用域条目保留一个内存位置。

我说除非你必须,否则不要用x:name。


姓名:

  • 只能用于frameworkelement和frameworkcontentelement的后代;
  • 可以通过setValue()和类似属性从代码隐藏中设置。
  • 姓名:

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


    唯一的区别是,如果将用户控件用于来自同一程序集的控件,则名称将不会标识控件,并且将得到错误"对同一程序集中的控件使用x:name"。所以x:name是wpf中命名控件的wpf版本控制。名称仅用作WinForm的传统。他们希望区分WPF和WinForms中控件的命名,因为它们在XAML中使用属性来标识控件与使用X:表示控件名称的其他程序集。

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


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

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


    我总是使用x:name变量。我不知道这是否会影响到任何性能,我只是发现它更容易,原因如下。如果您有自己的用户控件驻留在另一个程序集中,"name"属性并不总是足够。这样就更容易坚持X:Name属性。


    它不是一个wpf项,而是一个标准的xml项,btbh已经正确地回答了它,x引用了默认的名称空间。在XML中,如果不为元素/属性添加名称空间前缀,则假定需要默认的名称空间。所以只输入Name只不过是x:Name的一个简略的操作。有关XML命名空间的详细信息,请参见链接文本。


    在XAML中声明Button元素时,所指的是在Windows运行时调用的Button中定义的类。

    按钮有许多属性,如背景、文本、页边距…以及一个名为name的属性。

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

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

    到现在为止,一直都还不错。

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

    结论:

    名称是特定对象的属性,但x:name是该对象的一个属性(有一个类定义了一个常规对象)。


    其中一个答案是x:name将在不同的程序语言(如c)中使用,name将用于框架。老实说,我就是这么想的。


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

    阅读有关msdn的详细信息…


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

    1
    2
    3
    4
    5
    <StackPanel>
    <TextBlock Text="{Binding Path=Content, ElementName=btn}" />
    <Button Content="Example" Name="btn" />
    </StackPanel>
    <TextBlock Text="{Binding Path=Content, ElementName=btn}" />

    你不能把ButtonContent的财产Binding命名为"btn",因为它在StackPanel之外。