2012-12-07 90 views
2

我知道這個問題已經在這裏問過,但沒有回答。所以我再問一次,但提供我自己的調查,看看我們是否可以解決這個問題。如何在WP Listbox上保留視口(滾動位置)?

問題

我們有一個數據綁定列表框。我希望它在將新元素添加到數據源時保留視口(顯示的元素)。這樣,我可以在不更改視圖的情況下添加新元素。

當前WP行爲是保持滾動位置(ScrollViewer.VerticalOffset是恆定的)。這樣,當您添加新元素時,所有元素都會關閉。

可能的解決方案

我已經挖了很多與此,我有一些線索。

  • 當列表不在頂部時禁用數據源刷新。這樣,我們可以在不更改視口的情況下添加新項目。問題是:當用戶再次登頂時,所有新元素都會突然出現在列表頂部,從而失去連續性。

  • 獲取當前查看的項目,當所有的新元素都添加了它ScrollIntoView恢復。起初這看起來可能是最好的選擇,但相信我不是。首先,獲取正在查看的當前項目並不容易:它可以通過LinqToVisualTree完成,但它不完全(只能猜測它,視口緩衝區的大小不是恆定的),所以我們不會恢復用戶以前的確切位置。這個解決方案會「跳躍」:從用戶的角度來看,會有兩個滾動事件,這並不好。

  • 計算被添加的所有元素的垂直尺寸,以補償垂直偏移。這似乎是一個很好的解決方案(我目前正在調查它),但我擔心它也會產生「跳動」的效果。這將完成覆蓋Listbox中的PrepareContainerForItemOverride方法。當基礎方法已經準備好容器時,獲取其高度並將其添加到計數器。然後,當負載結束時,滾動到獲得的垂直偏移量。這是不可能的(我們只能稱爲ScrollToVerticalOffset方法,它不會立即滾動),所以我認爲這不會成爲最終的解決方案。

我的猜測是,要做到這一點,我們應該深入到Listbox定義。在某處,Listbox管理ItemsSource屬性的CollectionChanged事件。在那裏,列表決定重新創建緩衝區(more on Listbox buffers here)。由於這些依賴於ScrollViewer的VerticalOffset屬性(常量),因此視口會發生變化。我們應該修改列表框,以便它不重新創建緩衝區。問題是,我不知道如何做到這一點。

對此有何想法?

謝謝!

編輯:很明顯,我正在使用ObservableCollection添加項目。我不刷新ItemsSource屬性本身。

回答

-2

對於ListBox,您應該使用ObservableCollection作爲ItemsSource。因此,無論何時將對象添加到ObservableCollectionListBox都將保留其視圖。神奇的是,ObservableCollection實現INotifyPropertyChanged接口

How to use ObservableCollection

How to use INotifyPropertyChanged interface

+0

我已經使用的ObservableCollection(當然,修改所以它是線程安全的,但它實現了'INotifyPropertyChanged')。這不是問題。當您將項目添加到「ObservableCollection」的頂部時,該列表將保持垂直偏移,並且項目向下移動。 – gjulianm

相關問題