2011-08-05 5 views
4

WPF ListBoxes 사이에서 끌어서 놓기를 수행하고 있으므로 컬렉션의 끝 부분에 놓을 수있는 위치에 컬렉션을 삽입 할 수 있습니다.WPF ListBox IndexFromPoint

누구든지 WinForms ListBox IndexFromPoint 기능과 유사한 솔루션을 알고 있습니까? 당신이 (당신이 ListBoxItem의를 찾을 것리스트 박스, 대한 등이 ....) 올바른 ItemContainer을 명중 할 때까지

+0

입니다. http://msdn.microsoft.com/en-us/library/ms752097.aspx#Y4200 –

답변

6

DragDropEvent.GetPosition, VisualTreeHelper.GetDescendantBounds 및 Rect.Contains의 조합을 사용하여이 작업을 끝내게되었습니다. 다음은 내가 생각해 낸 것입니다 :

int index = -1; 
for (int i = 0; i < collection.Count; i++) 
{ 
    var lbi = listBox.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem; 
    if (lbi == null) continue; 
    if (IsMouseOverTarget(lbi, e.GetPosition((IInputElement)lbi))) 
    { 
     index = i; 
     break; 
    } 
} 

코드는 ListBox Drop 이벤트에 있습니다. e 객체는 Drop 이벤트에 전달 된 DragEventArgs 객체입니다.

IsMouseOverTarget의 구현은 다음과 같습니다

private static bool IsMouseOverTarget(Visual target, Point point) 
{ 
    var bounds = VisualTreeHelper.GetDescendantBounds(target); 
    return bounds.Contains(point); 
} 
+0

감사합니다 선생님! 오늘은 진짜 너 덕분이다! – Steffen

3

당신은

그런 전화

itemsControl.InputHitTest(position). 

거기에서 시각적 트리를 이동 사용할 수 있습니다

itemsControl.ItemContainerGenerator.IndexFromContainer(listBoxItem) 

삽입 색인을 얻으려면.

+0

나는 방금 이것을 시도했지만 어쩌면 내가 잘못 했어. 내가 본 것은 InputHitTest가 ListBoxItem을 비교할 수없는 TextBlock을 반환한다는 것입니다. 내 ListBox ObservableCollection 문자열에 바인딩되어 있기 때문에 가정합니다. – Josh

+0

아니요, VisualTreeHelper.GetParent (dependencyObject)를 textblock에서 계속 호출하여 (재귀 적으로, 해당 호출의 결과를 메서드로 전달합니다) listboxitem을 누를 때까지 계속 호출하십시오. –

+0

Ahh gotcha. 재귀를 피하기 위해 나는 아래에있는 것을 사용하는 것에 전념 할 것이라고 생각합니다. 나는 당신의 대답을 투표 할 것입니다. 왜냐하면 그것이 효과가 있기 때문입니다. – Josh

1

이것은 내가 그것을하지 어떻게 - 요점입니다 목록 등

//Get the position 
var currp = e.GetPosition(dgrid); 
//Get whats under that position 
var elem=dgrid.InputHitTest(currp); 
//Your ListView or DataGrid will have set the DataContext to your bound item 
if (elem is FrameworkElement && (elem as FrameworkElement).DataContext != null) 
{ 
    var target=dgrid.ItemContainerGenerator.ContainerFromItem((elem as FrameworkElement).DataContext) 
} 

를 반복 어떠한 드라마 - 당신이 다음 ItemContainerGenerator.ContainerFromItem을 사용할 수 있습니다 또는 IndexFromContainer를 사용하여 색인을 얻으십시오. 그러나 가장 많이 사용하고 싶은 항목은