Adakah yang tahu mengapa kode ini tidak berfungsi:
public class CollectionViewModel : ViewModelBase {
public ObservableCollection<EntityViewModel> ContentList
{
get { return _contentList; }
set
{
_contentList = value;
RaisePropertyChanged("ContentList");
//I want to be notified here when something changes..?
//debugger doesn't stop here when IsRowChecked is toggled
}
}
}
public class EntityViewModel : ViewModelBase
{
private bool _isRowChecked;
public bool IsRowChecked
{
get { return _isRowChecked; }
set { _isRowChecked = value; RaisePropertyChanged("IsRowChecked"); }
}
}
ViewModelBase
Melawan segala sesuatu untuk RaisePropertyChanged
dll. dan berfungsi untuk yang lainnya kecuali masalah ini ..
c#
observablecollection
inotifypropertychanged
Joseph Jun. Melettukunnel
sumber
sumber
Jawaban:
Metode Set ContentList tidak akan dipanggil ketika Anda mengubah nilai di dalam koleksi, sebaliknya Anda harus melihat keluar untuk penembakan acara CollectionChanged .
Oke, itu dua kali hari ini saya salah karena dokumentasi MSDN salah. Di tautan yang saya berikan itu tertulis:
Tapi itu sebenarnya tidak menyala ketika item diubah. Saya kira Anda akan membutuhkan metode yang lebih brutal:
Jika Anda akan sangat membutuhkan ini, Anda mungkin ingin mensubklasifikasikan acara Anda
ObservableCollection
yang memicuCollectionChanged
acara ketika seorang anggota memicuPropertyChanged
acara secara otomatis (seperti yang tertulis di dokumentasi ...)sumber
changed
? Ini bisa berarti bahwa properti dari salah satu elemen dalam koleksi telah berubah (yang menurut saya Anda menafsirkannya) atau itu bisa berarti bahwa salah satu elemen koleksi telah diubah dengan menggantinya dengan contoh yang berbeda ( ini interpretasi saya). Namun tidak sepenuhnya yakin - harus melihat lebih jauh._contentList.Clear()
? Tidak ada yang akan berhenti berlanggananPropertyChanged
!ContentCollectionChanged
hanya menangani Tambah / Hapus, dan tidak Ganti / Atur Ulang. Saya akan mencoba mengedit dan memperbaiki posting. Cara simon melakukannya dalam jawabannya sudah benar.Berikut adalah kelas drop-in yang sub-kelas ObservableCollection dan benar-benar menimbulkan tindakan Reset ketika properti pada item daftar berubah. Itu memberlakukan semua item untuk diimplementasikan
INotifyPropertyChanged
.Manfaatnya di sini adalah Anda dapat mengikat data ke kelas ini dan semua ikatan Anda akan diperbarui dengan perubahan pada properti item Anda.
sumber
NotifyCollectionChangedAction.Replace
ini bukan ide yang baik, karena Anda tidak dapat membedakan antara item yang sebenarnya diganti atau peristiwa yang disebabkan oleh perubahan item. Ini akan menjadi jauh lebih baik ketika Anda mendefinisikanpublic event PropertyChangedEventHandler CollectionItemChanged;
dan kemudianItemPropertyChanged
melakukanthis.CollectionItemChanged?.Invoke(sender, e);
Saya telah mengumpulkan apa yang saya harap merupakan solusi yang cukup kuat, termasuk beberapa teknik dalam jawaban lain. Ini adalah kelas baru yang berasal dari
ObservableCollection<>
, yang saya panggilFullyObservableCollection<>
Ini memiliki beberapa fitur berikut:
ItemPropertyChanged
,. Saya sengaja memisahkan ini dari yang adaCollectionChanged
:ItemPropertyChangedEventArgs
yang menyertainya: yang asliPropertyChangedEventArgs
dan indeks dalam koleksi.ObservableCollection<>
.ObservableCollection<>.Clear()
), menghindari kemungkinan kebocoran memori.OnCollectionChanged()
, daripada langganan yang lebih banyak sumber daya untukCollectionChanged
acara tersebut.Kode
File lengkap
.cs
berikut. Perhatikan bahwa beberapa fitur C # 6 telah digunakan, tetapi harus cukup sederhana untuk membuat backport:Tes NUnit
Jadi Anda dapat memeriksa perubahan yang mungkin Anda buat (dan lihat apa yang saya uji sejak awal!), Saya juga sudah memasukkan kelas tes NUnit saya. Jelas, kode berikut ini tidak perlu hanya digunakan
FullyObservableCollection<T>
di proyek Anda.NB Kelas tes menggunakan
BindableBase
dari PRISM untuk mengimplementasikanINotifyPropertyChanged
. Tidak ada ketergantungan pada PRISM dari kode utama.sumber
ListView
akan menanggapiCollectionChanged
acara karena tahu tentang mereka.ItemPropertyChanged
adalah tambahan yang tidak standar, jadi Anda perlu mengajarkannya tentang itu. Sebagai perbaikan cepat dan kotor, Anda dapat mencoba hanya menembakkanCollectionChanged
acara serta (atau bahkan bukannya)ItemPropertyChanged
diOnItemPropertyChanged()
. Saya memisahkan mereka untuk alasan yang disebutkan dalam jawaban, tetapi untuk kasus penggunaan Anda mungkin hanya melakukan apa yang Anda butuhkan.Ini menggunakan ide-ide di atas tetapi menjadikannya koleksi 'yang lebih sensitif':
sumber
ObservableCollection tidak akan menyebarkan perubahan item individual sebagai acara CollectionChanged. Anda harus berlangganan ke setiap acara dan meneruskannya secara manual, atau Anda dapat melihat kelas BindingList [T] , yang akan melakukan ini untuk Anda.
sumber
Ditambahkan ke acara TruelyObservableCollection "ItemPropertyChanged":
sumber
Saya menggunakan jawaban Jack Kenyons untuk mengimplementasikan OC saya sendiri, tetapi saya ingin menunjukkan satu perubahan yang harus saya lakukan untuk membuatnya bekerja. Dari pada:
Saya menggunakan ini:
Tampaknya "e.NewItems" menghasilkan nol jika tindakan .Hapus.
sumber
Hanya menambahkan 2 sen saya pada topik ini. Felt the TrulyObservableCollection memerlukan dua konstruktor lain seperti yang ditemukan dengan ObservableCollection:
sumber
Saya tahu bahwa saya terlambat untuk pesta ini, tapi mungkin - ini akan membantu seseorang ..
Di sini Anda dapat menemukan implementasi saya dari ObservableCollectionEx. Ini memiliki beberapa fitur:
Tentu saja, komentar apa pun dihargai;)
sumber
Jika saya tahu ObservableCollection membuat acara hanya ketika kami menambah / menghapus atau memindahkan item dalam koleksi kami. Ketika kami simly memperbarui beberapa properti dalam koleksi item koleksi, jangan menandakannya dan UI tidak akan diperbarui.
Anda dapat secara simultan mengimplementasikan INotifyPropertyChange di kelas Model Anda. Dan daripada saat kami memperbarui beberapa item koleksi yang layak secara otomatis akan memperbarui UI.
dan dari
Dalam kasus saya, saya menggunakan ListView untuk Mengikat untuk koleksi ini dan di ItemTemplate mengatur properti Binding ke Model dan itu berfungsi dengan baik.
Ini beberapa cuplikan
Windows XAML:
Contoh kode model:
Dan implementasi ViewModel:
sumber
Solusi sederhana untuk pengumpulan observasi standar yang telah saya gunakan:
JANGAN TAMBAHKAN ke properti Anda ATAU MENGUBAHnya item batin LANGSUNG, sebagai gantinya, buat beberapa koleksi temp seperti ini
dan tambahkan item atau buat perubahan ke tmpList,
kemudian kirimkan ke properti Anda yang sebenarnya dengan penugasan.
ini akan mengubah seluruh properti yang menyebabkan pemberitahuan INotifyPropertyChanged sesuai kebutuhan.
sumber
Saya mencoba solusi ini, tetapi hanya berfungsi untuk saya seperti RaisePropertyChange ("SourceGroupeGridView") ketika koleksi berubah, yang dipecat untuk setiap item ditambahkan atau diubah.
Masalahnya ada di:
NotifyCollectionChangedAction.Reset tindakan ini membuat rebind lengkap dari semua item di groupedgrid, setara di RaisePropertyChanged. Saat Anda menggunakannya semua grup gridview disegarkan.
JIKA Anda, hanya ingin menyegarkan di UI grup item baru, Anda tidak menggunakan tindakan Reset, Anda perlu mensimulasikan tindakan Tambahkan di itemproperty dengan sesuatu seperti ini:
Maaf oleh bahasa Inggris saya, dan terima kasih untuk kode dasar :), saya harap ini membantu seseorang ^ _ ^
Enjoi !!
sumber
Inilah metode ekstensi untuk solusi di atas ...
sumber
Daripada ObservableCollection atau TrulyObservableCollection, pertimbangkan untuk menggunakan BindingList dan memanggil metode ResetBindings.
Sebagai contoh:
Diberikan acara, seperti klik kode Anda akan terlihat seperti ini:
Model saya terlihat seperti ini:
sumber
BindingList
, tetapi ada batasan untuk pendekatan ini yang diatasi oleh jawaban lain: teknik ini bergantung pada nilai yang diubah dalam kode dan di mana panggilan untukResetBindings()
dapat ditambahkan. Sebagian besar jawaban lain akan berfungsi jika objek daftar diubah melalui cara lain, seperti kode yang tidak dapat diubah atau dari pengikatan ke kontrol kedua.Untuk Memicu OnChange dalam Daftar ObservableCollection
Contoh:
sumber
Ini versi implementasi saya. Ini memeriksa dan melempar kesalahan, jika objek dalam daftar tidak mengimplementasikan INotifyPropertyChanged, jadi tidak bisa melupakan masalah itu saat berkembang. Di luar Anda menggunakan Acara ListItemChanged menentukan apakah daftar atau item daftar itu sendiri telah berubah.
sumber
Solusi sederhana dalam 2 baris kode. Cukup gunakan copy constructor. Tidak perlu menulis TrulyObservableCollection dll.
Contoh:
Metode lain tanpa copy constructor. Anda dapat menggunakan serialisasi.
sumber
Anda juga dapat menggunakan metode ekstensi ini untuk mendaftarkan handler dengan mudah untuk perubahan properti item dalam koleksi yang relevan. Metode ini secara otomatis ditambahkan ke semua koleksi yang menerapkan INotifyCollectionChanged yang menyimpan item yang menerapkan INotifyPropertyChanged:
Cara Penggunaan:
sumber