2009-03-04 32 views
2

Ana formda bir uygulama var ve gelen verileri işlemek ve ana formdaki çeşitli denetimlerdeki değişiklikleri yansıtacak bir olay işleyicisi kullanıyor. Bu iyi çalışıyor.Ana Formdaki Olayları C İçinde Başka Bir Biçimden Dinleme C#

Ayrıca uygulamada başka bir formum var. Herhangi bir zamanda çalışan bu ikinci formun birden fazla örneği olabilir.

Yapmak istediğim, bu ikinci formun her örneğinin ana formdaki olay işleyicisini dinlemesi ve ikinci formdaki örneğinin denetimlerini güncelleştirmesidir.

Bunu nasıl yaparım?

İşte bazı örnek kod. SecondaryForm'un her bir örneğini güncellemek için the_timer_Tick olay işleyicisinden bilgi istiyorum.

public partial class Form1 : Form 
{ 
    Timer the_timer = new Timer(); 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     the_timer.Tick += new EventHandler(the_timer_Tick); 
     the_timer.Interval = 2000; 
     the_timer.Enabled = true; 
    } 

    void the_timer_Tick(object sender, EventArgs e) 
    { 
     // I would like code in here to update all instances of SecondaryForm 
     // that happen to be open now. 
     MessageBox.Show("Timer ticked"); 
    } 

    private void stop_timer_button_Click(object sender, EventArgs e) 
    { 
     the_timer.Enabled = false; 
    } 

    private void start_form_button_Click(object sender, EventArgs e) 
    { 
     SecondaryForm new_form = new SecondaryForm(); 
     new_form.Show(); 
    } 
} 

cevap

5
class SecondForm 
{ 
    private FirstForm firstForm; 

    public SecondForm() 
    { 
    InitializeComponent(); 
    // this means unregistering on form closing, uncomment if is necessary (anonymous delegate) 
    //this.Form_Closing += delegate { firstForm.SomeEvent -= SecondForm_SomeMethod; }; 
    } 

    public SecondaryForm(FirstForm form) : this() 
    { 
    this.firstForm = form; 
    firstForm.Timer.Tick += new EventHandler(Timer_Tick); 
    } 

    // make it public in case of external event handlers registration 
    private void Timer_Tick(object sender, EventArgs e) 
    { 
    // now you can access firstForm or it's timer here 
    } 
} 

class FirstForm 
{ 
    public Timer Timer 
    { 
    get 
    { 
     return this.the_timerl 
    } 
    } 

    public FirstForm() 
    { 
    InitializeComponent(); 
    } 

    private void Button_Click(object sender, EventArgs e) 
    { 
    new SecondForm(this).ShowDialog(); // in case of internal event handlers registration (in constructor) 
    // or 
    SecondForm secondForm = new SecondForm(this); 
    the_timer.Tick += new EventHandler(secondForm.Timer_tick); // that method must be public 
    } 
+0

İkinci form kapatıldığında olay işleyicisini kaldırmayı unutmayın, aksi takdirde referans sızıntısına sahip olabilirsiniz ... –

+0

SecondForm'a yapılan atıfların tümü SecondaryForm mu olmalıdır? Ve benim de yayınladığım ana formdaki gibi bir şey var mı? – Dave

+0

Yea, demek istediğim SecondForm = SecondaryForm. Örneğin, Timer'ı herkese açık hale getirebilir veya erişim için bir özelliğe sahip olabilirsiniz ve FistForm olaylarını dinlemezsiniz, ancak zamanlayıcı etkinlikleri vardır: Koduma bakın, ben düzenleyeceğim – abatishchev

0

Sana SecondaryForm yapıcı ebeveyn formunda sürmesine sebep olabilir ve yapıcı bir olay işleyicisi ekleyin sanırım. SecondaryForm.cs ise

private void start_form_button_Click(object sender, EventArgs e) 
{ 
    SecondaryForm new_form = new SecondaryForm(this); 
    new_form.Show(); 
} 

:

public SecondaryForm(ISomeView parentView) 
{ 
    parentView.SomeEvent += ..... 
} 
2

gevşek bağlı olayları kullanmayı düşünün. Bu, sınıfları, birbirlerinin doğrudan farkında olmak zorunda olmayacak şekilde eşleştirmenize izin verecektir. Birlik uygulama bloğu, bunu çok basit yapan EventBroker adlı bir uzantı ile gelir.

İşte şekerin biraz yalamak var:

public static class EVENTS 
{ 
    public const string UPDATE_TICKED = "event://Form1/Ticked"; 
} 

public partial class Form1 : Form 
{ 
    [Publishes(EVENTS.UPDATE_TICKED)] 
    public event EventHandler Ticked; 

    void the_timer_Tick(object sender, EventArgs e) 
    { 
     // I would like code in here to update all instances of SecondaryForm 
     // that happen to be open now. 
     MessageBox.Show("Timer ticked"); 
     OnTicked(); 
    } 

    protected virtual void OnTicked() 
    { 
     if (Ticked == null) return; 
     Ticked(this, e); 
    } 
} 

public partial class SecondaryForm : Form 
{ 
    [SubscribesTo(EVENTS.UPDATE_TICKED)] 
    private void Form1_Ticked(object sender, EventHandler e) 
    { 
     // code to handle tick in SecondaryForm 
    } 
} 

Şimdi Unity üzerinden bu sınıfların her ikisi, bunlar otomatik olarak bir araya kablolu edilecektir inşa halinde.

Güncelleme

Daha yeni çözümler gevşek bağlı olayları işlemek için mesaj otobüsü kullanıyoruz. Örnek olarak http://masstransit-project.com/ veya http://nimbusapi.github.io/'a bakın.

+0

@ Okuma.Scott Başka bir bağlantı sağladı, ayrıca gevşek bir şekilde bağlanmış olayları nasıl ele aldığım hakkında bir güncelleştirme sağladı. Mesaj yolunu hafızada tercih ederim. Yatay ölçek sağlar. Nimbus Azure Message Bus kullanıyor ve Mass Transit RabbitMQ kullanıyor. –

İlgili konular