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
相关产品推荐
相关产品推荐

