WPFでPath の図形の範囲内か?判定するコード

コンピュータ

マウスカーソルが、図形内にあるとカーソルが指のアイコンに変化するコードです。
範囲判定も、自前で書こうとうすると中々大変そうなので、ライブラリの機能をありがたく使わせてもらいます。

ソースコード

ファイル名:HitTestSample.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UseWPF>true</UseWPF>
  </PropertyGroup>

</Project>

ファイル名:MainWindow.xaml.cs

using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace HitTestSample;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }


    private bool IsMouseOverPath(Path path, MouseEventArgs e)
    {
        // マウス座標を Path 座標系に変換
        Point p = e.GetPosition(path);

        Geometry geometry = path.Data;

        // 塗りつぶし領域内?
        if (geometry.FillContains(p))
            return true;

        // 線の上(Stroke)?
        if (path.Stroke != null)
        {
            var pen = new Pen(path.Stroke, path.StrokeThickness);
            if (geometry.StrokeContains(pen, p))
                return true;
        }

        return false;
    }

    private void MyCanvas_MouseMove(object sender, MouseEventArgs e)
    {
        if (IsMouseOverPath(MyPath, e))
        {
            Cursor = Cursors.Hand;
        }
        else
        {
            Cursor = Cursors.Arrow;
        }
    }
}

ファイル名:MainWindow.xaml

<Window x:Class="HitTestSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:HitTestSample"
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="800">
    <Canvas
        x:Name="MyCanvas"
        Background="Transparent"
        MouseMove="MyCanvas_MouseMove">
        <Path
            x:Name="MyPath"
            Stroke="Blue"
            Fill="SkyBlue"
            Stretch="Fill"
            StrokeThickness="3"
            Canvas.Left="50"
            Canvas.Top="30"
            Data="M 0,0 L 100,100 L 100,0 Z"/>
    </Canvas>
</Window>

実行

実行動画:

コメント