2010-10-10 13 views
7

Łączę ItemsControl z Canvas jako ItemsPanelTemplate do ObservableCollection.Łączenie ItemsControl z przeciągalnymi elementami Element.parent zawsze zerowy

Chcę, aby elementy Draggable pomocą DraggableExtender jak pisał w Dragging an image in WPF (nie chcę używać transformacji - muszę korzystać z płótna left i top Właściwości)

Jest zdefiniowana jako:

<ItemsControl ItemsSource="{Binding Path=Nodes}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Canvas IsItemsHost="True" /> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Views:NodeView DataContext="{Binding}"/> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
     <ItemsControl.ItemContainerStyle> 
      <Style TargetType="ContentPresenter"> 
       <Setter Property="Utilities:DraggableExtender.CanDrag" Value="True" /> 
       <Setter Property="Canvas.Left" Value="{Binding Path=X}" /> 
       <Setter Property="Canvas.Top" Value="{Binding Path=Y}" /> 
      </Style> 
     </ItemsControl.ItemContainerStyle> 
    </ItemsControl> 

DraggableExtender potrzebuje rodzica elementu być płótnie, ale rodzic mojego elementu (contentpresenter) jest pusty, więc przeciąganie nie działa.

Oczywistym pytaniem jest - co robię źle?

Odpowiedz

7

Ponieważ elementy nie znajdują się bezpośrednio w obszarze roboczym, należy przejść do drzewa wizualnego, dopóki nie znajdzie się płótno. Zwykle używam następującą metodę rozszerzenia, aby to zrobić:

public static T FindAncestor<T>(this DependencyObject obj) 
    where T : DependencyObject 
{ 
    DependencyObject tmp = VisualTreeHelper.GetParent(obj); 
    while(tmp != null && !(tmp is T)) 
    { 
     tmp = VisualTreeHelper.GetParent(tmp); 
    } 
    return tmp as T; 
} 

Put powyższej metody w klasie statycznej, a następnie zaimportować przestrzeń nazw, gdzie jest zadeklarowany. W kodzie DraggableExtender, po prostu zastąpić ten wiersz:

Canvas canvas = element.Parent as Canvas; 

Z tego:

Canvas canvas = element.FindAncestor<Canvas>(); 
+0

Cheers, to działa jak czar. – Pygmy

Powiązane problemy