0

I have a drag behavior that I modified from answeres to this question. Almost everything works, except when I drag shapes past other shapes. Here is the XAML for my ItemsControl:

<ItemsControl x:Name="audioDisplayItemsControl" 
                      ItemsSource="{Binding Shapes}">
            <ItemsControl.Resources>
                <DataTemplate DataType="{x:Type ct:Rectangle}">
                    <Rectangle Width="{Binding Width}"
                               Height="{Binding Height}"
                               Fill="Black"
                               IsManipulationEnabled="True"/>
                </DataTemplate>
                <DataTemplate DataType="{x:Type ct:Line}">
                    <!-- Points reletive to ItemContainer -->
                    <Line X1="0"
                          Y1="0"
                          X2="0"
                          Y2="{Binding Length}"
                          Stroke="Gray"
                          StrokeThickness="2"
                          StrokeDashArray="4 1"/>
                </DataTemplate>
                <DataTemplate DataType="{x:Type ct:LabeledLine}">
                    <Grid>
                        <!-- Points reletive to ContentPresenter-->
                        <Line X1="0"
                              Y1="0"
                              X2="0"
                              Y2="{Binding Length}"
                              Stroke="Red"
                              StrokeThickness="2"/>
                        <TextBlock Margin="4,1,0,0" Foreground="White">
                            <Run Text="("/>
                            <Run Text="{Binding Num}"/>
                            <Run Text=") "/>
                            <Run Text="{Binding Title}"/>
                        </TextBlock>
                    </Grid>
                </DataTemplate>
            </ItemsControl.Resources>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    
                    <Canvas>
                        <Canvas.Background>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="Black"/>
                                    <GradientStop Color="Black" Offset="0.30"/>
                                    <GradientStop Color="Green" Offset="0.33"/>
                                    <GradientStop Color="Green" Offset="0.67"/>
                                    <GradientStop Color="Black" Offset="0.7"/>
                                    <GradientStop Color="Black" Offset="1"/>
                            </LinearGradientBrush>
                        </Canvas.Background>
                    </Canvas>
                    
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemContainerStyle>
                <Style TargetType="ContentPresenter">
                    <Setter Property="Canvas.Top" Value="{Binding Top, Mode=TwoWay}"/>
                    <Setter Property="Canvas.Left" Value="{Binding Left, Mode=TwoWay}"/>
                    <Setter Property="Panel.ZIndex" Value="{Binding ZIndex}"/>
                    <Setter Property="ct:DragBehavior.Drag" Value="{Binding CanDrag}"/>  <----- DragBehavior attached here
                </Style>
            </ItemsControl.ItemContainerStyle>
        </ItemsControl>

Here is what my ItemsControl looks like before I add my list of shapes to it Blank Items Control

After I add the shapes it looks like this enter image description here

Only the red lines (ct:LabeledLine) are draggable, and only along the x-axis. My problem is when I drag a red line past the one to its right as shown

enter image description here

The red line for "(0) New 0" is past the red line for "(1) New 1" but not past the text for "(1) New 1". Since (0) was added before (1), the ContentPresenter for (0) is behind the ContentPresenter for (1). Now I can no longer drag (0), unless I move (1) out of the way. This is because the drag behavior is attached to the contentPresenter, not the red line.

From the MouseLeftButtonUp event, I can get the ContentPresenter (it's just the sender), but I need to get the parent ItemsControl so I can get a list of its children, sort them by their x position values and assign ZIndex based on their sort order. This I think should solve my problem.

I just don't know how to get the parent ItemsControl.

master_ruko
  • 629
  • 1
  • 4
  • 22

1 Answers1

0

You could walk up the visual tree manually using VisualTreeHelper.GetParent.

This is a method I use when I need to do things like this:

Public Function FindVisualParent(Of ParentType As DependencyObject)(obj As DependencyObject) As ParentType
    Dim Parent As DependencyObject = obj

    Do Until Parent Is Nothing OrElse TypeOf Parent Is ParentType
        If TypeOf Parent IsNot Visual AndAlso TypeOf Parent IsNot Media3D.Visual3D AndAlso TypeOf Parent Is FrameworkContentElement Then
            Parent = DirectCast(Parent, FrameworkContentElement).Parent
        Else
            Parent = VisualTreeHelper.GetParent(Parent)
        End If
    Loop

    Return Parent
End Function

I took the time to convert the above to C#:

public ParentType FindVisualParent<ParentType>(DependencyObject obj) where ParentType : DependencyObject
{
    DependencyObject Parent = obj;

    while (Parent != null && !(Parent is ParentType))
    {
        if (Parent is FrameworkContentElement contentElement)
            Parent = contentElement.Parent;
        else
            Parent = VisualTreeHelper.GetParent(Parent);
    }

    return (ParentType)Parent;
}
Clemens
  • 123,504
  • 12
  • 155
  • 268
Keith Stein
  • 6,235
  • 4
  • 17
  • 36