Combining ItemsControl with draggable items - Element.parent is always null

I bind ItemControl with Canvas as ItemPanelTemplate to ObservableCollection.

I want the elements to be dragged using DraggableExtender, as shown in Dragging the image in WPF (I don't want to use transforms - I need to use the Canvas Left and Top properties)

It is defined as:

<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 requires the parent to be Canvas, but the parent of my element (contentpresenter) is NULL, so drag and drop does not work.

So the obvious question is: what am I doing wrong?

+7
parent wpf canvas draggable itemscontrol
source share
1 answer

Since the elements are not directly inside the canvas, you need to go to the visual tree until you find the canvas. I usually use the following extension method:

 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 the method above in a static class and import the namespace in which it was declared. In the DraggableExtender code, simply replace this line:

 Canvas canvas = element.Parent as Canvas; 

With the help of this:

 Canvas canvas = element.FindAncestor<Canvas>(); 
+7
source share

All Articles