2010-10-10 40 views
7

我将具有Canvas的ItemsControl作为ItemsPanelTemplate绑定到ObservableCollection。将ItemsControl与可拖动项目合并 - Element.parent始终为空

我想要的物品拖动使用DraggableExtender,张贴在 Dragging an image in WPF (我不想使用转换 - 我需要使用Canvas Left和Top属性)

它的定义为:

<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需要元素的父是画布, 但我的元素(contentpresenter)的母公司是空的,所以拖动不起作用。

所以显而易见的问题是 - 我做错了什么?

回答

7

由于项目不是直接位于画布内,因此需要沿着可视化树向上走,直到找到画布。我通常使用下面的扩展方法做到这一点:

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; 
} 

把上面的方法在静态类,并导入在声明的命名空间。在DraggableExtender代码,只需更换这行:

Canvas canvas = element.Parent as Canvas; 

有了这一个:

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

欢呼声中,它就像一个魅力。 – Pygmy 2010-10-19 22:01:12