【WPF】マウスクリックでキャンバスに三角形を描画するコード。

コンピュータ

ベクター画像を動的に描画するサンプルコードとして、マウスクリックした3つの座標を元にpathで三角形を描画します。

ソースコード

ファイル名:TriangleDrawSample.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.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace TriangleDrawSample;

public partial class MainWindow : Window
{
    // 三角形頂点座標のストック用配列(リスト)
    private readonly List<Point> _points = new();

    public MainWindow()
    {
        InitializeComponent();
    }
    // マウスクリックイベント
    private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        // キャンバス上の位置を取得
        var pos = e.GetPosition(MainCanvas);
        _points.Add(pos);   // 座標を配列(リスト)に記録

        // デバッグ用:クリック位置に小さな点を描く
        DrawPoint(pos);

        // 座標が配列(リスト)に3つ溜まったら
        if (_points.Count == 3)
        {
            // 三角形をを描画
            DrawTriangle(_points[0], _points[1], _points[2]);
            // 座標配列(リスト)をクリアし次の三角形に備える。
            _points.Clear();
        }
    }

    // 三角形を描画
    private void DrawTriangle(Point p1, Point p2, Point p3)
    {
        var figure = new PathFigure // 1本の連続した線(輪郭)を表すオブジェクト
        {
            StartPoint = p1,    // 始点の座標
            IsClosed = true,    // パスを閉じる ... 終点→始点
            IsFilled = true     // 輪郭の内側を塗り領域として扱う
        };

        figure.Segments.Add(new LineSegment(p2, true)); // 2つめの頂点
        figure.Segments.Add(new LineSegment(p3, true)); // 3つ目の頂点

        var geometry = new PathGeometry();  // 「複数の輪郭(PathFigure)+ 塗りルール(FillRule)」をまとめた図形データ
        geometry.Figures.Add(figure);

        var path = new Path // ベクター図形
        {
            Data = geometry,
            Stroke = Brushes.Black, // 直線描画のブラシ ... 黒色
            StrokeThickness = 2,    // 直線描画の線の太さ ... 2
            Fill = Brushes.LightSkyBlue // 塗りつぶし色
        };

        MainCanvas.Children.Add(path);  // カンバスの子要素に追加 ... ベクター図形の表示
    }
    // クリック場所を丸い赤い点の描画で表現
    private void DrawPoint(Point p)
    {
        const double size = 4;

        var ellipse = new Ellipse   // 楕円
        {
            Width = size,   // 幅 ... 4
            Height = size,  // 高さ ... 4
            Fill = Brushes.Red  // 塗りつぶしブラシ色 ... 赤
        };

        Canvas.SetLeft(ellipse, p.X - size / 2);    // X座標 ... 左端
        Canvas.SetTop(ellipse, p.Y - size / 2);     // Y座標 ... 上端

/*
XAMLだとこんな感じ。(疑似コード。動きません)
<Ellipse ... 楕円
    Width="4"
    Height="4"
    Fill="Red"
    Canvas.Left="p.X - size / 2"
    Canvas.Top="p.Y - size / 2"
/>
*/
        MainCanvas.Children.Add(ellipse);  // カンバスの子要素に追加 ... 楕円の描画

    }    
}

ファイル名:MainWindow.xaml


<Window x:Class="TriangleDrawSample.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:TriangleDrawSample"
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="800">
    <Canvas Name="MainCanvas"
            Background="White"
            MouseLeftButtonDown="Canvas_MouseLeftButtonDown"/>
</Window>

実行

dotnet run 

ウィンドウ内でマウスクリックすると赤い点が描画されます。点を3つ打つと三角形が描画されます。

コメント