Di WPF, apa perbedaan antara atribut x: Name dan Name?

574

Judulnya mengatakan itu semua. Kadang-kadang tampaknya atribut Namedan x:Namedipertukarkan.

Jadi, apa perbedaan definitif di antara mereka, dan kapan lebih baik menggunakan yang satu dari yang lain?

Adakah implikasi kinerja atau memori untuk menggunakannya dengan cara yang salah?

Drew Noakes
sumber
Tanggapan menunjukkan bahwa menggunakan x:Namesemua waktu berfungsi dengan baik. Saya baru saja harus mengubahnya menjadi Namekalau tidak saya tidak bisa referensi kontrol dalam kode .xaml.cs saya jadi saya akan berasumsi bahwa itu tidak lagi berfungsi dengan baik sepanjang waktu.
Ortund
1
Mengenai kemunduran Anda, apa arti tambahan yang diberikan oleh frasa "judul mengatakan itu semua", Drew? Apakah itu tidak berlebihan? (Alasan saya untuk mengedit adalah bahwa saya cenderung mengecilkan frase pengisi percakapan - ini tidak lebih informatif daripada "Saya ingin tahu apakah Anda dapat membantu saya").
halfer

Jawaban:

481

Hanya ada satu nama di XAML, the x:Name. Kerangka kerja, seperti WPF, secara opsional dapat memetakan salah satu propertinya ke XAML x:Namedengan menggunakan RuntimeNamePropertyAttributeon the class yang menunjuk salah satu properti class sebagai pemetaan ke x: Atribut atribut XAML.

Alasan ini dilakukan adalah untuk memungkinkan kerangka kerja yang sudah memiliki konsep "Nama" saat runtime, seperti WPF. Di WPF, misalnya, FrameworkElementmemperkenalkan properti Name.

Secara umum, kelas tidak perlu menyimpan nama untuk x:Namedapat digunakan. Semua x:Namesarana untuk XAML adalah menghasilkan bidang untuk menyimpan nilai dalam kode di belakang kelas. Apa yang dilakukan runtime dengan pemetaan itu bergantung pada kerangka kerja.

Jadi, mengapa ada dua cara untuk melakukan hal yang sama? Jawaban sederhananya adalah karena ada dua konsep yang dipetakan pada satu properti. WPF menginginkan nama elemen yang disimpan pada saat runtime (yang dapat digunakan melalui Bind, antara lain) dan XAML perlu tahu elemen apa yang ingin diakses oleh bidang dalam kode di belakang kelas. WPF mengikat keduanya bersama-sama dengan menandai properti Name sebagai alias dari x: Name.

Di masa depan, XAML akan memiliki lebih banyak kegunaan untuk x: Nama, seperti memungkinkan Anda untuk mengatur properti dengan merujuk ke objek lain dengan nama, tetapi di 3.5 dan sebelumnya, itu hanya digunakan untuk membuat bidang.

Apakah Anda harus menggunakan satu atau yang lain benar-benar pertanyaan gaya, bukan yang teknis. Saya akan menyerahkan itu kepada orang lain untuk rekomendasi.

Lihat juga AutomationProperties.Name VS x: Name , AutomationProperties.Name digunakan oleh alat aksesibilitas dan beberapa alat pengujian.

chuckj
sumber
2
Dalam Visual Studio 2010 properti Nama diatur (bukan x: Nama) ketika Anda mengedit XAML melalui desainer. Tampaknya seolah-olah MS mendorong penggunaan Nama lebih dari x: Nama jadi saya kira itu adalah standar defacto.
Nebula
11
Saya tidak berpikir keduanya dapat dipertukarkan secara umum. Memberi nama kontrol pengguna diperlukan x:Namekarena Nametidak akan membuat bidang untuk dikenali di belakang kode. Saya masih tidak tahu mengapa ini terjadi.
Libor
5
Mereka bukan atau saya tidak bermaksud menyiratkan mereka melakukannya. Dalam WPF, jika suatu elemen memiliki Nameproperti itu artinya sama. Jika elemen tidak memiliki Nameproperti, Anda harus menggunakan x:Name.
chuckj
90

Mereka bukan hal yang sama.

x:Nameadalah konsep xaml, digunakan terutama untuk elemen referensi. Ketika Anda memberikan elemen atribut x: Name xaml, "ditentukan x:Namemenjadi nama bidang yang dibuat dalam kode yang mendasari ketika xaml diproses, dan bidang itu menyimpan referensi ke objek." ( MSDN ) Jadi, ini adalah bidang yang dibuat oleh desainer, yang memiliki akses internal secara default.

Nameadalah properti string yang ada dari FrameworkElement, terdaftar sebagai properti elemen WPF lainnya dalam bentuk atribut xaml.

Sebagai konsekuensinya, ini juga berarti x:Namedapat digunakan pada objek yang lebih luas. Ini adalah teknik untuk memungkinkan apa pun dalam xaml untuk dirujuk oleh nama yang diberikan.

Kenan EK
sumber
6
Jadi mengapa bisa Name atau x: Name digunakan dengan Binding.ElementName? Tampaknya atribut x: Name tidak hanya digunakan untuk memberi nama bidang dalam kode yang dihasilkan, tetapi juga tersedia dalam metadata saat runtime.
Drew Noakes
Ini adalah bidang yang dihasilkan seperti Nama bidang dalam properti Desain editor WinForms. Di sana Anda menempatkan nama dalam daftar properti dan itu menjadi nama bidang. Ini adalah perilaku yang sama. Tentu saja tersedia saat runtime karena merupakan bidang internal yang dikompilasi ke dalam kode di belakang. Binding.ElementName memeriksa kedua kasus, yaitu editor xaml "magic", x: Nama itu sendiri tidak ajaib.
Kenan EK
39

x: Nama dan Nama merujuk ruang nama yang berbeda.

x: name adalah referensi ke namespace x yang didefinisikan secara default di bagian atas file Xaml.

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

Hanya mengatakan Nama menggunakan namespace default di bawah ini.

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

x: Nama mengatakan gunakan namespace yang memiliki x alias. x adalah default dan kebanyakan orang membiarkannya tetapi Anda dapat mengubahnya ke apa pun yang Anda suka

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

jadi referensi Anda adalah foo: name

Tentukan dan Gunakan Ruang Nama di WPF


OK mari kita lihat ini dengan cara yang berbeda. Katakanlah Anda menarik dan melepas tombol ke halaman Xaml Anda. Anda dapat merujuk 2 cara ini x: nama dan nama . Semua xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" dan xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml" adalah referensi ke beberapa ruang nama . Karena xaml memegang Control namespace (tidak 100% dari itu) dan presentasi memegang FrameworkElement AND kelas Button memiliki pola pewarisan:

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

Jadi seperti yang diharapkan seseorang yang mewarisi dari FrameworkElement akan memiliki akses ke semua atribut publik. jadi dalam kasus Button, ia mendapatkan atribut Name dari FrameworkElement, di bagian paling atas hierarki pohon. Jadi Anda bisa mengatakan x: Nama atau Nama dan mereka berdua akan mengakses pengambil / penyetel dari FrameworkElement.

Referensi MSDN

WPF mendefinisikan atribut CLR yang dikonsumsi oleh prosesor XAML untuk memetakan beberapa ruang nama CLR ke ruang nama XML tunggal. The XmlnsDefinitionAttribute atribut ditempatkan di tingkat perakitan dalam kode sumber yang menghasilkan perakitan. Kode sumber perakitan WPF menggunakan atribut ini untuk memetakan berbagai ruang nama umum, seperti System.Windows dan System.Windows.Controls, ke http://schemas.microsoft.com/winfx/2006/xaml/presentation namespace.

Jadi atribut assembly akan terlihat seperti:

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
sumber
1
Saya tidak berpikir itu benar yang http://schemas.microsoft.com/winfx/2006/xamlberlaku Controlkarena Anda dapat menggunakannya secara langsung di XAML tanpa namespace 'x':<Control />
Drew Noakes
23

Keduanya sama, banyak elemen framework mengekspos properti nama sendiri, tetapi bagi mereka yang tidak dapat menggunakan x: name - Saya biasanya hanya menggunakan x: name karena itu berfungsi untuk semuanya.

Kontrol dapat mengekspos nama diri mereka sebagai Properti Ketergantungan jika mereka mau (karena mereka perlu menggunakan Properti Ketergantungan secara internal), atau mereka dapat memilih untuk tidak.

Lebih detail di msdn sini dan di sini :

Beberapa aplikasi tingkat kerangka WPF mungkin dapat menghindari penggunaan atribut x: Name, karena properti ketergantungan Nama seperti yang ditentukan dalam ruang nama WPF untuk beberapa kelas dasar yang penting seperti FrameworkElement / FrameworkContentElement memenuhi tujuan yang sama ini. Masih ada beberapa skenario XAML dan kerangka kerja umum di mana akses kode ke elemen tanpa properti Nama diperlukan, terutama di kelas dukungan animasi dan storyboard tertentu. Misalnya, Anda harus menentukan x: Nama pada garis waktu dan transformasi yang dibuat dalam XAML, jika Anda bermaksud untuk merujuknya dari kode.

Jika Nama tersedia sebagai properti di kelas, Nama dan x: Nama dapat digunakan secara bergantian sebagai atribut, tetapi kesalahan akan terjadi jika keduanya ditentukan pada elemen yang sama.

Steven Robbins
sumber
4
Jika tidak ada perbedaan, lalu mengapa ada dua cara untuk melakukan hal yang sama? Kedua cara tersebut ada dalam rilis pertama WPF.
Drew Noakes
@Steve, saya tidak mengecilkan jawaban apa pun atas pertanyaan ini, meskipun sejauh ini tidak ada yang sesuai.
Drew Noakes
Saya tidak melihat bagaimana jawaban yang tidak hanya memberi Anda jawaban, tetapi juga memberi Anda tautan ke MSDN untuk informasi lebih lanjut tentang topik yang tidak pantas? :-)
Steven Robbins
5
@Steve jawaban awal Anda tidak menjawab pertanyaan saya, karenanya komentar saya. Saya tidak mencari buta iman "lakukan dengan cara ini", tetapi jawaban yang wawasan yang menjelaskan mengapa ada dua cara, bahkan jika salah satu dari mereka memang bekerja sepanjang waktu. Benar secara teknis! = Tepat. Pembaruan Anda jauh lebih baik.
Drew Noakes
1
Hampir sama dengan jawaban di sini: wpfwiki.com/WPF%20Q16.4.ashx x: Nama memberi nama kontrol untuk digunakan dalam kode-belakang. Beberapa kelas akan menyediakan properti Nama untuk tujuan yang sama. Untuk kelas-kelas ini, tidak ada perbedaan antara x: nama dan nama.
Vegar
11

X: Nama dapat menyebabkan masalah memori jika Anda memiliki kontrol khusus. Ini akan menyimpan lokasi memori untuk entri NameScope.

Saya katakan tidak pernah menggunakan x: Nama kecuali Anda harus.

scott
sumber
Sepakat. Bekerja pada aplikasi kios yang memiliki banyak kebocoran memori dan resolusi tim pengembang sebelumnya hanya untuk memaksa reboot. Banyak kebocoran yang mudah diidentifikasi. Namun, setelah memperbaiki yang ditemukan melalui IntelliTrace dan JustTrace, beberapa referensi masih mengelak dari pengumpulan sampah implisit dan eksplisit. Saya membaca: support.scichart.com/index.php?/News/NewsItem/View/21/… Menemukan bahwa mengurangi x: Nama semakin meningkatkan kinerja.
MachinusX
2
Hal itu saya memahami ini mempengaruhi baik Nama dan x: Nama karena keduanya ditambahkan ke NameScope. Jika Anda membutuhkan Nama di elemen Anda, tidak ada cara untuk mengelilinginya. Anda dapat mem-repro kode pada elemen tanpa nama via FrameworkElement.RegisterName("elementname"). Namun, jika Anda memanggilnya FrameworkElement.UnregisterName("elementname")bisa "dereferenced".
Adam Caviness
8

Satu-satunya perbedaan adalah bahwa jika Anda menggunakan Kontrol pengguna ke dalam kontrol dari Same Assembly maka Name tidak akan mengidentifikasi kontrol Anda dan Anda akan mendapatkan kesalahan "Gunakan x: Nama untuk kontrol di Assembly yang sama". Jadi x: Nama adalah versi WPF dari kontrol penamaan di WPF. Nama hanya digunakan sebagai Warisan Winform. Mereka ingin membedakan penamaan kontrol di WPF dan winforms karena mereka menggunakan atribut di Xaml untuk mengidentifikasi kontrol dari majelis lain yang mereka gunakan x: untuk Nama kontrol.

Hanya perlu diingat jangan meletakkan nama untuk kontrol hanya demi menjaganya karena berada di memori sebagai kosong dan itu akan memberi Anda peringatan bahwa Nama telah diterapkan untuk kontrol tetapi tidak pernah digunakan.

Bipul Kumar
sumber
8

Nama :

  1. hanya dapat digunakan untuk keturunan FrameworkElement dan FrameworkContentElement;
  2. dapat diatur dari kode-belakang melalui SetValue () dan seperti properti.

x: Nama :

  1. dapat digunakan untuk hampir semua elemen XAML;
  2. TIDAK dapat diatur dari kode-belakang melalui SetValue (); itu hanya dapat diatur menggunakan sintaks atribut pada objek karena itu adalah arahan.

Menggunakan kedua arahan dalam XAML untuk satu FrameworkElement atau FrameworkContentElement akan menyebabkan pengecualian: jika XAML dikompilasi markup, pengecualian akan terjadi pada kompilasi markup, jika tidak itu terjadi pada beban.

Oleksandr Zolotarov
sumber
7

x:Name berarti: membuat bidang dalam kode di belakang untuk menyimpan referensi ke objek ini.

Name berarti: mengatur properti nama objek ini.

itzmebibin
sumber
Ini tidak sepenuhnya benar; keduanya dapat diakses dari codebehind, tetapi yang cukup menarik hanya nama x: yang dapat diperbarui saat runtime. Pedas.
4

Saya selalu menggunakan varian x: Name. Saya tidak tahu apakah ini mempengaruhi kinerja apa pun, saya merasa lebih mudah karena alasan berikut. Jika Anda memiliki kontrol pengguna Anda sendiri yang berada di majelis lain hanya properti "Nama" tidak akan selalu cukup. Ini membuatnya lebih mudah untuk hanya menempelkan properti x: Name.

Simon
sumber
4
Jika tidak ada perbedaan, lalu mengapa ada dua cara untuk melakukan hal yang sama? Kedua cara tersebut ada dalam rilis pertama WPF.
Drew Noakes
3

Ini bukan item WPF tetapi XML standar dan BtBh telah menjawabnya dengan benar, x merujuk ke namespace default. Dalam XML ketika Anda tidak awalan elemen / atribut dengan namespace itu mengasumsikan Anda menginginkan namespace default. Jadi mengetik saja Nametidak lebih dari sekadar pekerjaan singkat x:Name. Rincian lebih lanjut tentang ruang nama XML dapat ditemukan di teks tautan

Robert MacLean
sumber
Tergoda untuk -1 x: merujuk ke namespace XML yang berbeda, benar, tetapi itu sebenarnya bukan jawaban yang berguna untuk Q yang adalah tentang kapan Anda perlu atau tidak menggunakan yang lain. : /
Tim Lovell-Smith
2

Salah satu jawabannya adalah bahwa nama x: akan digunakan dalam berbagai bahasa program seperti c # dan nama yang akan digunakan untuk kerangka kerja. Jujur itu seperti apa bagiku.

daddycardona
sumber
2

X yang ditentukan : Nama menjadi nama bidang yang dibuat dalam kode yang mendasari ketika XAML diproses, dan bidang itu menyimpan referensi ke objek. Di Silverlight, menggunakan API yang dikelola, proses pembuatan bidang ini dilakukan oleh langkah-langkah target MSBuild, yang juga bertanggung jawab untuk bergabung dengan kelas parsial untuk file XAML dan kode-belakangnya. Perilaku ini tidak harus ditentukan dalam bahasa XAML; itu adalah implementasi khusus yang Silverlight terapkan untuk menggunakan x: Nama dalam model pemrograman dan aplikasinya.

Baca Lebih Lanjut tentang MSDN ...

Edd
sumber
2

Ketika Anda mendeklarasikan elemen Button di XAML Anda merujuk ke kelas yang didefinisikan dalam windows run time yang disebut Button.

Tombol memiliki banyak atribut seperti latar belakang, teks, margin, ..... dan atribut yang disebut Nama.

Sekarang ketika Anda mendeklarasikan Tombol di XAML adalah seperti membuat objek anonim yang kebetulan memiliki atribut bernama Nama.

Secara umum Anda tidak bisa merujuk ke objek anonim, tetapi dalam kerangka kerja WPF XAML prosesor memungkinkan Anda untuk merujuk ke objek tersebut dengan nilai apa pun yang Anda berikan ke atribut Name.

Sejauh ini bagus.

Cara lain untuk membuat objek adalah membuat objek bernama bukan objek anonim. Dalam hal ini namespace XAML memiliki atribut untuk objek bernama Name (dan karena itu ada dalam ruang nama XAML maka punya X :) yang dapat Anda atur sehingga Anda dapat mengidentifikasi objek Anda dan merujuknya.

Kesimpulan:

Nama adalah atribut dari objek tertentu, tetapi X: Nama adalah salah satu atribut dari objek itu (ada kelas yang mendefinisikan objek umum).

Rocky Man Rocky
sumber
0

Penelitian saya adalah x:Namesebagai variabel global . Namun, Namesebagai variabel lokal . Apakah itu berarti x: Nama yang dapat Anda panggil di mana saja di file XAML Anda tetapi Name tidak.
Contoh:

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

Anda tidak bisa Bindingproperti Contentdari Buttondengan Nama adalah "btn" karena di luarStackPanel

Phuc Hoang
sumber