将 ItemsControl 与可拖动项目相结合 - Element.parent 始终为空

Posted

技术标签:

【中文标题】将 ItemsControl 与可拖动项目相结合 - Element.parent 始终为空【英文标题】:Combining ItemsControl with draggable items - Element.parent always null 【发布时间】:2011-04-23 13:50:07 【问题描述】:

我正在将带有 Canvas 的 ItemsControl 作为 ItemsPanelTemplate 绑定到 ObservableCollection。

我想使用 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 需要元素的父元素是 Canvas, 但是我的元素(contentpresenter)的父元素为空,所以拖动不起作用。

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

【问题讨论】:

【参考方案1】:

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

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>();

【讨论】:

以上是关于将 ItemsControl 与可拖动项目相结合 - Element.parent 始终为空的主要内容,如果未能解决你的问题,请参考以下文章

JqueryUI Drag:光标与可拖动元素不在同一位置

将 WrapPanel 用作 ItemsPanel 的 ItemsControl - 结合“静态”子项和 ItemsSource

如何阻止鼠标中键单击取消选择 QGraphicsScene 中的项目而不阻止它与场景中的项目相结合?

可排序与可拖动的 jQuery 和 Rails

jQuery Safari / Chrome与可拖动的包含属性不兼容

Android : 将图库功能与相机捕捉相结合