2013-06-03 63 views
2

我有一個有幾個孩子班的父母抽象班。最後,我希望通過GUI中的進度條來顯示兒童課程的進度。撫養孩子/父母事件

我現在已經做了什麼,我正在意識到這一點是行不通的,是在父類中聲明的事件方法定義,作爲每個子類將覆蓋的虛擬方法。因此,像:

public abstract class Parent 
{ 
public event EventHandler someEvent; 

protected virtual void OnSomeEvent(object sender, EventArgs e) 
    { 
      EventHandler eh= someEvent; 
     if (eh!= null) 
     { 
      eh(this, e); 
     } 
    } 
} 

我的子類有類似:

protected override void OnSomeEvent(object sender, EventArgs e) 
    { 
     base.OnSomeEvent(sender, e); 
    } 

,而該事件在子類中的某處提高。

但是,由於我無法創建抽象類的實例,因此,作爲父類看起來很抽象,我無法從我的GUI中聽到該事件。

我完全偏離了課程和/或是否有另一種方法?

+2

爲什麼您的UI無法附加到子實例上的事件?如果你從'Parent'繼承,'Child'也會有這個事件。 – qJake

+0

這個想法是,我不一定希望GUI知道哪個孩子提出了事件。@SpikeX –

+0

所以你想在Parent上有一個靜態事件處理程序,它只有一個實例,就是你說的。 – qJake

回答

2

您可以附加到來自子實例的事件。

public abstract class Parent 
{ 
     public event Action Something; 

     public void OnSomething() 
     { 
      if (Something != null) 
      { 
       Something(); 
      } 
     } 
} 
public class Child : Parent 
{ 

} 

Child c = new Child(); 
c.Something +=() => Console.WriteLine("Got event from child"); 
c.OnSomething(); 
> Got event from child 

你甚至可以將它聲明爲一個包含一個孩子Parent類型:

Parent c2 = new Child(); 
c2.Something +=() => Console.WriteLine("Got event from Parent type"); 
c2.OnSomething(); 
> Got event from Parent type 

一個抽象類就是這樣被複制到每一個繼承它(把它類代碼模板只是)。想想看,您所有的Child類都包含存在於Parent中的相同代碼副本。


請注意,這也將爲每個Child實例生成一個唯一的事件處理程序。擁有所有Child s表示從Parent派生應該是這樣的一個靜態的事件處理程序,並要求在Child沒有代碼:

public abstract class Parent 
{ 
    public static event Action Something; 

    public static void OnSomething() 
    { 
     if (Something != null) 
     { 
      Something(); 
     } 
    } 
} 

然後,你可以做這樣的事情,例如:

Parent.Something +=() => Console.WriteLine("This will be invoked twice."); 

Child c = new Child(); 
Child c2 = new Child(); 
c.OnSomething(); 
c2.OnSomething(); 

> This will be invoked twice. 
> This will be invoked twice. 

這兩個對象/事件調用都會調用相同的事件處理函數,即使它們來自不同的子項。

+0

要明確一點,你在子類中的OnSomething()的實現是什麼? –

+0

@moalaz沒有一個。它自動從'Parent'繼承。你可以從'Child'中調用'OnSomething();',除非你特別想用其他行爲來覆蓋它,但是默認情況下它只會調用'Something'事件。 – qJake

+0

ahh當然,完美的謝謝 –

0

首先不要,因爲someEvent沒有指定static,子類的每個實例都會有自己的someEvent。這意味着你沒有得到一個統一的觀點,而是一個多元化的觀點。這對於響應正在按下的按鈕很有用,因爲您不想在單擊背景時以相同的方式響應。

通常不是使用類層次結構,而是使用組合來處理這種情況。例如,向您的以下類添加:

public class ParentContainer 
{ 
    private List<Parent> watched = new List<Parent>(); 
    public void Add(Parent watch) 
    { 
     watched.Add(watch); 
     watch.SomeEvent += Handler; 
    } 

    private void Handler(object sender, EventArgs args) 
    { 
     //Do something 
    } 
}