将 ItemsControl 与可拖动项目组合 - Element.parent 始终为 null

发布于 2024-09-27 08:23:01 字数 1358 浏览 9 评论 0原文

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

我想使用 DraggableExtender 使项目可拖动,如发布的 在 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)的父元素为空,因此拖动不起作用。

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

I'm binding an ItemsControl with Canvas as ItemsPanelTemplate to an ObservableCollection.

I want to make the items draggable using the DraggableExtender as posted in
Dragging an image in WPF
(I don't want to use transforms - I need to use the Canvas Left and Top properties)

It's 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>

The DraggableExtender needs the parent of the element to be the Canvas,
but the parent of my element (contentpresenter) is null, so the dragging doesn't work.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝礼 2024-10-04 08:23:01

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

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

Since the items are not directly inside the canvas, you need to walk up the visual tree until you find the canvas. I usually use the following extension method to do that:

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 where it is declared. In the DraggableExtender code, just replace this line:

Canvas canvas = element.Parent as Canvas;

With this one:

Canvas canvas = element.FindAncestor<Canvas>();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文