2012-08-24 86 views
3

我有一個WinRT/C#/ XAML應用程序,其視圖具有垂直ListView項目。根據項目的數量,ListView顯示一個垂直滾動條。這裏的XAML定義:讓ListView滾動到所選項目

<UserControl.Resources> 
    <CollectionViewSource 
     x:Name="myViewSource" 
     Source="{Binding myViewModel.Items}" /> 
</UserControl.Resources> 
... 
<ListView 
    x:Name="myListView" 
    ItemsSource="{Binding Source={StaticResource myViewSource}}" 
    SelectedItem="{Binding SelectedItem, Mode=TwoWay}"> 
</ListView> 

現在每次我瀏覽這個觀點,ListView中的所選項目從後面的代碼(OnNavigatedTo)設置數據綁定的SelectedItem屬性在視圖模型選擇。我的問題:ListView不會自動滾動到這個選定的項目。滾動條保持在ListView的頂部,用戶必須手動滾動才能看到選定的項目。

我試着在代碼後面(在OnNavigatedTo)設置SelectedItem後執行myListView.ScrollIntoView(MyViewModel.SelectedItem);,但它不起作用。滾動條仍然在頂部。

我知道這個線程上SO:Scroll WinRT ListView to particular group。 這似乎是一個類似的問題。但是當我手動或使用WinRT XAML工具包走過ListView的可視化樹時,它找不到ScrollViewer(而是返回null)。

+0

你是在等你嘗試滾動前ListView控件加載(被添加到可視化樹)? –

+0

我在OnNavigatedTo()中調用ScrollIntoView()。我認爲這將是正確的地方,ListView應該已經加載。或者我可能錯了? – Matthias

+3

我認爲OnNavigatedTo發生在控件加載之前... –

回答

14

感謝Filip我注意到在OnNavigatedTo()中調用ScrollIntoView()爲時尚早,因爲ListView控件尚未在此處加載。

第一溶液的想法是把Loaded事件ListView中的結合:

myListView.Loaded += (s, e) => 
    myListView.ScrollIntoView(MyViewModel.SelectedItem); 

不幸的是一種使討厭的視覺效果,在那裏當前的ListView項與用於第二部分所選擇的項目重疊,一切前重新安排好了。

我找到最終的解決方案是通過視圖的Dispatcher調用ScrollIntoView()異步:

myListView.Loaded += (s, e) => Dispatcher.RunAsync(CoreDispatcherPriority.Normal, 
    () => myListView.ScrollIntoView(MyViewModel.SelectedItem)); 

這種解決方案的布點工作正常。

+0

我的事情,你有你的解決方案中的小語法錯誤 - 分號後myListView.ScrollIntoView(MyViewModel.SelectedItem)lambda表達式正文。 – honzakuzel1989

+0

在我的情況myListView.UpdateLayout()之前myListView.ScrollIntoView()也幫助 – Borzh

1

我有類似的需求,並以稍微不同的方式解決它。我訂閱了ListView中的SelectionChangedEvent,並在處理程序中執行滾動。

XAML:

<ListView x:Name="myListView" SelectionChanged="myListView_SelectionChanged" ...> 
</ListView> 

代碼:

private void myListView_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    myListView.ScrollIntoView(myListView.SelectedItem); 
}