You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MAUI实现点击按钮后在运行时于GraphicsView中绘制线条

MAUI GraphicsView点击按钮添加新线条实现方案

1. 改造Drawable类,支持多线条存储与绘制

原Drawable仅绘制固定单条线,我们需要扩展它来存储多条线条数据,并在Draw方法中遍历绘制所有线条:

namespace CoachesToolbox.Models
{
    // 定义线条数据模型,存储线条的关键属性
    public class LineData
    {
        public float X1 { get; set; }
        public float Y1 { get; set; }
        public float X2 { get; set; }
        public float Y2 { get; set; }
        public Color StrokeColor { get; set; }
        public float StrokeSize { get; set; }
    }

    public class Drawable : IDrawable
    {
        // 存储所有待绘制的线条
        public List<LineData> Lines { get; } = new List<LineData>();

        public Drawable()
        {
            // 初始化时添加默认线条
            Lines.Add(new LineData
            {
                X1 = 10,
                Y1 = 10,
                X2 = 90,
                Y2 = 100,
                StrokeColor = Colors.Red,
                StrokeSize = 5
            });
        }

        public void Draw(ICanvas canvas, RectF dirtyRect)
        {
            // 遍历所有线条完成绘制
            foreach (var line in Lines)
            {
                canvas.StrokeColor = line.StrokeColor;
                canvas.StrokeSize = line.StrokeSize;
                canvas.DrawLine(line.X1, line.Y1, line.X2, line.Y2);
            }
        }

        // 提供添加新线条的方法
        public void AddLine(LineData newLine)
        {
            Lines.Add(newLine);
        }

        // 可选:清空所有线条(用于重绘场景)
        public void ClearLines()
        {
            Lines.Clear();
        }
    }
}

2. 在XAML中添加按钮并设置布局

修改页面布局,添加触发添加线条的按钮,与GraphicsView共存:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:CoachesToolbox.Controls"
             xmlns:viewmodel="clr-namespace:CoachesToolbox.ViewModel"
             xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             xmlns:drawable="clr-namespace:CoachesToolbox.Models"
             x:DataType="viewmodel:MainViewModel"
             x:Class="CoachesToolbox.Views.MainPage"
             Title="CoachesToolBox demos">
    <ContentPage.Resources>
        <drawable:Drawable x:Key="MyDrawable" />
    </ContentPage.Resources>

    <!-- 使用Grid布局排列按钮与画布 -->
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- 添加线条按钮 -->
        <Button Text="添加新线条" 
                Clicked="OnAddLineClicked"
                Margin="10"/>

        <!-- GraphicsView画布 -->
        <GraphicsView x:Name="Canvas"
                      HorizontalOptions="Fill"
                      VerticalOptions="Fill"
                      Drawable="{StaticResource MyDrawable}"
                      Grid.Row="1"
                      BackgroundColor="Transparent"/>
    </Grid>
</ContentPage>

3. 实现按钮点击逻辑,添加线条并刷新视图

在页面后台代码中处理按钮点击事件,完成线条添加与画布重绘:

namespace CoachesToolbox.Views
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void OnAddLineClicked(object sender, EventArgs e)
        {
            if (Resources["MyDrawable"] is Drawable myDrawable)
            {
                // 生成随机坐标的新线条(可替换为自定义坐标逻辑)
                Random random = new Random();
                float x1 = random.Next(50, (int)Canvas.Width - 50);
                float y1 = random.Next(50, (int)Canvas.Height - 50);
                float x2 = random.Next(50, (int)Canvas.Width - 50);
                float y2 = random.Next(50, (int)Canvas.Height - 50);

                // 添加新线条到集合
                myDrawable.AddLine(new LineData
                {
                    X1 = x1,
                    Y1 = y1,
                    X2 = x2,
                    Y2 = y2,
                    StrokeColor = Colors.Blue,
                    StrokeSize = 5
                });

                // 通知画布重绘,更新显示
                Canvas.Invalidate();
            }
        }

        // 可选:重绘当前线条的实现(替换所有线条为新线条)
        private void OnRedrawLineClicked(object sender, EventArgs e)
        {
            if (Resources["MyDrawable"] is Drawable myDrawable)
            {
                Random random = new Random();
                // 清空原有线条
                myDrawable.ClearLines();
                // 添加新线条
                myDrawable.AddLine(new LineData
                {
                    X1 = random.Next(50, (int)Canvas.Width - 50),
                    Y1 = random.Next(50, (int)Canvas.Height - 50),
                    X2 = random.Next(50, (int)Canvas.Width - 50),
                    Y2 = random.Next(50, (int)Canvas.Height - 50),
                    StrokeColor = Colors.Green,
                    StrokeSize = 5
                });
                Canvas.Invalidate();
            }
        }
    }
}

关键说明

  • 若需要重绘当前线条(替换所有现有线条),可调用ClearLines()方法清空集合后再添加新线条。
  • 线条坐标逻辑可根据需求自定义,示例中使用随机坐标仅作演示。
  • 注意Canvas.Width与Canvas.Height需在页面加载完成后才能获取到有效值,若需基于视图尺寸初始化线条,可在SizeChanged事件中处理。

内容的提问来源于stack exchange,提问作者Aj Johnson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 19:10:50