2010-04-10 18 views
3

我有3個數據圖通過它們的繪畫事件繪製。 當我有需要插入圖形的數據時,我會調用controls invalidate()命令。Onpaint事件(無效)在一段時間正常操作(運行時)後更改執行順序

第一個控件的繪畫事件實際上爲其他2個圖形創建了一個位圖緩衝區,以避免重複長循環。

所以無效命令是按特定順序(1,2,3)。這很好,但是當圖形數據到達數據通常開始滾動的圖形窗口(PictureBox)的末端時,繪製事件以錯誤的順序(2,3,1)開始觸發。

有沒有人遇到過這個?爲什麼會發生這種情況?使在任何三個控件的調用Invalidate之前,您創建一個共享的位圖緩存(可以想象作爲控件類的靜態成員)

+0

@Luke:沒有必要把標題中的語言,因爲你已經在標籤中。這也沒有必要說「嗨」,因爲我們沒有談話 - 我們正在做一個問答。請參閱http://stackoverflow.com/faq。 – 2010-04-10 23:08:46

回答

5

更改您的密碼,並在每個控件然後呼叫Invalidate。在控件的Paint事件中,您可以使用靜態位圖緩衝區,並且事件以何種順序觸發都無關緊要。

當您在控件上調用Invalidate時,基本上是告訴操作系統向該控件發送WM_PAINT消息。因爲這是一個Windows消息,所以只要Windows開始這樣做,它就會保證交付。在你的情況下,他們通常按照收到的順序交付,但有時他們不會。

另一個要考慮你的代碼:當你把你的控件的Paint事件處理中相對複雜的繪製代碼(或直接從Paint事件處理程序調用的方法中),這個代碼將每當控制無效執行出於任何原因,這意味着代碼將在您撥打Invalidate時運行,但只要將另一個窗口拖動到控件上,它也會運行。

對於複雜,費時的圖形,它總是最好到一個隱藏緩衝區(一個Bitmap或無形PictureBox或其他)執行復雜的渲染,然後在控制的Paint事件做從隱藏緩衝區的簡單複製到可見窗口(使用Graphics.DrawImageBitBlt或其他)。

這種方法還允許您避免閃爍,如果您添加第二個緩衝區之間的緩衝區你畫和可見窗口(因此「雙緩衝」)。在完成對主緩衝區的繪製之後,將其複製到第二個緩衝區。在控件的Paint事件中,您從第二個緩衝區複製到可見窗口。

+0

對不起,我的壞。我沒有看時間戳。當我做出勾號時,該帖子沒有通過張貼順序來呈現。經驗教訓 – 2010-04-11 10:13:01

+0

@Luke:你可以將支票退還給Virtlink--我有很多的代表點,而且他也是對的。 :) – MusiGenesis 2010-04-11 13:46:53

3

因爲在控件上調用Invalidate()本質上要求操作系統安排控件重繪,所以不能保證這是按特定順序完成的。

由於您嘗試以特定順序致電Invalidate(),我假設您有一個單獨的方法來執行此操作。您可以在這些調用之前添加代碼以繪製位圖緩衝區,然後由無效控件使用該位圖緩衝區。我不知道這是否會發生,但是這也讓您在數據沒有變化時不會使控件失效的自由。此外,控制可以在任何時候失效。例如,通過控件1移動表單會導致它無效,並且在您當前的設置中,重新計算緩衝區位圖,而不是必需的。因此,你應該分開這個功能。

+0

只是在我等待啤酒開始時抱怨一下:這正是我在5分鐘前說過的。 :) – MusiGenesis 2010-04-10 23:53:48