您的位置:首页 > 其它

[WPF 容易忽视的细节] —— x:Name与Name属性

2013-10-14 17:26 281 查看

一、前言

WPF使用XAML来对界面进行编写,界面与后台逻辑分离。我们也可以写Style、Trigger来实现一些界面效果,

这些都是通过Name来定位控件的,例如Setter.TargetName、Trigger.SourceName和Binding的ElementName等。

而这些Name都是通过设置控件的x:Name来定义的,如<Button x:Name="Button1" />

但是,XAML中有x:Name和Name这两个属性,究竟它们有什么区别呢?

本专题就来探究一下x:Name和Name的区别,它们的本质又是什么?

二、XAML与Code-Behind

在编写WPF程序时,通常需要分别编写前台XAML代码和后台Code-Behind代码(不使用MVVM时)。

WPF通过一个partial关键字,将一个类的定义切分为两部分:XAML和Code-Behind。

其中XAML交给设计师设计,Code-Behind交给程序员写业务逻辑,从而实现分离(虽然大部分时候全部都是程序员完成的)。

我们在XAML上写标签,其实与后台写代码是等效的。只要你想,完全可以只使用XAML或者只是用Code-Behind来写程序。

示例:

namespace System.Windows.Markup
{
[AttributeUsage(AttributeTargets.Class)]
[TypeForwardedFrom("WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")]
public sealed class RuntimeNamePropertyAttribute : Attribute
{
private string _name;

public string Name
{
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get
{
return this._name;
}
}

[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public RuntimeNamePropertyAttribute(string name)
{
this._name = name;
}
}
}


RuntimeNamePropertyAttribute
可以看出来这个特性使用在Class上面的,也就是这个特性,使得XAML处理Name时,映射到了x:Name,才有了前面的结论。

我们再来查看以下还有哪些类使用了这个特性。

在4个Assembly中找到了13个,比较眼熟的有:

Timeline、BeginStoryboard、FrameworContentElement、FramewordElement、VisualState、VisualStateGroup,

这些也基本都是WPF中很多常用类型的基类了。

结论:RuntimeNameProperty特性,使得XAML中使用Name和x:Name效果一样,当编译器遇到此特性后,

就将Name映射到x:Name,执行一样的操作。

六、XAML中x:Name与Name并不完全等价。

不是所有类型都可以使用Name,但是任何类型都可以使用x:Name。

只有拥有Name属性,才可以在XAML中使用Name。不同于x:Name,因为这个是附加属性。

并且该类型、或者其父类型标记了RuntimeNameProperty特性,才拥有与x:Name一样的效果。

例如:<SolidColorBrush Color="Transparent" Name="ddd"/>便会报错,因为SolidColorBrush没有Name属性。

只能使用x:Name。<SolidColorBrush Color="Transparent" x:Name="ddd"/>

七、其他

1、分析为什么要有x:Name

前面提到,XAML中经常需要通过名字来定位某个控件或对象,而SomeWpfType的Name属性,只是一个DP,我们可以设置两个控件拥有相同的Name属性。

那么这样就非常不利于定位控件,因为Name不是一个唯一的标识了。

使用对象的引用有两个好处:

1.在特定的范围域内,能够保证它的唯一性;

2.在视图树中查找某个对象时,通过引用对象的名称比查找Name属性更加简单。

2. MSDN上对着几个名词的定义


FrameworkElement.Name - Gets or sets the identifying name of the element. The name provides a reference so that code-behind, such as event handler code, can refer to a markup element after it is constructed during processing by a XAML processor.

Remark:

The most common usage of this property is to specify a XAML element name as an attribute in markup.

This property essentially provides a WPF framework-level convenience property to set the XAML x:Name Directive.

Names must be unique within a namescope. For more information, see WPF XAML Namescopes.



x:Name Directive - Uniquely identifies XAML-defined elements in a XAML namescope. XAML namescopes and their uniqueness models can be applied to the instantiated objects, when frameworks provide APIs or implement behaviors that access the XAML-created object graph at run time.

Remark:

The value of an x:Name directive usage must be unique within a XAML namescope. By default when used by .NET Framework XAML Services API, the primary XAML namescope is defined at the XAML root element of a single XAML production, and encompasses the elements that are contained in that XAML production. Additional discrete XAML namescopes that might occur within a single XAML production can be defined by frameworks to address specific scenarios. For example, in WPF, new XAML namescopes are defined and created by any template that is also defined on that XAML production. For more information about XAML namescopes (written for WPF but relevant for many XAML namescope concepts), see WPF XAML Namescopes.



希望对大家有帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: