Pernyataan masalah
Sebagai bagian dari pengembangan satu aplikasi, diperlukan untuk mengimplementasikan skema berikut:
- Metode asinkron meminta data
- Pengguna memasukkan data dari keyboard
- Metode menerima hasil input sebagai hasil dari fungsi dan berlanjut dari tempat yang sama
Persyaratan tambahan: Jangan membuat jendela tambahan.
Akan terlihat sederhana? Ternyata sangat sederhana. Tetapi hal pertama yang pertama.
Solusi
Upaya pertama untuk melakukannya secara langsung dan tanpa mencari di Internet menyebabkan terhambatnya utas utama, dan, karenanya, tidak ada gunanya. Dan saya akan menggunakan ShowDialog, ketika saya menemukan sebuah artikel . Penulis melihat bagaimana ShowDialog dibuat di WPF. Apa yang kamu butuhkan!
Dalam artikelnya, ia menyarankan untuk membuat implementasi sendiri dari metode ShowDialog
[DllImport("user32")] internal static extern bool EnableWindow(IntPtr hwnd, bool bEnable); public void ShowModal() { IntPtr handle = (new WindowInteropHelper(Application.Current.MainWindow)).Handle; EnableWindow(handle, false); DispatcherFrame frame = new DispatcherFrame(); this.Closed += delegate { EnableWindow(handle, true); frame.Continue = false; }; Show(); Dispatcher.PushFrame(frame); }
Saya tidak perlu kunci jendela, karena semuanya ditampilkan dalam satu jendela, dan nilai kembali juga diperlukan. Kami menghapus terlalu banyak, tambahkan yang benar ...
public string GetInput() { var frame = new DispatcherFrame(); ButtonClicked += () => { frame.Continue = false; }; Dispatcher.PushFrame(frame); return Text; }
Dispatcher.PushFrame(frame)
mencegah metode GetInput()
sampai frame.Continue
menjadi false
. Ketika bingkai baru dimulai, loop utama berhenti dan yang baru dimulai. Loop ini memproses pesan sistem, sedangkan titik eksekusi di loop utama tidak bergerak lebih jauh. Ketika kita keluar dari frame saat ini ( frame.Continue = false
), loop utama terus bekerja dari tempat yang sama.
Sekarang tinggal memeriksa kinerja saja.
Di MainWindow, buat tombol dan letakkan handler di atasnya yang akan meluncurkan tugas, di mana kita akan beralih ke input keyboard.
Kode Penangan:
public RelayCommand ButtonClick => new RelayCommand(() => { Task.Factory.StartNew(() => {
Saya menggunakan solusi ini untuk memasukkan captcha dan kode tambahan untuk otentikasi dua faktor. Tetapi bisa ada sejumlah besar aplikasi.
! Kode sampel berisi pelanggaran prinsip mvvm, dan jangan memukul keras desain yang hilang
Kode sumber Github: Bukti konsep
Tautan yang bermanfaat
Artikel "Custom ShowDialog"
Deskripsi sedikit tentang kelas DispatcherFrame menggunakan terjemahan mesin
Menunggu penyelesaian melalui menunggu diberikan dalam artikel ini .