2010-05-11 32 views
1

我使用ListView在列表中顯示項目。用戶可以自己選擇項目,或使用某些「預選鍵」來選擇具有指定屬性的項目。WPF Listview - 選擇'field of view'外的項目

要檢查的項目我使用類似的東西:

for(int i;i<MyListView.Items.Count;++i) 
{ 
    if(/*... Check if the items should be selected ...*/) 
     (MyListView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem).IsSelected = true; 
} 

這完全適用的項目,是在excecution時可見。但對於不可見的項目,ContainerFromIndex()返回null。我聽說這與虛擬化有關,並且該列表不知道「視野」上的項目是否有利或不利。但是,如果您手動選擇它們,可能會在列表的「視野」旁邊選擇列表中的項目?

以及如何選擇「視野」以外的項目?我認爲這一定是可能的。

感謝您的幫助, 商標

回答

2

正如你所說,我的猜測是,這個問題是ListView的項目的虛擬化。默認情況下,ListView(和ListBox)使用VirtualizingStackPanel作爲它們的ItemsPanel來提高性能。有關其工作原理的簡要說明可以閱讀here

但是,您可以替換另一個面板。在這種情況下,請嘗試使用正常的StackPanel。如果ListView中有大量項目,特別是如果它們是複雜項目,性能可能會受到一些影響。

<ListView> 
    <ListView.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel/> 
     </ItemsPanelTemplate> 
    </ListView.ItemsPanel> 
</ListView> 

編輯

您也可以嘗試的解決方案描述at this similar question,這取決於你的模型。但是,這可能不適合你。

+0

但是,怎麼可能呢,當我選擇一個項目時,將它滾動到視線之外並且向後滾動,它仍然被選中?某處必須存儲這些信息。這真的不可訪問嗎? – Marks 2010-05-11 11:47:54

+0

那麼,選定的項目可以通過'SelectedItems'訪問。它返回一個IList,它有一個Add()方法。你嘗試添加你想要選擇的項目嗎?這意味着你必須從你在ListView中顯示的任何集合中添加項目到這個IList。可能沒有辦法只使用索引來完成它。 – 2010-05-11 19:04:51

+0

感謝這個答案,這一直讓我瘋狂。 – Mark 2013-04-11 15:48:05

0

在處理虛擬化項目控件時,禁用虛擬化的替代方法(有時候實際上是一個有用的功能,即使它干擾API其他部分的正確操作)也是找到VirtualizingPanel並告訴它明確地滾動。

例如:

void ScrollToIndex(ListBox listBox, int index) 
{ 
    VirtualizingPanel panel = FindVisualChild<VirtualizingPanel>(listBox); 

    panel.BringIndexIntoViewPublic(index); 
} 

static T FindVisualChild<T>(DependencyObject o) where T : class 
{ 
    T result = o as T; 

    if (result != null) 
    { 
     return result; 
    } 

    int childCount = VisualTreeHelper.GetChildrenCount(o); 

    for (int i = 0; i < childCount; i++) 
    { 
     result = FindVisualChild<T>(VisualTreeHelper.GetChild(o, i)); 

     if (result != null) 
     { 
      return result; 
     } 
    } 

    return null; 
} 

我不是很滿意,需要通過視覺樹搜索找到的面板,但我不知道任何其他方式得到它,也不在處理虛擬化面板時滾動到特定索引。