Combining ItemsControl with draggable items - Element.parent always null

拈花ヽ惹草 提交于 2019-12-10 03:04:00

问题


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 ?


回答1:


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


来源:https://stackoverflow.com/questions/3902392/combining-itemscontrol-with-draggable-items-element-parent-always-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!