2014-02-24 44 views
0

如何實現下面的GetListBoxItemIndex函數來獲取我單擊的項目的索引?我嘗試使用VisualTreeHelper沒有成功(意思是,VisualTreeHelper明顯的作品,但我不與樹搜索Anywhere入門...)如何獲得沒有SelectedIndex之類的ListBox項目的索引(在PreviewMouseDown中,沒有任何「已選擇」)

private void MyListBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e){ 
    var listBox = sender as ListBox; 
    var src = e.OriginalSource as DependencyObject; 
    if (src == null || listBox == null) return; 

    var i = GetListBoxItemIndex(listBox,src); 

    DragDrop.DoDragDrop(src, BoundCollection[i], DragDropEffects.Copy); 
    // BoundCollection defined as: 
    // ObservableCollection<SomeDataModelType> BoundCollection 
} 

請注意,沒有什麼在這種狀態下還選擇了,因爲它是一個PreviewMouseDown事件

回答

3

下面的代碼將幫助你解決問題,步驟都在評論,

private void ListBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e) 
{ 
    // you can check which mouse button, its state, or use the correct event. 

    // get the element the mouse is currently over 
    var uie = ListBox.InputHitTest(Mouse.GetPosition(this.ListBox)); 

    if (uie == null) 
     return; 

    // navigate to its ListBoxItem container 
    var listBoxItem = FindParent<ListBoxItem>((FrameworkElement) uie); 

    // in case the click was not over a listBoxItem 
    if (listBoxItem == null) 
     return; 

    // here is the index 
    int index = this.ListBox.ItemContainerGenerator.IndexFromContainer(listBoxItem); 
    MessageBox.Show(index.ToString()); 
} 

public static T FindParent<T>(FrameworkElement child) where T : DependencyObject 
{ 
    T parent = null; 
    var currentParent = VisualTreeHelper.GetParent(child); 

    while (currentParent != null) 
    { 

     // check the current parent 
     if (currentParent is T) 
     { 
      parent = (T)currentParent; 
      break; 
     } 

     // find the next parent 
     currentParent = VisualTreeHelper.GetParent(currentParent); 
    } 

    return parent; 
} 

更新

你想要的是你點擊的數據項的索引。一旦獲得容器,在通過DataContext獲得與其關聯的數據項之前,無法獲取索引,並在綁定集合中查找其索引。 ItemContainerGenerator已經爲你做了。

在您的代碼中,假設ListBoxItem索引與綁定集合中的數據項索引相同,但只有在關閉Virtualization時纔是如此。如果它打開,那麼只有可見區域中的物品的容器纔會被實例化。例如,如果您的綁定集合中有1000個數據項目,並且您已滾動到第50個數據項目,理論上,索引0處的ListBoxItem綁定到第50個數據項目,這證明您的假設是錯誤的。

我之前在理論上說過,因爲當Virtualization打開時,爲了使鍵盤導航正常工作,在滾動區域的頂部和底部創建了一些隱藏容器。

+0

謝謝,它的工作原理。但你能解釋爲什麼我需要'ItemContainerGenerator'嗎?爲什麼我不能「樹狀漫步」('VisualTreeHelper'方法)來獲取物品? – Tar

+0

請看看更新。 – abdelkarim

相關問題