Bagaimana cara memperbarui Label dari dalam thread BackgroundWorker?

Ketika saya menggunakan WinForms, saya akan melakukan ini dalam metode bg_DoWork saya:

status.Invoke(new Action(() => { status.Content = e.ToString(); }));
status.Invoke(new Action(() => { status.Refresh(); }));

Namun dalam aplikasi WPF saya mendapatkan pesan kesalahan yang mengatakan bahwa Invoke tidak ada untuk Label.

Bantuan apa pun akan dihargai.


person software is fun    schedule 22.05.2015    source sumber


Jawaban (5)


Ini akan membantu Anda.

Untuk Mengeksekusi secara sinkron:

Application.Current.Dispatcher.Invoke(new Action(() => { status.Content = e.ToString(); }))

Untuk Mengeksekusi Secara Asinkron:

Application.Current.Dispatcher.BeginInvoke(new Action(() => { status.Content = e.ToString(); }))
person Gopichandar    schedule 22.05.2015

Gunakan kemampuan yang sudah ada di BackgroundWorker. Saat Anda "melaporkan kemajuan", data Anda akan dikirim ke acara ProgressChanged, yang berjalan di thread UI. Tidak perlu menelepon Invoke().

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
    bgWorker.ReportProgress(0, "Some message to display.");
}

private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    status.Content = e.UserState.ToString();
}

Pastikan Anda menyetel bgWorker.WorkerReportsProgress = true untuk mengaktifkan kemajuan pelaporan.

person Grant Winney    schedule 22.05.2015
comment
Ini. Karena Anda tidak benar-benar ingin memperbarui kontrol UI di berbagai thread. - person Mike Eason; 22.05.2015

Jika Anda menggunakan WPF, saya sarankan mencari DataBinding.

"Cara WPF" untuk melakukan pendekatan ini adalah dengan mengikat properti Content label ke beberapa properti model Anda. Dengan begitu, memperbarui model secara otomatis memperbarui label dan Anda tidak perlu khawatir menyusun sendiri threadnya.

Ada banyak artikel tentang WPF dan penyatuan data, ini mungkin merupakan awal yang baik untuk memulai: http://www.wpf-tutorial.com/data-binding/hello-bound-world/

person paul    schedule 22.05.2015

Anda perlu menggunakan

Dispatcher.Invoke(new Action(() => { status.Content = e.ToString(); }))

bukannya status.Invoke(...)

person Jens    schedule 22.05.2015

Anda benar-benar harus memikirkan untuk menggunakan kekuatan "Data Binding" di WPF.

Anda harus memperbarui objek dalam model tampilan Anda dan mengikatnya ke kontrol antarmuka pengguna Anda.

Lihat Cahaya MVVM. Sederhana dan mudah digunakan. Jangan membuat kode WPF tanpanya.

person AndrewJE    schedule 22.05.2015
comment
Anda tidak memerlukan kerangka kerja mewah apa pun untuk menggunakan pola desain MVVM. Meskipun hal ini membuat beberapa hal menjadi sedikit lebih mudah untuk dikelola. - person Mike Eason; 22.05.2015