Saya memiliki satu set kontrol dengan perintah dan logika terlampir yang terus digunakan kembali dengan cara yang sama. Saya memutuskan untuk membuat kontrol pengguna yang menampung semua kontrol dan logika umum.
Namun saya juga membutuhkan kontrol untuk dapat menyimpan konten yang dapat diberi nama. Saya mencoba yang berikut ini:
<UserControl.ContentTemplate>
<DataTemplate>
<Button>a reused button</Button>
<ContentPresenter Content="{TemplateBinding Content}"/>
<Button>a reused button</Button>
</DataTemplate>
</UserControl.ContentTemplate>
Namun tampaknya konten apa pun yang ditempatkan di dalam kendali pengguna tidak dapat dinamai. Misalnya jika saya menggunakan kontrol dengan cara berikut:
<lib:UserControl1>
<Button Name="buttonName">content</Button>
</lib:UserControl1>
Saya menerima kesalahan berikut:
Tidak dapat menyetel nilai atribut Nama 'buttonName' pada elemen 'Tombol'. 'Tombol' berada di bawah cakupan elemen 'UserControl1', yang sudah memiliki nama yang terdaftar saat didefinisikan dalam cakupan lain.
Jika saya menghapus buttonName, maka akan terkompilasi, namun saya harus dapat menamai konten tersebut. Bagaimana saya bisa mencapai ini?
Jawaban:
Jawabannya adalah tidak menggunakan UserControl untuk melakukannya.
Buat kelas yang memperluas ContentControl
lalu gunakan gaya untuk menentukan isinya
dan terakhir - gunakan
sumber
UserControl
menjadi mewarisiContentControl
. Untuk mengatasinya, cukup tambahkan Kelas baru ( bukan XAML dengan CS). Dan kemudian itu akan (semoga) berhasil. jika Anda suka, saya telah membuat solusi VS2010HeadingContainer
danMyFunkyContainer
dimaksudkan untuk menjadiMyFunkyControl
?!Sepertinya ini tidak mungkin ketika XAML digunakan. Kontrol khusus tampaknya berlebihan ketika saya benar-benar memiliki semua kontrol yang saya butuhkan, tetapi hanya perlu mengelompokkannya bersama dengan sedikit logika dan mengizinkan konten bernama.
Solusi di blog JD seperti yang disarankan mackenir, tampaknya memiliki kompromi terbaik. Cara untuk memperluas solusi JD untuk memungkinkan kontrol tetap didefinisikan di XAML adalah sebagai berikut:
Dalam contoh saya di atas, saya telah membuat kontrol pengguna yang disebut UserControlDefinedInXAML yang didefinisikan seperti kontrol pengguna biasa menggunakan XAML. Di UserControlDefinedInXAML saya, saya memiliki StackPanel yang disebut aStackPanel di mana saya ingin konten bernama saya muncul.
sumber
Alternatif lain yang saya gunakan adalah mengatur
Name
properti diLoaded
acara tersebut.Dalam kasus saya, saya memiliki kontrol yang agak rumit yang tidak ingin saya buat di belakang kode, dan mencari kontrol opsional dengan nama tertentu untuk perilaku tertentu, dan karena saya perhatikan saya dapat menetapkan nama di
DataTemplate
Saya pikir saya bisa melakukannya diLoaded
acara itu juga.sumber
Terkadang Anda mungkin hanya perlu mereferensikan elemen dari C #. Bergantung pada kasus penggunaan, Anda kemudian dapat menyetel dan
x:Uid
bukannyax:Name
dan mengakses elemen dengan memanggil metode pencari Uid seperti Get object by-nya Uid di WPF .sumber
Anda dapat menggunakan helper ini untuk mengatur nama di dalam kontrol pengguna:
dan Window atau Control Code Behind Anda mengatur kontrol Anda berdasarkan Properti:
jendela Anda xaml:
UserControlNameHelper mendapatkan nama kontrol dan nama Kelas Anda untuk mengatur Kontrol ke Properti.
sumber
Saya telah memilih untuk membuat properti tambahan untuk setiap elemen yang saya butuhkan:
Ini memungkinkan saya untuk mengakses elemen anak di XAML:
sumber
Kode di belakang:
Solusi sebenarnya adalah bagi Microsoft untuk memperbaiki masalah ini, serta semua masalah lainnya dengan pohon visual yang rusak, dll. Secara hipotetis.
sumber
Solusi lain: rujuk elemen sebagai RelativeSource .
sumber
Saya memiliki masalah yang sama menggunakan TabControl ketika menempatkan sekelompok kontrol bernama ke.
Solusi saya adalah menggunakan template kontrol yang berisi semua kontrol saya untuk ditampilkan di halaman tab. Di dalam template Anda bisa menggunakan properti Name dan juga data mengikat ke properti kontrol bernama dari kontrol lain setidaknya di dalam template yang sama.
Sebagai Content of the TabItem Control, gunakan Control sederhana dan setel ControlTemplate sesuai:
Mengakses kontrol bernama di dalam templat dari kode di belakang Anda perlu menggunakan pohon visual.
sumber