663 votes

Dans WPF, quelles sont les différences entre les attributs x:Name et Name ?

Parfois, il semble que le Name et x:Name sont interchangeables.

Alors, quelles sont les différences définitives entre eux, et quand est-il préférable d'utiliser l'un plutôt que l'autre ?

Y a-t-il des conséquences sur les performances ou la mémoire si on ne les utilise pas de la bonne façon ?

2 votes

Les réponses suggèrent que l'utilisation de x:Name tout le temps fonctionne bien. J'ai juste dû le changer pour Name Sinon, je n'ai pas pu faire référence au contrôle dans mon code .xaml.cs. Je vais donc supposer que ce n'est plus le cas et qu'il fonctionne bien tout le temps.

526voto

chuckj Points 7975

Il n'y a vraiment qu'un seul nom en XAML, le x:Name . Un framework, tel que WPF, peut éventuellement faire correspondre l'une de ses propriétés à la propriété XAML x:Name en utilisant le RuntimeNamePropertyAttribute sur la classe qui désigne l'une des propriétés de la classe comme étant le mappage de l'attribut x:Name de XAML.

Cette mesure a été prise pour tenir compte des structures qui ont déjà un concept de "nom" au moment de l'exécution, comme WPF. Dans WPF, par exemple, FrameworkElement introduit une propriété Nom.

En général, une classe n'a pas besoin de stocker le nom de l'élément x:Name pour être utilisable. Tous les sites x:Name signifie pour XAML de générer un champ pour stocker la valeur dans le code derrière la classe. Ce que le runtime fait avec ce mapping dépend du framework.

Alors, pourquoi y a-t-il deux façons de faire la même chose ? La réponse est simple : parce que deux concepts sont associés à une seule propriété. WPF veut que le nom d'un élément soit préservé au moment de l'exécution (ce qui est utilisable par le biais de Bind, entre autres) et XAML a besoin de savoir quels éléments vous voulez rendre accessibles par des champs dans le code derrière la classe. WPF lie ces deux éléments en marquant la propriété Name comme un alias de x:Name.

À l'avenir, XAML aura d'autres utilisations de x:Name, par exemple pour vous permettre de définir des propriétés en faisant référence à d'autres objets par leur nom, mais dans les versions 3.5 et antérieures, il est uniquement utilisé pour créer des champs.

La question de savoir si vous devez utiliser l'un ou l'autre est vraiment une question de style, et non une question technique. Je laisserai à d'autres le soin de formuler une recommandation.

Voir aussi AutomationProperties.Name VS x:Name AutomationProperties.Name est utilisé par les outils d'accessibilité et certains outils de test.

2 votes

Dans Visual Studio 2010, la propriété Name est définie (et non x:Name) lorsque vous modifiez le XAML via le concepteur. Il semble que MS encourage l'utilisation de Name au lieu de x:Name, donc je suppose que c'est la norme de facto.

13 votes

Je ne pense pas que les deux soient interchangeables en général. Nommer les contrôles de l'utilisateur nécessite x:Name parce que Name ne crée pas de champ à reconnaître dans le code-behind. Je ne sais toujours pas pourquoi cela se produit, cependant.

7 votes

Ils ne le sont pas et je n'ai pas voulu insinuer qu'ils l'étaient. Dans WPF, si un élément a un Name propriété, ils signifient la même chose. Si l'élément n'a pas de propriété Name vous devez utiliser la propriété x:Name .

114voto

Kenan E. K. Points 8497

Ce n'est pas la même chose.

x:Name est un concept xaml, utilisé principalement pour référencer des éléments. Lorsque vous donnez à un élément l'attribut x:Name xaml, "l'élément spécifié" est considéré comme un élément de référence. x:Name devient le nom d'un champ qui est créé dans le code sous-jacent lorsque le xaml est traité, et ce champ contient une référence à l'objet." ( MSDN ) Il s'agit donc d'un champ généré par le concepteur, qui a un accès interne par défaut.

Name est la propriété de la chaîne existante d'un FrameworkElement comme toute autre propriété d'un élément wpf, sous la forme d'un attribut xaml.

Par conséquent, cela signifie également x:Name peut être utilisé sur un plus grand nombre d'objets. Il s'agit d'une technique permettant de référencer n'importe quel objet dans le xaml par un nom donné.

9 votes

Alors pourquoi peut-on utiliser soit Name soit x:Name avec Binding.ElementName ? Il semble que l'attribut x:Name ne soit pas seulement utilisé pour nommer un champ dans le code généré, mais qu'il soit également disponible dans les métadonnées au moment de l'exécution.

2 votes

C'est un champ généré comme le champ Nom dans les propriétés de conception de l'éditeur WinForms. Là, vous placez un nom dans la liste des propriétés et il devient le nom d'un champ. C'est le même comportement. Bien sûr, il est disponible au moment de l'exécution puisqu'il s'agit d'un champ interne compilé dans le code derrière. Binding.ElementName vérifie les deux cas, c'est la "magie" de l'éditeur xaml, le x:Name n'est pas magique en soi.

0 votes

Un champ sera généré, que vous utilisiez x:Name ou Name. Il n'y a pas de différence entre x:Name et Name pour tous les types dérivés de FrameworkElement (ce qui est le cas de la plupart des types utilisés dans XAML), à une seule exception près : Si vous voulez donner à un UserControl un nom et ce UserControl est déclaré dans la même assemblée où vous voulez également l'utiliser vous devrez utiliser x:Name en raison de la limitation de l'analyseur XAML.

48voto

cgreeno Points 17379

X:Name et Name font référence à des espaces de noms différents.

x:nom est une référence à l'espace de nom x défini par défaut en haut du fichier Xaml.

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

Je dis juste Nom utilise l'espace de nom par défaut ci-dessous.

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

x:Nom est de dire d'utiliser l'espace de nom qui a le x alias. x est la valeur par défaut et la plupart des gens la laissent, mais vous pouvez la changer en ce que vous voulez.

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

donc votre référence serait foo:nom

Définir et utiliser les espaces de noms dans WPF


Voyons cela sous un autre angle. Disons que vous faites glisser et déposez un bouton sur votre page Xaml. Vous pouvez le référencer de 2 façons x:nom et nom . Tous les sites xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" et xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" sont des références à plusieurs espaces de noms. Puisque xaml détient le Contrôle (pas à 100%) et présentation détient le Élément-cadre ET le Classe de boutons a un modèle d'héritage de :

Button : ButtonBase
ButtonBase : ContentControl, ICommandSource
ContentControl : Control, IAddChild
Control : FrameworkElement
FrameworkElement : UIElement, IFrameworkInputElement, 
                    IInputElement, ISupportInitialize, IHaveResources

Donc, comme on peut s'y attendre, tout ce qui hérite de FrameworkElement a accès à tous ses attributs publics. Ainsi, dans le cas du bouton, l'attribut Name provient de FrameworkElement, tout en haut de l'arbre hiérarchique. Alors vous pouvez dire x:Nom ou Nom et ils accéderont tous deux au getter/setter de l'élément FrameworkElement.

Référence MSDN

WPF définit un attribut CLR qui est utilisé par les processeurs XAML afin de faire correspondre plusieurs espaces de noms CLR à un seul espace de noms XML. Le site XmlnsDefinitionAttribute est placé au niveau de l'assemblage dans le code source qui produit l'assemblage. Le code source de l'assemblage WPF utilise cet attribut pour faire correspondre les divers espaces de noms communs, tels que System.Windows et System.Windows.Controls, à l'espace de noms de l'assemblage WPF. http://schemas.microsoft.com/winfx/2006/xaml/presentation espace de noms.

Ainsi, les attributs de l'assemblage ressembleront à quelque chose comme :

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

1 votes

Je ne pense pas que ce soit vrai que http://schemas.microsoft.com/winfx/2006/xaml détient Control puisque vous pouvez l'utiliser directement dans XAML sans espace de nom "x" : <Control />

28voto

Steven Robbins Points 18791

C'est la même chose, beaucoup d'éléments du cadre exposent eux-mêmes une propriété de nom, mais pour ceux qui ne le font pas, vous pouvez utiliser x:name - je m'en tiens généralement à x:name parce que cela fonctionne pour tout.

Les contrôles peuvent s'exposer en tant que propriété de dépendance s'ils le souhaitent (parce qu'ils doivent utiliser cette propriété de dépendance en interne), ou ils peuvent choisir de ne pas le faire.

Plus de détails dans msdn ici et ici :

Certaines applications WPF de niveau cadre pourraient être en mesure d'éviter toute utilisation de l'élément x:Name, car l'attribut Name telle que spécifiée dans l'espace de noms WPF pour plusieurs des classes de base importantes telles que FrameworkElement/FrameworkContentElement répond à ce même objectif. Il existe encore quelques scénarios XAML et framework communs où l'accès du code à un élément élément sans propriété Name est nécessaire nécessaire, notamment dans certains support d'animation et de storyboard d'animation et de storyboard. Par exemple, vous devez spécifier x:Name sur les lignes de temps et transformées créées en XAML, si vous avez si vous avez l'intention de les référencer dans le code.

Si Name est disponible comme propriété de la classe la classe, Name et x:Name peuvent être utilisés interchangeables comme attributs, mais une mais une erreur se produira si les deux sont spécifiés sur le même élément.

4 votes

S'il n'y a pas de différence, alors pourquoi y aurait-il deux façons de faire la même chose ? Les deux méthodes existaient dans la première version de WPF.

0 votes

@Steve, je n'ai déclassé aucune des réponses à cette question, même si aucune d'entre elles n'était jusqu'à présent très appropriée.

1 votes

Je ne vois pas en quoi une réponse qui non seulement vous donne la réponse, mais vous donne aussi des liens vers MSDN pour plus d'informations sur le sujet n'est pas appropriée :-)

14voto

scott Points 29

X:Name peut causer des problèmes de mémoire si vous avez des contrôles personnalisés. Il conservera un emplacement mémoire pour l'entrée NameScope.

Je dis de ne jamais utiliser x:Name à moins d'y être obligé.

0 votes

Approuvé. J'ai travaillé sur une application de kiosque qui avait de nombreuses fuites de mémoire et la résolution de l'équipe de développement précédente consistait simplement à forcer un redémarrage. La plupart des fuites étaient facilement identifiables. Pourtant, après avoir corrigé celles trouvées via IntelliTrace et JustTrace, certaines références échappaient encore au garbage collection implicite et explicite. J'ai lu : support.scichart.com/index.php?/Nouvelles/NewsItem/View/21/ J'ai constaté que la réduction de x:Name améliorait encore les performances.

3 votes

Je crois comprendre que cela affecte les deux Nom et x:Nom car les deux sont ajoutés à NameScope. Si vous avez besoin d'un nom sur votre élément, il n'y a pas d'autre solution. Vous pouvez reproduire en code sur un élément sans nom via FrameworkElement.RegisterName("elementname") . Cependant, si vous appelez FrameworkElement.UnregisterName("elementname") il peut être "déréférencé".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X