Was sind in WPF die Unterschiede zwischen den Attributen x: Name und Name?

574

Der Titel sagt alles. Manchmal scheint es, dass die Nameund x:NameAttribute austauschbar sind.

Also, was sind die endgültigen Unterschiede zwischen ihnen und wann ist es vorzuziehen, einen über den anderen zu verwenden?

Gibt es irgendwelche Auswirkungen auf die Leistung oder den Speicher, wenn sie falsch verwendet werden?

Drew Noakes
quelle
Die Antworten deuten darauf hin, dass die ständige Verwendung x:Nameeinwandfrei funktioniert. Ich musste es nur ändern, Namesonst konnte ich das Steuerelement in meinem .xaml.cs-Code nicht referenzieren, daher gehe ich davon aus, dass es nicht mehr immer funktioniert.
Ortund
1
Welche zusätzliche Bedeutung hat der Satz "Der Titel sagt alles", Drew, in Bezug auf Ihren Rollback? Ist es nicht redundant? (Mein Grund für die Bearbeitung ist, dass ich dazu neige, Konversationsfüllphrasen zu entmutigen - dies ist nicht informativer als "Ich frage mich, ob Sie mir helfen können").
Halfer

Antworten:

481

Es gibt wirklich nur einen Namen in XAML, den x:Name. Ein Framework wie WPF kann optional eine seiner Eigenschaften XAMLs zuordnen, x:Nameindem es die RuntimeNamePropertyAttributeon-Klasse verwendet, die eine der Klasseneigenschaften als Zuordnung zum x: Name-Attribut von XAML festlegt.

Der Grund dafür war, Frameworks zuzulassen, die zur Laufzeit bereits das Konzept "Name" haben, wie z. B. WPF. In WPF wird beispielsweise FrameworkElementeine Name-Eigenschaft eingeführt.

Im Allgemeinen muss eine Klasse den Namen nicht speichern, um verwendet werden x:Namezu können. Alles, x:Namewas XAML bedeutet, ist, ein Feld zu generieren, um den Wert im Code hinter der Klasse zu speichern. Was die Laufzeit mit dieser Zuordnung macht, ist vom Framework abhängig.

Warum gibt es also zwei Möglichkeiten, dasselbe zu tun? Die einfache Antwort lautet, dass zwei Konzepte auf eine Eigenschaft abgebildet sind. WPF möchte, dass der Name eines Elements zur Laufzeit erhalten bleibt (was unter anderem über Bind verwendet werden kann), und XAML muss wissen, auf welche Elemente Felder im Code hinter der Klasse zugreifen sollen. WPF verbindet diese beiden Elemente, indem es die Name-Eigenschaft als Alias ​​von x: Name markiert.

In Zukunft wird XAML mehr Verwendungszwecke für x: Name haben, z. B. das Festlegen von Eigenschaften durch Verweisen auf andere Objekte nach Namen. In Version 3.5 und früheren Versionen wird XAML jedoch nur zum Erstellen von Feldern verwendet.

Ob Sie das eine oder das andere verwenden sollten, ist wirklich eine Stilfrage, keine technische. Ich werde das anderen für eine Empfehlung überlassen.

Siehe auch AutomationProperties.Name VS x: Name , AutomationProperties.Name wird von Eingabehilfen und einigen Testtools verwendet.

chuckj
quelle
2
In Visual Studio 2010 wird die Eigenschaft Name festgelegt (nicht x: Name), wenn Sie die XAML über den Designer bearbeiten. Es scheint, als würde MS die Verwendung von Name über x: Name empfehlen, also denke ich, dass dies der Defacto-Standard ist.
Nebel
11
Ich denke nicht, dass die beiden im Allgemeinen austauschbar sind. Das Benennen von Benutzersteuerelementen erfordert, x:Nameda Namekein Feld erstellt wird, das im CodeBehind erkannt wird. Ich weiß immer noch nicht, warum das passiert.
Libor
5
Sie sind nicht und ich wollte auch nicht implizieren, dass sie es taten. Wenn in WPF ein Element eine NameEigenschaft hat, bedeutet dies dasselbe. Wenn das Element keine NameEigenschaft hat, müssen Sie verwenden x:Name.
Chuckj
90

Sie sind nicht dasselbe.

x:Nameist ein xaml-Konzept, das hauptsächlich zum Referenzieren von Elementen verwendet wird. Wenn Sie einem Element das xaml-Attribut x: Name geben, "wird das angegebene x:Namezum Namen eines Felds, das im zugrunde liegenden Code erstellt wird, wenn xaml verarbeitet wird, und dieses Feld enthält einen Verweis auf das Objekt." ( MSDN ) Es handelt sich also um ein vom Designer generiertes Feld, das standardmäßig über internen Zugriff verfügt.

Nameist die vorhandene Zeichenfolgeeigenschaft von a FrameworkElement, die als jede andere wpf-Elementeigenschaft in Form eines xaml-Attributs aufgeführt ist.

Infolgedessen kann dies auch x:Namefür eine größere Anzahl von Objekten verwendet werden. Dies ist eine Technik, mit der alles in xaml mit einem bestimmten Namen referenziert werden kann.

Kenan EK
quelle
6
Warum kann mit Binding.ElementName entweder Name oder x: Name verwendet werden? Es scheint, dass das Attribut x: Name nicht nur zum Benennen eines Felds im generierten Code verwendet wird, sondern auch zur Laufzeit auch in Metadaten verfügbar ist.
Drew Noakes
Es ist ein generiertes Feld wie das Feld Name in den Design-Eigenschaften des WinForms-Editors. Dort platzieren Sie einen Namen in der Eigenschaftsliste und dieser wird zum Namen eines Feldes. Dies ist das gleiche Verhalten. Natürlich ist es zur Laufzeit verfügbar, da es sich um ein internes Feld handelt, das in den Code dahinter kompiliert wurde. Binding.ElementName prüft in beiden Fällen, ob es sich um den xaml-Editor "magic" handelt. Der x: Name ist an sich nicht magisch.
Kenan EK
39

x: Name und Name verweisen auf unterschiedliche Namespaces.

x: name ist ein Verweis auf den x-Namespace, der standardmäßig oben in der Xaml-Datei definiert ist.

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

Wenn Sie nur Name sagen, wird der unten stehende Standard-Namespace verwendet.

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

x: Name sagt, benutze den Namespace, der den x- Alias ​​hat. x ist die Standardeinstellung und die meisten Leute verlassen sie, aber Sie können sie nach Belieben ändern

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

Ihre Referenz wäre also foo: name

Definieren und Verwenden von Namespaces in WPF


OK, sehen wir uns das anders an. Angenommen, Sie ziehen eine Schaltfläche per Drag & Drop auf Ihre Xaml-Seite. Sie können auf zwei Arten auf x verweisen : Name und Name . Alle xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" und xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml" verweisen auf mehrere Namespaces . Da xaml den Control- Namespace enthält (nicht 100%) und die Präsentation das FrameworkElement AND enthält, hat die Button-Klasse ein Vererbungsmuster von:

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

Wie zu erwarten wäre, hätte alles, was von FrameworkElement erbt, Zugriff auf alle öffentlichen Attribute. Im Fall von Button wird das Attribut Name von FrameworkElement ganz oben im Hierarchiebaum abgerufen. So kann man sagen , x: Name oder Namen , und sie werden sowohl die Getter / Setter vom Framework zugreifen.

MSDN-Referenz

WPF definiert ein CLR-Attribut, das von XAML-Prozessoren verwendet wird, um mehrere CLR-Namespaces einem einzelnen XML-Namespace zuzuordnen. Das XmlnsDefinitionAttribute- Attribut wird auf Assemblyebene im Quellcode platziert, der die Assembly erstellt. Der Quellcode der WPF-Assembly verwendet dieses Attribut, um die verschiedenen allgemeinen Namespaces wie System.Windows und System.Windows.Controls dem Namespace http://schemas.microsoft.com/winfx/2006/xaml/presentation zuzuordnen.

Die Assembly-Attribute sehen also ungefähr so ​​aus:

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")]  
cgreeno
quelle
1
Ich glaube nicht , es ist wahr , die http://schemas.microsoft.com/winfx/2006/xamlhält , Controlda Sie es direkt in XAML ohne ein ‚x‘ Namespace verwenden:<Control />
Drew Noakes
23

Sie sind beide dasselbe, viele Framework-Elemente machen eine Namenseigenschaft selbst verfügbar, aber für diejenigen, die dies nicht tun, können Sie x: name verwenden - ich bleibe normalerweise nur bei x: name, weil es für alles funktioniert.

Steuerelemente können den Namen selbst als Abhängigkeitseigenschaft verfügbar machen, wenn sie dies möchten (da sie diese Abhängigkeitseigenschaft intern verwenden müssen), oder sie können sich dagegen entscheiden.

Weitere Details in msdn hier und hier :

Einige Anwendungen auf WPF-Framework-Ebene können möglicherweise die Verwendung des Attributs x: Name vermeiden, da die im WPF-Namespace für mehrere wichtige Basisklassen wie FrameworkElement / FrameworkContentElement angegebene Abhängigkeitseigenschaft Name denselben Zweck erfüllt. Es gibt immer noch einige gängige XAML- und Framework-Szenarien, in denen Codezugriff auf ein Element ohne Name-Eigenschaft erforderlich ist, insbesondere in bestimmten Animations- und Storyboard-Unterstützungsklassen. Beispielsweise sollten Sie x: Name in in XAML erstellten Zeitleisten und Transformationen angeben, wenn Sie beabsichtigen, sie aus Code zu referenzieren.

Wenn Name als Eigenschaft für die Klasse verfügbar ist, können Name und x: Name austauschbar als Attribute verwendet werden. Ein Fehler tritt jedoch auf, wenn beide für dasselbe Element angegeben werden.

Steven Robbins
quelle
4
Wenn es keinen Unterschied gibt, warum gibt es dann zwei Möglichkeiten, dasselbe zu tun? Beide Möglichkeiten gab es in der ersten Version von WPF.
Drew Noakes
@Steve, ich habe keine der Antworten auf diese Frage abgelehnt, obwohl bisher keine davon sehr angemessen war.
Drew Noakes
Ich verstehe nicht, wie eine Antwort, die Ihnen nicht nur die Antwort gibt, sondern auch Links zu MSDN enthält, um weitere Informationen zum Thema zu erhalten, nicht angemessen ist. :-)
Steven Robbins
5
@Steve Ihre ursprüngliche Antwort hat meine Frage nicht beantwortet, daher mein Kommentar. Ich suche nicht nach blindem Glauben, "mach es so", sondern nach einer aufschlussreichen Antwort, die erklärt, warum es zwei Wege gibt, auch wenn einer von ihnen die ganze Zeit funktioniert. Technisch korrekt! = Geeignet. Dein Update ist viel besser.
Drew Noakes
1
Ähnliche Antwort hier: wpfwiki.com/WPF%20Q16.4.ashx x: Name gibt dem Steuerelement einen Namen, der im CodeBehind verwendet werden soll. Einige Klassen bieten eine Name-Eigenschaft für denselben Zweck. Für diese Klassen gibt es keinen Unterschied zwischen x: name und name.
Vegar
11

X: Der Name kann Speicherprobleme verursachen, wenn Sie über benutzerdefinierte Steuerelemente verfügen. Es wird ein Speicherort für den NameScope-Eintrag gespeichert.

Ich sage, benutze niemals x: Name, es sei denn du musst.

Scott
quelle
Einverstanden. Arbeitete an einer Kiosk-App, die zahlreiche Speicherlecks aufwies, und die Lösung des vorherigen Entwicklerteams bestand lediglich darin, einen Neustart zu erzwingen. Ein Großteil der Lecks war leicht zu identifizieren. Nachdem die über IntelliTrace und JustTrace gefundenen Fehler behoben wurden, konnten sich einige Refs der impliziten und expliziten Speicherbereinigung entziehen. Ich habe gelesen: support.scichart.com/index.php?/News/NewsItem/View/21/… Ich habe festgestellt, dass das Reduzieren von x: Name die Leistung weiter verbessert.
MachinusX
2
Nach meinem Verständnis betrifft dies sowohl Name als auch x: Name, da beide zu NameScope hinzugefügt werden. Wenn Sie einen Namen für Ihr Element benötigen, führt kein Weg daran vorbei. Sie können Code für ein Element ohne Namen über neu erstellen FrameworkElement.RegisterName("elementname"). Wenn Sie es aufrufen FrameworkElement.UnregisterName("elementname"), kann es jedoch "dereferenziert" werden.
Adam Caviness
8

Der einzige Unterschied besteht darin, dass, wenn Sie Benutzersteuerelemente in einem Steuerelement aus derselben Assembly verwenden, Name Ihr Steuerelement nicht identifiziert und die Fehlermeldung "Verwenden Sie x: Name für Steuerelemente in derselben Assembly" angezeigt wird. X: Name ist also die WPF-Versionierung von Namenssteuerelementen in WPF. Der Name wird nur als Winform Legacy verwendet. Sie wollten die Benennung von Steuerelementen in WPF und Winforms unterscheiden, da sie Attribute in Xaml verwenden, um Steuerelemente aus anderen Assemblys zu identifizieren, die sie x: für Namen von Steuerelementen verwendeten.

Denken Sie daran, dass Sie einem Steuerelement keinen Namen geben, nur um es zu behalten, da es sich im Speicher als Leerzeichen befindet. Sie erhalten eine Warnung, dass der Name für ein Steuerelement angewendet wurde, aber nie verwendet wird.

Bipul Kumar
quelle
8

Name :

  1. kann nur für Nachkommen von FrameworkElement und FrameworkContentElement verwendet werden;
  2. kann von CodeBehind über SetValue () und eigenschaftsähnlich festgelegt werden.

x: Name :

  1. kann für fast alle XAML-Elemente verwendet werden;
  2. kann NICHT über SetValue () vom Code-Behind aus eingestellt werden; Es kann nur mithilfe der Attributsyntax für Objekte festgelegt werden, da es sich um eine Direktive handelt.

Die Verwendung beider Anweisungen in XAML für ein FrameworkElement oder FrameworkContentElement führt zu einer Ausnahme: Wenn die XAML markupkompiliert ist, tritt die Ausnahme bei der Markupkompilierung auf, andernfalls tritt sie beim Laden auf.

Oleksandr Zolotarov
quelle
7

x:Name bedeutet: Erstellen Sie ein Feld im Code dahinter, um einen Verweis auf dieses Objekt zu enthalten.

Name bedeutet: Legen Sie die Eigenschaft name dieses Objekts fest.

Itzmebibin
quelle
Das ist nicht ganz richtig; Beide sind über den Codebehind zugänglich, aber interessanterweise kann nur der x: Name zur Laufzeit aktualisiert werden. Nussig.
4

Ich benutze immer die Variante x: Name. Ich habe keine Ahnung, ob sich dies auf die Leistung auswirkt. Ich finde es aus folgendem Grund einfacher. Wenn Sie über eigene Benutzersteuerelemente verfügen, die sich in einer anderen Assembly befinden, reicht die Eigenschaft "Name" nicht immer aus. Dies macht es einfacher, auch die Eigenschaft x: Name beizubehalten.

Simon
quelle
4
Wenn es keinen Unterschied gibt, warum gibt es dann zwei Möglichkeiten, dasselbe zu tun? Beide Möglichkeiten gab es in der ersten Version von WPF.
Drew Noakes
3

Es ist kein WPF-Element, sondern ein Standard-XML-Element, und BtBh hat es richtig beantwortet. X bezieht sich auf den Standard-Namespace. Wenn Sie in XML einem Element / Attribut keinen Namespace voranstellen, wird davon ausgegangen, dass Sie den Standard-Namespace möchten. Tippen Nameist also nichts weiter als eine kurze Hand für x:Name. Weitere Details zu XML-Namespaces finden Sie unter Linktext

Robert MacLean
quelle
Versuchung auf -1 x: Bezieht sich auf einen anderen XML-Namespace, true, aber das ist eigentlich keine nützliche Antwort auf das Q, bei dem es darum geht, wann Sie keinen anderen verwenden müssen. : /
Tim Lovell-Smith
2

Eine der Antworten ist, dass x: name in verschiedenen Programmiersprachen wie c # verwendet werden soll und name für das Framework verwendet werden soll. Ehrlich gesagt klingt das für mich so.

Daddycardona
quelle
2

Der angegebene x: Name wird zum Namen eines Felds, das im zugrunde liegenden Code erstellt wird, wenn XAML verarbeitet wird, und dieses Feld enthält einen Verweis auf das Objekt. In Silverlight wird das Erstellen dieses Felds mithilfe der verwalteten API von den MSBuild-Zielschritten ausgeführt, die auch für das Zusammenführen der Teilklassen für eine XAML-Datei und deren CodeBehind verantwortlich sind. Dieses Verhalten ist nicht unbedingt in der XAML-Sprache angegeben. Es ist die spezielle Implementierung, die Silverlight für die Verwendung von x: Name in seinen Programmier- und Anwendungsmodellen anwendet .

Lesen Sie mehr über MSDN ...

Edd
quelle
2

Wenn Sie ein Button-Element in XAML deklarieren, beziehen Sie sich auf eine in der Windows-Laufzeit definierte Klasse namens Button.

Die Schaltfläche hat viele Attribute wie Hintergrund, Text, Rand, ..... und ein Attribut namens Name.

Wenn Sie jetzt eine Schaltfläche in XAML deklarieren, erstellen Sie ein anonymes Objekt, das zufällig ein Attribut namens Name hat.

Im Allgemeinen können Sie nicht auf ein anonymes Objekt verweisen, aber im WPF-Framework können Sie mit dem XAML-Prozessor auf dieses Objekt mit dem Wert verweisen, den Sie dem Attribut Name gegeben haben.

So weit, ist es gut.

Eine andere Möglichkeit, ein Objekt zu erstellen, besteht darin, ein benanntes Objekt anstelle eines anonymen Objekts zu erstellen. In diesem Fall hat der XAML-Namespace ein Attribut für ein Objekt namens Name (und da es sich im XAML-Namensraum befindet, haben Sie X :), das Sie festlegen können, damit Sie Ihr Objekt identifizieren und darauf verweisen können.

Fazit:

Name ist ein Attribut eines bestimmten Objekts, aber X: Name ist ein Attribut dieses Objekts (es gibt eine Klasse, die ein allgemeines Objekt definiert).

RockyMan Rocky
quelle
0

Meine Forschung ist x:Nameals globale Variable. Doch Nameals lokaler Variable. Bedeutet das x: Name, den Sie überall in Ihrer XAML-Datei aufrufen können, Name jedoch nicht.
Beispiel:

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

Sie können nicht BindingEigentum Contentvon Buttonmit Namen „BTN“ , weil es außerhalbStackPanel

Phuc Hoang
quelle