Gerard
Gerard

Reputation: 13397

Hittest for PathGeometry

I have a custom Shape with PathGeometry as DefiningGeometry.
The PathGeometry displays a text.

I notice that when one tries to select the Shape on the Canvas, you have to exactly on the text border of the Path.

I would like to be able to hit the rectangle around it.
How would you solve that, should I add a transparant Rectangle geometry?


Code for Krishna:

<DataTemplate DataType="{x:Type vm:TextLabel}">
    <c:Label Left="{Binding Left}" Top="{Binding Top}" IsDragEnabled="True" DragDeltaCommand="{Binding DragCommand}" Text="{Binding Text}" ToolTip="{Binding Code}" Fill="Black" StrokeThickness="0" x:Name="Label"/>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True">
            <Setter TargetName="Label" Property="Fill" Value="Red"/>
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

But c:Label is just a custom shape with formatted text. The Fill is the Brush of the text. So the space between/around characters is not part of the shape. Is it possible to add a transparant rectangle so that this rectangle takes part in the hittest?

Upvotes: 0

Views: 833

Answers (2)

Gerard
Gerard

Reputation: 13397

The following code works:
Top, Left are custom DP to give the shape an exact location on the Canvas (they replace Canvas.Top, Canvas.Left).

protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
    var result = base.HitTestCore(hitTestParameters);
    if (result == null && hitTestParameters.HitPoint.X < (Left + geometry.Bounds.Width) && hitTestParameters.HitPoint.X > Left)
    {
        if (hitTestParameters.HitPoint.Y < (Top + geometry.Bounds.Height) && hitTestParameters.HitPoint.Y > Top)
        {
            result = new PointHitTestResult(this, hitTestParameters.HitPoint);
        }
    }
    return result;
}

Upvotes: 0

Krishna
Krishna

Reputation: 1996

Set the background property of the container to be Transparant and then it will work.

For example if your path is inside a grid then Grid.Background="Transparant"

Sorry for these edits, Can you just try something? Put c:Label inside an empty grid and see what happens. Like

<Grid Background=White> 
<c:Label Left="{Binding Left}" ...x:Name="Label"/>
</Grid>

You might have to change the triggers and put them inside Grid.Style

Upvotes: 2

Related Questions