2011-01-07 25 views
1

短的問題:Control.VisibleChanged事件不會引發

我注意到Control.VisibleChanged事件不會觸發時,從真正的Visible屬性更改爲false。

我讀過這篇文章,深入解釋了Visible屬性是如何實現的(link)。這並不能解決我的問題,因爲我直接設置了UserControl的Visible屬性,並且我不躺在子可見狀態事件上。

我錯過了什麼?

長的問題:

我有一個包含很多元素一個ListView的用戶控件。 ListView是使用虛擬模式實現的,因此只有在必要時才創建節點。

當相關對象發生變化時,ListView項目應該更新自己;它知道何時該對象具有每當對象改變時通知訂戶的事件ObjectChanged事件。所以,在構造ListViewItem時,也會訂閱MyObject.ObjectChanged事件。不幸的是,MyObject實例在內存中幾乎是持久的(從來沒有處理過),但ListView以虛擬模式請求我創建大量代表同一對象的ListViewItem。由於創建的ListViewItem實例已訂閱到(持久性)對象,因此它們從不處置,導致內存泄漏。

與之相對應的是,如果創建的ListViewItem實例不訂閱ObjectChanged事件,它們將在GC喚醒後儘快處理;但這會是一個問題,因爲節點不會根據更改自行更新。如果UserControl跟蹤創建的ListViewItem實例,則可能會有解決方法,但這樣可以最大限度地減少ListView在虛擬模式下的優勢。

所以,我已經放棄了。我會跟蹤每個創建的節點。

接着,我希望當用戶控件變爲不可見重置ListViewItem的集合,但...

[參考簡短的問題]

回答

1

不能完全遵循這一點,但它聽起來像一個XY問題。使用VisibleChanged非常棘手,它不遵循您指定的Visible的值。只有實際的可見性狀態。

請勿以任何方式使ListViewItems知道底層數據的更改狀態。我猜你正在使用派生類與事件。是的,如果事件源未被收集,則會泄漏這些項目。相反,調用列表視圖的Invalidate()方法強制重繪自己。它將再次爲所有可見項目提高RetrieveVirtualItem事件,以便它們顯示更新的數據。如果你想優化這個,只有在可見項更新時才調用Invalidate,然後實現CacheVirtualItems事件。

+0

CacheVirtualItems給我的實際顯示的項目的範圍使ListView失效後? – Luca 2011-01-07 17:49:30