Menetapkan metode ke peristiwa pada kontrol pengguna yang dideklarasikan dalam antarmuka

Di C#, saya membuat kontrol khusus untuk digunakan dalam aplikasi khusus. Saya ingin setiap kontrol menerapkan peristiwa yang akan diaktifkan jika pengecualian atau kesalahan (kegagalan pemeriksaan internal) terjadi di dalam kontrol. Saya membuat antarmuka yang mendeklarasikan acara tersebut. Saya membuat kontrol pengguna yang mengimplementasikan antarmuka. Inilah masalah saya.

Ketika saya menambahkan salah satu kontrol khusus saya ke formulir, saya ingin mengulang kontrol pada formulir, mendeteksi semua kontrol yang merupakan kontrol khusus saya dan kemudian menetapkan pengendali acara ke acara yang saya nyatakan di antarmuka. Saya tidak dapat menemukan cara untuk melemparkan objek ke tipe antarmuka.

Mempertimbangkan:

interface IMyInterface
{
    event ControlExceptionOccured ControlExceptionOccuredEvent;
...
}

public partial class TextControl : UserControl, IMyInterface {
...
  public event ControlExceptionOccured ControlExceptionOccuredEvent;
...
}

dan di formulir saya, saya menggunakan salah satu TextControls ini. Saya punya metode ini:

private void Form1_Load(object sender, EventArgs e)
{
  foreach (Control Control in Controls)
  {
    if (Control.GetType().GetInterface(typeof(IMyInterface).FullName) != null)
    {
       ((IMyInterface)Control).ControlExceptionOccuredEvent += ControlExceptionHandler;
    }
  }
}

Ini mematuhi tetapi tidak akan dijalankan. Bagaimana cara menambahkan ControlExceptionHandler ke rantai acara?

Terima kasih saya kepada siapa pun yang mencoba membantu.


person Mike L.    schedule 05.07.2011    source sumber
comment
Apa yang Anda maksud dengan tidak akan mengeksekusi? Adakah alasan untuk tidak menggunakan if (Control is IMyInterface) daripada menelepon GetType dll?   -  person Jon Skeet    schedule 06.07.2011


Jawaban (3)


Sejauh yang saya pahami, Anda tidak dapat berlangganan acara tersebut karena kondisi IF mengembalikan FALSE. Apakah kamu mencoba menulis sesuatu seperti ini? :

foreach(Control ctrl in this.Controls){
    if((ctrl as IMyInterface) != null) {
        //do stuff
    }
}
person Tigran    schedule 05.07.2011
comment
Itu sama dengan if (ctrl is IMyInterface) {do stuff}. - person Igby Largeman; 06.07.2011

Ini adalah cara yang lebih sederhana untuk melakukannya:

if (control is IMyInterface)
    ((IMyInterface)control).ControlExceptionOccuredEvent += ControlExceptionHandler;

... Namun cara Anda melakukannya seharusnya berhasil juga, jadi Anda harus memberikan lebih banyak detail tentang apa yang terjadi.

person Igby Largeman    schedule 05.07.2011

Kode

((IMyInterface)Control).ControlExceptionOccuredEvent += ControlExceptionHandler;

menghasilkan

Tidak dapat mentransmisikan objek bertipe '...Teks.TeksKontrol' ke mengetik 'IMyInterface'.

Saya tidak mengerti mengapa tidak.

Sebagai catatan tambahan, saya menggantinya

if (Control.GetType().GetInterface(typeof(IMyInterface).FullName) != null)

dengan

if (Control is IMyInterface)

dan itu tidak berhasil. Contoh kedua tidak pernah kembali benar. Saya juga mencoba

if ((Control as IMyInterface) != null)

dan itu juga tidak pernah kembali benar.

person Mike Landi    schedule 06.07.2011