WPF之碰撞檢測--HitTesting

WPF之碰撞檢測–HitTesting

效果如下:
在這裏插入圖片描述
界面代碼如下:

<Window x:Class="Hit_Testing.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:Hit_Testing"
        mc:Ignorable="d"    
        Title="MainWindow" Height="450" Width="800">
    <Canvas Name="canvas1" MouseLeftButtonDown="Canvas_MouseLeftButtonDown">
        <Rectangle MouseEnter="Rectangle_MouseEnter"  MouseLeave="Rectangle_MouseLeave" Canvas.Left="20" Canvas.Top="20" Width="100" Height="60" Stroke="Black" Fill="LightBlue" Opacity="0.7"/>
        <Rectangle MouseEnter="Rectangle_MouseEnter" MouseLeave="Rectangle_MouseLeave" Canvas.Left="70" Canvas.Top="50" Width="100" Height="60" Stroke="Black" Fill="LightBlue" Opacity="0.7"/>
        <Rectangle MouseEnter="Rectangle_MouseEnter" MouseLeave="Rectangle_MouseLeave" Canvas.Left="150" Canvas.Top="80" Width="100" Height="60" Stroke="Black" Fill="LightBlue" Opacity="0.7"/>
        <Rectangle MouseEnter="Rectangle_MouseEnter" MouseLeave="Rectangle_MouseLeave" Canvas.Left="20" Canvas.Top="100" Width="100" Height="60" Stroke="Black" Fill="LightBlue" Opacity="0.7"/>
        <Rectangle MouseEnter="Rectangle_MouseEnter" MouseLeave="Rectangle_MouseLeave" Canvas.Left="40" Canvas.Top="60" Width="100" Height="60" Stroke="Black" Fill="LightBlue" Opacity="0.7"/>
        <Rectangle Canvas.Left="30" Canvas.Top="130" MouseLeave="Rectangle_MouseLeave" Width="100" Height="60" Stroke="Black" Fill="LightBlue" Opacity="0.7"/>


    </Canvas>
</Window>


後臺代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Hit_Testing
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private List<Rectangle> hitList = new List<Rectangle>();
        private EllipseGeometry hitArea = new EllipseGeometry();
        public MainWindow()
        {
            InitializeComponent();
            Initialize();
        }

        private void Initialize()
        {
            foreach(Rectangle rect in this.canvas1.Children)
            {
                rect.Fill = Brushes.LightBlue;
            }
        }

        private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Initialize();

            // Get Mouse Click Point
            Point pt = e.GetPosition(this.canvas1);

            // Define hit testing area
            hitArea = new EllipseGeometry(pt, 1.0, 1.0);
            hitList.Clear();

            // Call HitTest Method
            VisualTreeHelper.HitTest(canvas1, null, new HitTestResultCallback(HitTestCallback), new GeometryHitTestParameters(hitArea));

            if(hitList.Count>0)
            {
                foreach(Rectangle rect in hitList)
                {
                    // Change rectangle fill if it is hit;
                    rect.Fill = Brushes.LightCoral;
                }
                MessageBox.Show($"You hit+{hitList.Count.ToString()}+  rectangles.");
            }



        }

        private HitTestResultBehavior HitTestCallback(HitTestResult result)
        {
            // Retrieve the results of the hit test
            IntersectionDetail intersectionDetail = ((GeometryHitTestResult)result).IntersectionDetail;
            switch(intersectionDetail)
            {
                case IntersectionDetail.FullyContains:
                    // Add HitTest result to the List
                    hitList.Add((Rectangle)result.VisualHit);
                    return HitTestResultBehavior.Continue;

                case IntersectionDetail.Intersects:
                    // Set behavior to return the visuals at all z-orders levels;
                    return HitTestResultBehavior.Continue;


                case IntersectionDetail.FullyInside:
                    // Set bahivor to return the visuals at all z-orders levels;
                    return HitTestResultBehavior.Continue;
                default:
                    return HitTestResultBehavior.Stop;


            }

        }

        private void Rectangle_MouseEnter(object sender, MouseEventArgs e)
        {
            Rectangle rect = (Rectangle)sender;
            if(rect!=null)
            {
                rect.Fill = Brushes.Green;
            }
        }

        private void Rectangle_MouseLeave(object sender, MouseEventArgs e)
        {
            Rectangle rect = (Rectangle)sender;
            if (rect != null && rect.Fill==Brushes.Green)
            {
                rect.Fill = Brushes.LightBlue;
            }
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章