Bagaimana saya bisa mengambil item yang dipilih dalam WPF-treeview? Saya ingin melakukan ini di XAML, karena saya ingin mengikatnya.
Anda mungkin berpikir bahwa itu SelectedItem
tetapi ternyata tidak ada hanya dapat dibaca dan karenanya tidak dapat digunakan.
Inilah yang ingin saya lakukan:
<TreeView ItemsSource="{Binding Path=Model.Clusters}"
ItemTemplate="{StaticResource ClusterTemplate}"
SelectedItem="{Binding Path=Model.SelectedCluster}" />
Saya ingin mengikat SelectedItem
ke properti di Model saya.
Tapi ini memberi saya kesalahan:
Properti 'SelectedItem' hanya baca dan tidak dapat diatur dari markup.
Sunting: Oke, ini cara saya memecahkan masalah ini:
<TreeView
ItemsSource="{Binding Path=Model.Clusters}"
ItemTemplate="{StaticResource HoofdCLusterTemplate}"
SelectedItemChanged="TreeView_OnSelectedItemChanged" />
dan dalam codebehindfile dari xaml saya:
private void TreeView_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
Model.SelectedCluster = (Cluster)e.NewValue;
}
Jawaban:
Saya menyadari bahwa jawaban ini sudah diterima, tetapi saya menyatukannya untuk menyelesaikan masalah. Ini menggunakan ide yang mirip dengan solusi Delta, tetapi tanpa perlu mensubklasifikasikan TreeView:
Anda kemudian dapat menggunakan ini di XAML Anda sebagai:
Semoga ini bisa membantu seseorang!
sumber
{Binding SelectedItem, Mode=TwoWay}
dengan{Binding MyViewModelField, Mode=TwoWay}
xmlns:e="http://schemas.microsoft.com/expression/2010/interactivity"
Properti ini ada: TreeView.SelectedItem
Tapi ini hanya bisa dibaca, jadi Anda tidak dapat menetapkannya melalui ikatan, hanya mengambilnya
sumber
TreeView.SelectedItem
memengaruhi properti pada model saat pengguna memilih item (aliasOneWayToSource
)?Jawab dengan properti terlampir dan tidak ada ketergantungan eksternal, jika perlu pernah muncul!
Anda dapat membuat properti terlampir yang dapat diikat dan memiliki pengambil dan penyetel:
Tambahkan deklarasi namespace yang berisi kelas itu ke XAML Anda dan ikat sebagai berikut (lokal adalah bagaimana saya menamakan deklarasi namespace):
Sekarang Anda dapat mengikat item yang dipilih, dan juga mengaturnya dalam model tampilan Anda untuk mengubahnya secara terprogram, jika persyaratan itu pernah muncul. Ini, tentu saja, dengan asumsi bahwa Anda menerapkan INotifyPropertyChanged pada properti tertentu.
sumber
Yah, saya menemukan solusinya. Ini memindahkan kekacauan, sehingga MVVM berfungsi.
Pertama-tama tambahkan kelas ini:
dan tambahkan ini ke xaml Anda:
sumber
Jawabannya sedikit lebih banyak daripada yang diharapkan OP ... Tapi saya harap itu setidaknya bisa membantu seseorang.
Jika Anda ingin menjalankan
ICommand
setiap kaliSelectedItem
perubahan, Anda dapat mengikat perintah pada suatu peristiwa dan penggunaan propertiSelectedItem
diViewModel
tidak diperlukan lagi.Untuk melakukannya:
1- Tambahkan referensi ke
System.Windows.Interactivity
2- Ikatkan perintah ke acara tersebut
SelectedItemChanged
sumber
System.Windows.Interactivity
dapat diinstal dari NuGet: nuget.org/packages/System.Windows.Interactivity.WPFSystem.Windows.Interactivity
. Itu berhasil untuk saya (dicoba dengan proyek .NET Core). Untuk mengatur semuanya, cukup tambahkan paket nuget Microsoft.Xaml.Behaviors.Wpf , ubah namespace menjadixmlns:i="http://schemas.microsoft.com/xaml/behaviors"
. Untuk mendapatkan info lebih lanjut - silakan lihat blogIni dapat dicapai dengan cara yang 'lebih baik' dengan hanya menggunakan binding dan EventToCommand GalaSoft MVVM Light library. Dalam VM Anda, tambahkan perintah yang akan dipanggil ketika item yang dipilih diubah, dan inisialisasi perintah untuk melakukan tindakan apa pun yang diperlukan. Dalam contoh ini saya menggunakan RelayCommand dan hanya akan mengatur properti SelectedCluster.
Kemudian tambahkan perilaku EventToCommand di xaml Anda. Ini sangat mudah menggunakan campuran.
sumber
Semua menjadi rumit ... Gunakan Caliburn Micro (http://caliburnmicro.codeplex.com/)
Melihat:
ViewModel:
sumber
Saya menemukan halaman ini mencari jawaban yang sama dengan penulis asli, dan membuktikan selalu ada lebih dari satu cara untuk melakukannya, solusi bagi saya bahkan lebih mudah daripada jawaban yang diberikan di sini sejauh ini, jadi saya pikir saya mungkin juga menambahkan ke tumpukan.
Motivasi untuk mengikat adalah untuk tetap bagus & MVVM. Kemungkinan penggunaan ViewModel adalah memiliki properti dengan nama seperti "CurrentThingy", dan di tempat lain, DataContext pada beberapa hal lain terikat dengan "CurrentThingy".
Daripada melalui langkah-langkah tambahan yang diperlukan (misalnya: perilaku kustom, kontrol pihak ke-3) untuk mendukung pengikatan yang bagus dari TreeView ke Model saya, dan kemudian dari hal lain ke Model saya, solusi saya adalah menggunakan Elemen sederhana yang mengikat hal lain untuk TreeView.SelectedItem, daripada mengikat hal lain ke ViewModel saya, sehingga melewatkan pekerjaan tambahan yang diperlukan.
XAML:
Tentu saja, ini bagus untuk membaca item yang dipilih saat ini, tetapi tidak mengaturnya, yang saya butuhkan.
sumber
Anda mungkin juga dapat menggunakan properti TreeViewItem.IsSelected
sumber
Ada juga cara untuk membuat properti SelectedItem bindable XAML tanpa menggunakan Interaksi. Perilaku.
Anda kemudian dapat menggunakan ini di XAML Anda sebagai:
sumber
Saya mencoba semua solusi dari pertanyaan ini. Tidak ada yang menyelesaikan masalah saya sepenuhnya. Jadi saya pikir lebih baik menggunakan kelas warisan seperti itu dengan properti SelectedItem yang didefinisikan ulang. Ini akan bekerja dengan sempurna jika Anda memilih elemen pohon dari GUI dan jika Anda menetapkan nilai properti ini dalam kode Anda
sumber
Persyaratan saya adalah untuk solusi berbasis PRISM-MVVM di mana TreeView diperlukan dan objek terikat adalah tipe Collection <> dan karenanya membutuhkan HierarchicalDataTemplate. BindableSelectedItemBehavior default tidak akan dapat mengidentifikasi TreeViewItem anak. Untuk membuatnya berfungsi dalam skenario ini.
Ini memungkinkan untuk beralih melalui semua elemen terlepas dari level.
sumber
Saya menyarankan tambahan untuk perilaku yang disediakan oleh Steve Greatrex. Perilakunya tidak mencerminkan perubahan dari sumber karena itu mungkin bukan kumpulan TreeViewItems. Jadi itu adalah masalah menemukan TreeViewItem di pohon yang datacontext adalah Nilai yang dipilih dari sumber. TreeView memiliki properti yang dilindungi yang disebut "ItemsHost", yang menampung koleksi TreeViewItem. Kita bisa mendapatkannya melalui refleksi dan berjalan di pohon mencari item yang dipilih.
Dengan cara ini perilaku berfungsi untuk binding dua arah. Atau, dimungkinkan untuk memindahkan akuisisi ItemsHost ke metode OnAttached Behavior, menghemat biaya tambahan menggunakan refleksi setiap kali pembaruan yang mengikat.
sumber
WPF MVVM TreeView SelectedItem
... adalah jawaban yang lebih baik, tetapi tidak menyebutkan cara untuk mendapatkan / mengatur SelectedItem di ViewModel.
sumber
Setelah mempelajari Internet selama sehari saya menemukan solusi saya sendiri untuk memilih item setelah membuat treeview normal di lingkungan WPF / C # yang normal
sumber
Itu juga dapat dilakukan dengan menggunakan properti IsSelected dari item TreeView. Begini cara saya mengelolanya,
Kemudian di ViewModel yang berisi data yang terikat dengan TreeView Anda, cukup berlangganan acara di kelas TreeViewItem.
Dan akhirnya, laksanakan handler ini dalam ViewModel yang sama,
Dan tentu saja mengikat,
sumber
Saya tahu utas ini berumur 10 tahun tetapi masalahnya masih ada ....
Pertanyaan aslinya adalah 'untuk mengambil' item yang dipilih. Saya juga perlu "mendapatkan" item yang dipilih di viewmodel saya (tidak disetel). Dari semua jawaban di utas ini, yang oleh 'Wes' adalah satu-satunya yang mendekati masalah secara berbeda: Jika Anda dapat menggunakan 'Item yang Dipilih' sebagai target untuk penyatuan data, gunakan sebagai sumber untuk penyatuan data. Wes melakukannya ke properti tampilan lain, saya akan melakukannya ke properti viewmodel:
Kami membutuhkan dua hal:
Model tampilan:
Lihat konstruktor:
sumber
(Mari kita semua sepakat bahwa TreeView jelas-jelas rusak sehubungan dengan masalah ini. Mengikat ke SelectedItem sudah jelas. Sigh )
Saya membutuhkan solusi untuk berinteraksi dengan benar dengan properti IsSelected dari TreeViewItem, jadi inilah cara saya melakukannya:
Dengan XAML ini:
sumber
Saya membawa Anda solusi saya yang menawarkan fitur-fitur berikut:
Mendukung 2 cara mengikat
Otomatis memperbarui properti TreeViewItem.IsSelected (sesuai dengan SelectedItem)
Tidak ada subklasifikasi TreeView
Item yang terikat pada ViewModel dapat berupa jenis apa pun (bahkan nol)
1 / Rekatkan kode berikut di CS Anda:
2 / Contoh penggunaan dalam file XAML Anda
sumber
Saya mengusulkan solusi ini (yang saya anggap paling mudah dan bebas dari kebocoran memori) yang berfungsi sempurna untuk memperbarui item yang dipilih ViewModel dari item yang dipilih View.
Harap dicatat bahwa mengubah item yang dipilih dari ViewModel tidak akan memperbarui item yang dipilih dari View.
Penggunaan XAML
sumber