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.