2016-02-28 135 views
2

我正在使用DataGridCellEditingTemplates。由於ItemsSource使用了數據虛擬化集合(AlphaChiTech解決方案),該集合一次只能按需獲取大小爲100的頁面。WPF - VirtualizingStackPanel在DataGrid中進入編輯模式時請求所有項目

它很好用,直到單元格被雙擊到編輯表單中,然後VirtualizingStackPanel一個接一個地請求所有項目。當然,作爲一種副作用,最終要求所有頁面。

有沒有辦法解決這個問題?

編輯:

我找到了一個解決辦法,這可能會幫助人們在我的情況:

最後,我觀察到VirtualizingStackPanel沒有要求的情況下的所有項目,該行高度保持不變切換到編輯表單後。在解決方法之前,我的編輯表單略高一些。

現在我以這樣一種方式設置單元格中的控件的MinHeight(正常和編輯),切換到編輯窗體的高度不會改變。

不幸的是,這隻適用於某些條件。有些情況下,將無法正常工作的情況下:

  • 使用RowDetailsTemplate。一旦可見,虛擬化就會被破壞。我假設行的細節屬於它自己的行,所以行高再次增加。

  • 提高Collection中的Reset事件,分別爲CollectionView。根據我的經驗,這通常是DataGrids的數據虛擬化殺手。

  • 退化集合Count(這也沒有拋出重置事件的問題)。

有趣的是,增加集合的Count確實奏效。但是我必須提高AlphaChiTech的功能(幸運的是源代碼位於github上),因爲如果沒有提高Reset事件的開箱即用(至少我沒有找到),沒有辦法改變Count。此外,DataGrid's項目必須立即刷新,否則會拋出異常,指出ItemsControl和集合確實存在不一致狀態。

行細節對我來說是可選的,但刪除項目而不破壞數據虛擬化至關重要。因此,問題依然存在。我的解決方法很可能會幫助收集固定大小的人,但不幸的是不是我自己。

回答

0

的解決方法

我發現這個問題自己解決方法的解決方案。 此替代方法用於在WPF中使用數據虛擬化的可編輯集合(數據虛擬化只讀集合可在沒有解決方法的情況下實現)。

首先,行必須是uni-sized。我的一個問題是CellEditingTemplates高於CellTemplates。因此,每次觸發編輯表單時,DataGrid都會獲取集合的所有項目。設置CellTemplatesMinHeightCellEditingTemplates的高度相匹配就行了。

通常,RowDetailsTemplate屬於該行,因此當它變爲可見時,它會更改行的高度,因此會中斷數據虛擬化。因此,最好使用排除細節並使用主細節模式,其中「細節」顯示在DataGrid之外。後者我正試圖執行現在(一個未完全實施的第一次嘗試運作良好,足以說明這不會造成任何麻煩)。我想到了行細節的一個例外:如果行細節總是可見的,並且每個項目具有相同大小的行細節,那麼它可能工作。這個想法是,行的高度然後是單一的大小,但在我的應用程序只有整個集合中的少數項目需要的細節我沒有嘗試這種方法。

其次,減少計數 - 意味着刪除項目 - 並重置集合上的項目或者DataGrid也觸發了所有項目的提取。此處的解決方法是,在添加或刪除項目時,用相同項目的新集合對象替換現有集合。幸運的是,這個新的集合也是數據虛擬化的。所以它仍然省時,流暢,用戶不會注意到它。但是,如果在DataGrid中選擇某個項目時執行了這種「刷新」,則仍然存在問題。這裏出現了一個令人討厭的解決方法:我在ViewModel中實施了兩個事件,管理虛擬化集合。這些是PreVirtualizedRefreshPostVirtualizedRefreshViewDataGrid訂閱它們並取消選擇DataGrid,PreVirtualizedRefreshPostVirtualizedRefresh中的每個項目,可以再次選擇取消選擇的項目索引(如果存儲)。後來,仍然不適合我。

重要的是,通過使用這些解決方法(使用備用主細節模式並使用新集合對象&取消選擇項目進行刷新),數據虛擬化不會被打破。

備註

出所有的虛擬化解決方案,而解決這些問題,我嘗試了我認爲AlphaChi解決方案是最好的。

WPF絕對不是在考慮數據虛擬化的情況下構建的。另一方面,它的繼承者UWP甚至擁有自己的數據虛擬化接口。因爲我沒有任何UWP項目,所以我不能嘗試自己,但我想這會讓我很開心。話雖如此,UWP沒有本地DataGrid,所以數據虛擬化的集合必須被提供給Lists或第三方DataGrids。所以還需要權衡。