In WPF, quali sono le differenze tra gli attributi x: Name e Name?


574

Il titolo dice tutto. A volte sembra che gli attributi Namee x:Namesiano intercambiabili.

Quindi, quali sono le differenze definitive tra loro e quando è preferibile usarne uno rispetto all'altro?

Ci sono implicazioni in termini di prestazioni o memoria nell'usarli nel modo sbagliato?


Le risposte suggeriscono che usare x:Nametutto il tempo funziona bene. Ho appena dovuto cambiarlo in Namealtrimenti non potrei fare riferimento al controllo nel mio codice .xaml.cs, quindi suppongo che non è più il caso che funzioni sempre bene.
Ortund,

1
Per quanto riguarda il tuo rollback, quale significato extra è dato dalla frase "il titolo dice tutto", Drew? Non è ridondante? (La mia ragione per l'editing è che tendo a scoraggiare le frasi di riempimento della conversazione - questo non è più informativo di "Mi chiedo se puoi aiutarmi").
halfer

Risposte:


481

C'è davvero solo un nome in XAML, il x:Name. Un framework, come WPF, può facoltativamente mappare una delle sue proprietà su XAML x:Nameusando RuntimeNamePropertyAttributela classe on che designa una delle proprietà della classe come mappatura all'attributo x: Name di XAML.

Il motivo è stato quello di consentire framework che hanno già un concetto di "Nome" in fase di runtime, come WPF. In WPF, ad esempio, FrameworkElementintroduce una proprietà Name.

In generale, una classe non ha bisogno di memorizzare il nome per x:Nameessere utilizzabile. Tutti i x:Namemezzi per XAML sono generare un campo per memorizzare il valore nel codice dietro la classe. Ciò che il runtime fa con quel mapping dipende dal framework.

Quindi, perché ci sono due modi per fare la stessa cosa? La risposta semplice è perché ci sono due concetti mappati su una proprietà. WPF vuole il nome di un elemento conservato in fase di runtime (che è utilizzabile tramite Bind, tra le altre cose) e XAML deve sapere quali elementi si desidera siano accessibili dai campi nel codice dietro la classe. WPF lega questi due elementi contrassegnando la proprietà Name come alias di x: Name.

In futuro, XAML avrà più usi per x: Name, come consentire di impostare proprietà facendo riferimento ad altri oggetti per nome, ma in 3.5 e precedenti, viene utilizzato solo per creare campi.

Se dovresti usare l'uno o l'altro è davvero una domanda di stile, non tecnica. Lo lascerò ad altri per una raccomandazione.

Vedi anche AutomationProperties.Name VS x: Name , AutomationProperties.Name viene utilizzato dagli strumenti di accessibilità e da alcuni strumenti di test.


2
In Visual Studio 2010 la proprietà Name viene impostata (non x: Name) quando si modifica XAML tramite la finestra di progettazione. Sembra che MS incoraggi l'uso di Name over x: Name, quindi immagino che sia lo standard defacto.
Nebulosa,

11
Non penso che i due siano intercambiabili in generale. I nomi dei controlli utente richiedono x:Nameperché Namenon creerebbero un campo da riconoscere in code-behind. Non so ancora perché questo accada, comunque.
Libor,

5
Non sono né intendevo implicare che lo facessero. In WPF, se un elemento ha una Nameproprietà, significa la stessa cosa. Se l'elemento non ha una Nameproprietà, è necessario utilizzare x:Name.
Chuckj,

90

Non sono la stessa cosa.

x:Nameè un concetto xaml, utilizzato principalmente per fare riferimento a elementi. Quando si assegna a un elemento l'attributo x: Name xaml, "lo specificato x:Namediventa il nome di un campo che viene creato nel codice sottostante quando viene elaborato xaml e quel campo contiene un riferimento all'oggetto". ( MSDN ) Quindi, è un campo generato dal designer, che ha accesso interno per impostazione predefinita.

Nameè la proprietà stringa esistente di a FrameworkElement, elencata come qualsiasi altra proprietà dell'elemento wpf nella forma di un attributo xaml.

Di conseguenza, questo significa anche che x:Namepuò essere utilizzato su una gamma più ampia di oggetti. Questa è una tecnica per consentire a qualsiasi cosa in xaml di essere referenziata da un determinato nome.


6
Quindi perché è possibile utilizzare Nome o x: Nome con Binding.ElementName? Sembra che l'attributo x: Name non sia usato solo per nominare un campo nel codice generato, ma è anche disponibile nei metadati in fase di esecuzione.
Drew Noakes,

È un campo generato come il campo Nome nelle proprietà di progettazione dell'editor WinForms. Lì si inserisce un nome nell'elenco delle proprietà e diventa il nome di un campo. Questo è lo stesso comportamento. Naturalmente è disponibile in fase di esecuzione poiché è un campo interno compilato nel codice sottostante. Binding.ElementName controlla per entrambi i casi, ovvero l'editor "magico" di xaml, il nome x: non è magico in sé.
Kenan EK,

39

x: Nome e Nome fanno riferimento a spazi dei nomi diversi.

x: name è un riferimento allo spazio dei nomi x definito per impostazione predefinita nella parte superiore del file Xaml.

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

Solo dicendo Name usa il namespace sottostante predefinito.

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

x: il nome dice usa lo spazio dei nomi che ha l' alias x . x è l'impostazione predefinita e la maggior parte delle persone lo lascia, ma puoi cambiarlo come preferisci

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

quindi il tuo riferimento sarebbe foo: nome

Definisci e usa gli spazi dei nomi in WPF


OK, vediamo questo in un modo diverso. Supponi di trascinare e rilasciare un pulsante sulla tua pagina Xaml. Puoi fare riferimento a questo 2 modi x: nome e nome . Tutti xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" e xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml" sono riferimenti a più spazi dei nomi . Poiché xaml contiene lo spazio dei nomi Control (non al 100% su quello) e la presentazione contiene FrameworkElement AND la classe Button ha un modello di ereditarietà di:

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

Quindi, come ci si aspetterebbe che tutto ciò che eredita da FrameworkElement avrebbe accesso a tutti i suoi attributi pubblici. quindi nel caso di Button sta ottenendo il suo attributo Name da FrameworkElement, nella parte superiore dell'albero della gerarchia. Quindi puoi dire x: Name o Name e entrambi accederanno al getter / setter da FrameworkElement.

Riferimento MSDN

WPF definisce un attributo CLR che viene utilizzato dai processori XAML per mappare più spazi dei nomi CLR su un singolo spazio dei nomi XML. L' attributo XmlnsDefinitionAttribute viene posizionato a livello di assembly nel codice sorgente che produce l'assembly. Il codice sorgente dell'assembly WPF utilizza questo attributo per mappare i vari spazi dei nomi comuni, come System.Windows e System.Windows.Controls, allo spazio dei nomi http://schemas.microsoft.com/winfx/2006/xaml/presentation .

Quindi gli attributi dell'assembly saranno simili a:

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
Non credo che sia vero che http://schemas.microsoft.com/winfx/2006/xamldetiene Controldal momento che è possibile utilizzare direttamente in XAML, senza una 'x' namespace:<Control />
Drew Noakes

23

Sono entrambi la stessa cosa, molti elementi del framework espongono loro stessi una proprietà name, ma per quelli che non lo fanno puoi usare x: name - di solito mi attengo solo a x: name perché funziona per tutto.

I controlli possono esporre i nomi stessi come proprietà di dipendenza se lo desiderano (perché devono utilizzare quella proprietà di dipendenza internamente), oppure possono scegliere di non farlo.

Maggiori dettagli in msdn qui e qui :

Alcune applicazioni a livello di framework WPF potrebbero essere in grado di evitare qualsiasi utilizzo dell'attributo x: Name, poiché la proprietà di dipendenza Name come specificata nello spazio dei nomi WPF per diverse importanti classi di base come FrameworkElement / FrameworkContentElement soddisfa questo stesso scopo. Esistono ancora alcuni scenari XAML e framework comuni in cui è necessario l'accesso al codice a un elemento senza proprietà Name, in particolare in determinate classi di supporto di storyboard e animazioni. Ad esempio, è necessario specificare x: Name su timeline e trasformazioni create in XAML, se si intende fare riferimento a loro dal codice.

Se Nome è disponibile come proprietà sulla classe, Nome e x: Nome possono essere usati in modo intercambiabile come attributi, ma si verificherà un errore se entrambi sono specificati sullo stesso elemento.


4
Se non c'è differenza, allora perché ci dovrebbero essere due modi per fare la stessa cosa? Entrambi i modi esistevano nella prima versione di WPF.
Drew Noakes,

@Sveve, non ho votato a fondo nessuna delle risposte a questa domanda, anche se finora nessuna di esse è stata molto appropriata.
Drew Noakes,

Non vedo come una risposta che non solo ti dia la risposta, ma ti dia anche collegamenti a MSDN per ulteriori informazioni sull'argomento non è appropriata? :-)
Steven Robbins,

5
@Steve la tua risposta originale non ha risposto alla mia domanda, quindi al mio commento. Non sto cercando la fede cieca "fallo in questo modo", ma piuttosto una risposta perspicace che spiega perché esistono due modi, anche se uno di loro funziona sempre. Tecnicamente corretto! = Appropriato. Il tuo aggiornamento è molto meglio.
Drew Noakes,

1
Più o meno la stessa risposta qui: wpfwiki.com/WPF%20Q16.4.ashx x: Nome sta assegnando al controllo un nome da usare in code-behind. Alcune classi forniranno una proprietà Name per lo stesso scopo. Per queste classi, non c'è differenza tra x: name e name.
Vegar,

11

X: Il nome può causare problemi di memoria se si dispone di controlli personalizzati. Manterrà una posizione di memoria per la voce NameScope.

Dico di non usare mai x: Name a meno che non sia necessario.


Concordato. Ha lavorato su un'app kiosk che presentava numerose perdite di memoria e la risoluzione del precedente team di sviluppo era solo quella di forzare un riavvio. Gran parte delle perdite sono state facilmente identificate. Tuttavia, dopo aver corretto quelli trovati tramite IntelliTrace e JustTrace, alcuni ref hanno ancora eluso la raccolta dei rifiuti implicita ed esplicita. Ho letto: support.scichart.com/index.php?/News/NewsItem/View/21/… Ho scoperto che la riduzione di x: Name migliora ulteriormente le prestazioni.
MachinusX,

2
Comprendo che ciò influisce sia su Nome che su x: Nome poiché entrambi vengono aggiunti a NameScope. Se hai bisogno di un nome sul tuo elemento, non c'è modo di aggirarlo. Puoi riprogrammare il codice su un elemento senza nome tramite FrameworkElement.RegisterName("elementname"). Tuttavia, se lo chiami FrameworkElement.UnregisterName("elementname"), può essere "dereferenziato".
Adam Caviness,

8

L'unica differenza è che se si utilizzano i controlli utente in un controllo dallo stesso assieme, il nome non identificherà il controllo e verrà visualizzato un errore "Utilizzare x: nome per i controlli nello stesso assieme". Quindi x: Name è il versioning WPF dei controlli di denominazione in WPF. Il nome viene usato solo come eredità di Winform. Volevano differenziare la denominazione dei controlli in WPF e winforms mentre usano gli attributi in Xaml per identificare i controlli da altri assembly che hanno usato x: per Names of control.

Tieni solo a mente che non inserire un nome per un controllo solo per il gusto di mantenerlo in quanto risiede in memoria come vuoto e ti avvertirà che il nome è stato applicato per un controllo ma non è mai stato usato.


8

Nome :

  1. può essere utilizzato solo per i discendenti di FrameworkElement e FrameworkContentElement;
  2. può essere impostato da code-behind tramite SetValue () e simile a proprietà.

x: Nome :

  1. può essere usato per quasi tutti gli elementi XAML;
  2. NON può essere impostato da code-behind tramite SetValue (); può essere impostato solo usando la sintassi dell'attributo sugli oggetti perché è una direttiva.

L'uso di entrambe le direttive in XAML per un FrameworkElement o FrameworkContentElement provocherà un'eccezione: se XAML è compilato con markup, l'eccezione si verificherà nella compilazione con markup, altrimenti si verificherà nel caricamento.


7

x:Name significa: creare un campo nel codice dietro per contenere un riferimento a questo oggetto.

Name significa: imposta la proprietà name di questo oggetto.


Questo non è del tutto vero; entrambi sono accessibili dal codebehind, ma abbastanza interessante solo il x: Name può essere aggiornato in fase di esecuzione. Nutty.

4

Uso sempre la variante x: Name. Non ho idea se questo influisce su qualsiasi prestazione, lo trovo più semplice per il seguente motivo. Se hai i tuoi controlli utente che risiedono in un altro assembly, la proprietà "Nome" non sarà sempre sufficiente. Ciò semplifica anche il solo incollamento della proprietà x: Name.


4
Se non c'è differenza, allora perché ci dovrebbero essere due modi per fare la stessa cosa? Entrambi i modi esistevano nella prima versione di WPF.
Drew Noakes,

3

Non è un oggetto WPF ma uno XML standard e BtBh ha risposto correttamente, x si riferisce allo spazio dei nomi predefinito. In XML quando non si antepone un elemento / attributo con uno spazio dei nomi, si presuppone che si desideri lo spazio dei nomi predefinito. Quindi digitare non Nameè altro che una scorciatoia per x:Name. Maggiori dettagli sugli spazi dei nomi XML sono disponibili nel testo del link


Tentato a -1 x: si riferisce a un diverso spazio dei nomi XML, vero, ma questa non è in realtà una risposta utile alla Q che riguarda quando hai bisogno di usare l'uno o l'altro. : /
Tim Lovell-Smith,

2

Una delle risposte è che x: name deve essere utilizzato in diversi linguaggi di programma come c # e name deve essere usato per il framework. Onestamente questo è quello che sembra per me.


2

Il nome x: specificato diventa il nome di un campo che viene creato nel codice sottostante quando viene elaborato XAML e quel campo contiene un riferimento all'oggetto. In Silverlight, utilizzando l'API gestita, il processo di creazione di questo campo viene eseguito dai passaggi di destinazione di MSBuild, che sono anche responsabili dell'unione delle classi parziali per un file XAML e il suo code-behind. Questo comportamento non è necessariamente specificato nel linguaggio XAML; è l'implementazione particolare che Silverlight applica per usare x: Name nei suoi modelli di programmazione e applicazione.

Maggiori informazioni su MSDN ...


2

Quando si dichiara un elemento Button in XAML, ci si riferisce a una classe definita in fase di esecuzione di Windows chiamata Button.

Il pulsante ha molti attributi come sfondo, testo, margine, ..... e un attributo chiamato Nome.

Ora quando si dichiara un pulsante in XAML è come creare un oggetto anonimo che ha avuto un attributo chiamato Nome.

In generale, non è possibile fare riferimento a un oggetto anonimo, ma nel framework WPF il processore XAML consente di fare riferimento a tale oggetto in base al valore assegnato all'attributo Nome.

Fin qui tutto bene.

Un altro modo per creare un oggetto è creare un oggetto denominato anziché un oggetto anonimo. In questo caso lo spazio dei nomi XAML ha un attributo per un oggetto chiamato Nome (e poiché è nello spazio dei nomi XAML, è quindi possibile impostare X :) in modo da poter identificare l'oggetto e fare riferimento ad esso.

Conclusione:

Nome è un attributo di un oggetto specifico, ma X: Nome è un attributo di quell'oggetto (esiste una classe che definisce un oggetto generale).


0

La mia ricerca è x:Namecome variabile globale . Tuttavia, Namecome variabile locale . Significa x: Nome, puoi chiamarlo ovunque nel tuo file XAML ma Nome non lo è.
Esempio:

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

Non puoi avere Bindingproprietà Contentdi Buttoncon Nome è "btn" perché è esternoStackPanel

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.