2009-02-26 11 views
476

Il titolo dice tutto. A volte sembra che gli attributi Name e x:Name siano intercambiabili.In WPF, quali sono le differenze tra gli attributi x: Name e Name?

Quindi, quali sono le differenze definitive tra di loro e quando è preferibile utilizzare l'una sull'altra?

Ci sono delle prestazioni o delle implicazioni di memoria nell'usarle nel modo sbagliato?

EDIT Le risposte finora suggeriscono che l'utilizzo di x:Name tutto il tempo funzioni bene, ma voglio ancora sapere qual è la differenza. Microsoft ha inserito questi due attributi nella primissima versione di WPF, quindi deve esserci una spiegazione ragionevole.

+0

Le risposte suggeriscono che l'uso di 'x: Name' tutto il tempo funziona correttamente. Ho appena dovuto cambiarlo in 'Name' altrimenti non potrei fare riferimento al controllo nel mio codice .xaml.cs, quindi presumo che non funzioni più tutto il tempo. – Ortund

risposta

420

In XAML esiste davvero un solo nome, lo x:Name. Un framework, come WPF, può opzionalmente mappare una delle sue proprietà a x:Name di XAML utilizzando lo RuntimeNamePropertyAttribute sulla classe che designa una delle proprietà delle classi come associazione all'attributo x: Name di XAML.

Il motivo per cui questo è stato fatto è stato quello di consentire i framework che hanno già un concetto di "Nome" in fase di runtime, come WPF. In WPF, ad esempio, FrameworkElement introduce una proprietà Name.

In generale, una classe non ha bisogno di memorizzare il nome per x:Name per essere utilizzabile. Tutto x:Name significa che XAML è generare un campo per memorizzare il valore nel codice dietro la classe. Ciò che il runtime fa con quella mappatura 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 esecuzione (che è utilizzabile tramite Bind, tra le altre cose) e XAML ha bisogno di sapere quali elementi si desidera essere accessibili dai campi nel codice della 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 ad esempio consentire di impostare le proprietà facendo riferimento ad altri oggetti per nome, ma in 3.5 e precedenti, è usato solo per creare campi.

Se si dovrebbe usare l'una o l'altra è davvero una domanda di stile, non tecnica. Lo lascerò agli altri per una raccomandazione.

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

+2

In Visual Studio 2010 la proprietà Name è impostata (non x: Name) quando si modifica XAML tramite il designer. Sembra che MS incoraggi l'uso di Name su x: Name quindi suppongo che sia lo standard defacto. – Nebula

+7

Non penso che i due siano intercambiabili in generale. La denominazione dei controlli utente richiede 'x: Name' perché' Name' non creerebbe un campo da riconoscere nel code-behind. Non so ancora perché questo accada, però. – Libor

+3

Non sono né volevo dire che lo hanno fatto. In WPF, se un elemento ha una proprietà 'Name' significa la stessa cosa. Se l'elemento non ha una proprietà 'Name', devi usare' x: Name'. – chuckj

5

Uso sempre la variante x: Name. Non ho idea se questo influisce sulle prestazioni, trovo che sia più semplice per il seguente motivo. Se i propri comandi utente che risiedono in un altro assieme, la proprietà "Nome" non sempre è sufficiente. Ciò rende più semplice attaccare anche la proprietà x: Name.

+4

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

17

Sono entrambi la stessa cosa, molti elementi di framework espongono direttamente una proprietà di nome, ma per quelli che non è possibile usare x: name - di solito rimango con x: name perché funziona per tutto .

I controlli possono esporre il nome stesso come DP se lo desiderano (poiché devono utilizzare tale DP internamente) oppure possono scegliere di non farlo.

Maggiori dettagli in MSDN here e here:

Alcune applicazioni di livello quadro WPF potrebbe essere in grado di evitare qualsiasi uso delle x: attributo Name, perché la proprietà di dipendenza Nome come specificato all'interno lo spazio dei nomi WPF per più delle importanti classi di base come FrameworkElement/FrameworkContentElement soddisfa lo stesso scopo. Ci sono ancora un po ' XAML comuni e un quadro scenari in cui il codice di accesso ad un elemento senza proprietà Name è necessarie, in particolare in alcuni animazione e di sostegno storyboard classi. Ad esempio, è necessario specificare x: Nome sulle timeline e le trasformazioni create in XAML, se si desidera fare riferimento a tali codici dal codice con .

Se Name è disponibile come una proprietà su classe, Nome e x: Name può essere usato in modo intercambiabile come attributi, ma un errore risulterà se entrambi sono specificato sullo stesso elemento.

+3

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

+0

Lol, hai votato tutte le risposte? –

+0

@Steve, non ho minimizzato nessuna delle risposte a questa domanda, anche se nessuna di esse finora è stata molto appropriata. –

27

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

x: nome è 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" 

Basta dire Nome utilizza il valore predefinito di sotto dello spazio dei nomi.

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

x: Name sta dicendo utilizzare lo spazio dei nomi che ha l'alias x. x è il valore predefinito e la maggior parte delle persone lasciano, ma si può cambiare a tutto ciò che ti piace

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

in modo che il riferimento sarebbe foo: nome

Define and Use Namespaces in WPF

EDIT:

OK consente di guardare questo in un modo diverso. Supponi di trascinare un pulsante sulla tua pagina Xaml. È possibile 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ù domini. Dal momento che XAML detiene il controllo namespace (non al 100% su questo) e presentazione detiene il FrameworkElement e la classe pulsante ha un modello di ereditarietà di:

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

Così come ci si aspetterebbe tutto ciò che eredita da FrameworkElement avrebbe accesso a tutti i suoi attributi pubblici. quindi nel caso di Button ottiene l'attributo Name da FrameworkElement, nella parte superiore dell'albero gerarchico. Quindi è possibile dire x: Nome o Nome e entrambi accederanno al getter/setter da FrameworkElement.

MSDN Reference

WPF definisce un attributo CLR che viene consumata dai processori XAML al fine di mappare più spazi dei nomi CLR a un unico namespace XML. L'attributo XmlnsDefinitionAttribute viene inserito 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.

Così gli attributi di assemblaggio avranno un aspetto simile:

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

Non penso sia vero che 'http: // schemas.microsoft.com/winfx/2006/xaml' contiene' Control' dato che puoi usarlo direttamente in XAML senza uno spazio dei nomi 'x': '' –

3

Non è un elemento WPF, ma un XML standard e uno BtBh ha correttamente risposto, x si riferisce a lo spazio dei nomi predefinito. In XML quando non si prefissa un elemento/attributo con uno spazio dei nomi, si presuppone che si desideri lo spazio dei nomi predefinito. Quindi digitare solo Name non è altro che una breve mano per x:Name. Maggiori dettagli sugli spazi dei nomi XML sono disponibili su link text

+0

Tempted a -1 x: si riferisce a un diverso spazio dei nomi XML, vero, ma in realtà non è una risposta utile alla Q che riguarda quando è necessario utilizzare l'altro no. :/ –

66

Non sono la stessa cosa.

x:Name è un concetto xaml, utilizzato principalmente per gli elementi di riferimento. Quando assegni a un elemento l'attributo x: Name xaml, "lo x:Name specificato diventa il nome di un campo che viene creato nel codice sottostante quando xaml viene elaborato 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à di stringa esistente di un FrameworkElement, elencata come qualsiasi altra proprietà di elemento wpf sotto forma di un attributo xaml.

Di conseguenza, questo significa anche che x:Name può essere utilizzato su una gamma più ampia di oggetti. Questa è una tecnica per abilitare qualsiasi cosa in xaml a cui fare riferimento con un nome specifico.

+4

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 che sia anche disponibile nei metadati in fase di runtime. –

+0

È un campo generato come il campo Nome nelle proprietà Design dell'editor WinForms. Lì si inserisce un nome nell'elenco delle proprietà e diventa il nome di un campo. Questo è lo stesso comportamento. Ovviamente è disponibile in runtime poiché è un campo interno compilato nel codice sottostante. Binding.ElementName verifica per entrambi i casi, cioè l'editor xaml "magic", la x: Name non è magica in sé. –

9

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

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

+0

concordato. Ho lavorato su un'app kiosk che ha avuto numerose perdite di memoria e la risoluzione del team di sviluppo precedente era solo per forzare un riavvio. Molte delle perdite sono state facilmente identificate. Tuttavia, dopo aver sistemato quelli trovati tramite IntelliTrace e JustTrace, alcuni ref sono ancora sfuggiti alla garbage collection esplicita ed esplicita. Ho letto: http://support.scichart.com/index.php?/ Notizie/NewsItem/Visualizza/21/wpf-xname-memory-leak - how-to-clear-memory-in-scichart Trovato che riducendo x: nome prestazioni ulteriormente migliorate. – MachinusX

+0

A mio avviso ciò influisce su _both_ ** Nome ** e ** x: Nome ** in quanto entrambi vengono aggiunti a NameScope. Se hai bisogno di un nome sul tuo elemento, non c'è modo di aggirarlo. È possibile effettuare la riproduzione di codice su un elemento senza nome tramite ['FrameworkElement.RegisterName (" elementname ")'] (https://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.registername (v = vs.110) aspx). Tuttavia, se si chiama ['FrameworkElement.UnregisterName (" elementname ")'] (https://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.unregistername (v = vs.110) .aspx) può essere "dereferenziato". –

7

L'unica differenza è che se si utilizzano i controlli utente in un controllo da Stesso assieme, Nome non identificherà il proprio controllo e si riceverà un errore "Usa x: Nome per i controlli nello stesso assieme". Quindi x: Name è la versione WPF dei controlli di denominazione in WPF. Il nome è appena usato come eredità Winform.Volevano differenziare la denominazione dei controlli in WPF e Winforms mentre utilizzavano attributi in Xaml per identificare i controlli da altri assiemi utilizzati x: per i nomi di controllo.

Basta tenere a mente non mettere un nome per un controllo solo per il gusto di tenerlo in quanto risiede in memoria come uno spazio vuoto e ti darà un avviso che Nome è stato applicato per un controllo ma non è mai stato utilizzato.

7

Nome:

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

x: Name:

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

Con entrambe le direttive XAML per un FrameworkElement o FrameworkContentElement causerà un'eccezione: se il XAML è markup compilato, l'eccezione si verifica nella compilazione markup, mentre avviene il carico.

2

Una delle risposte è che x: nome deve essere utilizzato all'interno di diversi linguaggi di programmazione come C# e il nome deve essere utilizzato per il framework. Onestamente questo è quello che sembra per me.

5

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

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

+0

Questo non è del tutto vero; entrambi sono accessibili da codebehind, ma è interessante notare che solo x: Name può essere aggiornato in fase di runtime. Nutty. – Will

1

Il valore specificato x: nome diventa il nome di un campo creato nel codice sottostante quando XAML viene elaborato e tale campo contiene un riferimento all'oggetto. In Silverlight, utilizzando l'API gestita, il processo di creazione di questo campo viene eseguito dai passi di destinazione di MSBuild, che sono anche responsabili dell'adesione alle classi parziali per un file XAML e al suo code-behind. Questo comportamento non è necessariamente specificato nella lingua XAML; è la particolare implementazione che Silverlight applica per utilizzare x: Nome nei suoi modelli di programmazione e applicazione.

Read More on MSDN...

2

Quando si dichiara un elemento pulsante in XAML ci si riferisce a una classe definita in finestre di tempo di esecuzione chiamato 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 un attributo chiamato Nome.

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

Fin qui tutto bene.

Un altro modo per creare un oggetto è creare un oggetto con nome anziché un oggetto anonimo. In questo caso lo spazio dei nomi XAML ha un attributo per un oggetto chiamato Nome (e dato che è nello spazio dei nomi XAML quindi X :) che puoi impostare in modo da poter identificare il tuo oggetto e fare riferimento ad esso.

Conclusione:

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

Problemi correlati