2010-05-06 33 views
0

想象以下場景:表單在回調時的OnPaint事件是否在下面?

this.SetStyle(ControlStyles.UserPaint, true); //this doesn’t change anything 

… 

void OpenSomeForm() 
{ 
    SomeForm sf = new SomeForm(); 
    sf.SomeEvent += new … (SomeEventOcurred); 
    sf.ShowDialog(); 
} 

private void SomeEventOcurred(…) 
{ 
    OnePanelInThisForm.Invalidate(); 
} 

private void OnePanelInThisForm_Paint(object sender, PaintEventArgs e) 
{ 
    DoSomeDrawing(e.Graphics); 
} 

現在,OnePanelInThisForm繪製正確加載窗體時。但是,如果SomeEventOcurred從「SomeForm」被觸發,繪製事件是而不是被觸發。如果我關閉並重新打開表單,則會正確重新繪製。 如果我將一個按鈕添加到執行的窗體中:OnePanelInThisForm.Invalidate();該面板正確重新繪製。

我錯過了什麼?

UPDATE:澄清。 (爲什麼我們不這樣做首先...)

我有一個FORM_A。這個FORM_A有一個覆蓋Paint事件的面板。這是一個標準的WinForm。在Paint中繪製一個圓。這工作。原來,FORM_A有一個打開FORM_B的按鈕。但在此之前,它在FORM_B中訂閱了一個名爲SomeEvent的自定義事件。 (見上面的示例)。所以FORM_B可以告訴FORM_A關於「SomeEvent」。

現在,FORM_B也是一個正常的WinForm。它有一個正常的按鈕。在該按鈕的Click事件中,它打開FORM_C。 FORM_C也有一個名爲SomeEvent的事件,顯然FORM_B訂閱了該事件。完全像以前一樣。這個想法是,FORM_C有一個按鈕,將觸發該事件,通知感興趣的用戶。在這種情況下,當FORM_C觸發事件時,FORM_B被訂閱並且感興趣。

當FORM_B收到回叫時,它所做的唯一的事情就是......通知相關方(在這種情況下爲FORM A)該事件已被解僱。

現在,即使Form C仍然是頂層窗體,callstack會返回FormA,返回從第一個事件定義爲回調的方法。

此代碼執行。它所做的確實是somePanel.Invalidate()(或Refresh(),結果相同)。

該面板的PAINT方法的斷點顯示代碼沒有被調用。儘管無效,但沒有引發Paint事件。我認爲這是因爲表單(以及面板)實際上由FORMB和FORMC(仍然打開)所覆蓋。

就是這樣。如果我關閉表格C然後關閉表格B,表格A仍然不會提升繪畫事件。我試圖使表單激活上的面板失效,但是這沒有發生。

如果我關閉表單A並重新打開它,那麼繪圖當然是正確的。

希望這個更清楚。因爲這非常簡單,FORM A> B> C(火災事件) - > B - > A - > Invalidate(),所以代碼並不多。

回答

1

嘗試使用Refresh()而不是Invalidate()。無論如何,這似乎對我來說更加一貫。

相關問題