Tim Robbins
Tim Robbins

Reputation: 335

How to find point on Path from the closest point?

user128300 has a wonderful solution for this at Get point on a path or polyline which is closest to a disconnected point but I cannot seem to get it right when using margins to position the point.

Xaml code

<Style x:Key="Test_Path_Actual" TargetType="Path">
    <Setter Property="Stroke" Value="Blue"/>
    <Setter Property="StrokeThickness" Value="1"/>
    <Setter Property="StrokeLineJoin" Value="Round"/>
    <Setter Property="Stretch" Value="Fill"/>
    <Setter Property="Data" Value="M 0,20 L 30 0 L 60,20 L 30,40 Z"/>
</Style>
<Style TargetType="{x:Type c:ConnectorStrip}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type c:ConnectorStrip}">
                <Grid x:Name="PART_Grid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                    <Path x:Name="PART_PathActual" Style="{StaticResource Test_Path_Actual}"/>
                    <Path x:Name="PART_PathHitArea" Style="{StaticResource Test_Path_Hit_Area}"/>
                    <s:ConnectorSeeker x:Name="PART_ConnectorSeeker" Visibility="collapsed"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

C# code

    void hitPath_MouseEnter(object sender, MouseEventArgs e)
    {
        ScaleX = this.DesiredSize.Width / origWidth;
        ScaleY = this.DesiredSize.Height / origHeight;

        ConnectorSeeker connSeekerL = GetConnectorSeeker();
        Point pt = GetClosestPointOnPath(e.GetPosition(this), actualPath.Data);

        if (connSeekerL != null)
        {
            double marginLeft = pt.X - (connSeekerL.Width / 2);
            double marginTop = pt.Y - (connSeekerL.Height / 2);
            double marginRight = this.DesiredSize.Width - pt.X - (connSeekerL.Width / 2);
            double marginBottom = this.DesiredSize.Height - pt.Y - (connSeekerL.Height / 2);

            connSeekerL.Margin = new Thickness(marginLeft, marginTop, marginRight, marginBottom);
            connSeekerL.Visibility = System.Windows.Visibility.Visible;
        }
        else
        {
            throw new Exception("Cannot find connector seeker");
        }
    }

The margin positioning logic works fine when e.GetPosition(this) for the current cursor position is used but I want that point on the nearest Path.

Upvotes: 2

Views: 697

Answers (1)

Tim Robbins
Tim Robbins

Reputation: 335

Got it!

Simply replace this.DesiredSize.Width with this.ActualWidth and this.DesiredSize.Height with this.ActualHeight.

The reason is if your Path object (Or the container of your Path object) is smaller than the parent, this.DesiredSize will be smaller than the actual size which causes problems with margin positioning.

Upvotes: 1

Related Questions