当前位置: 首页 > news >正文

C# Avalonia 13- MoreDrawing - VisualLayer

扩展已经更新,新增对资源和样式的动态加载。

https://www.cnblogs.com/dalgleish/p/18972924

有了这个新增功能,我们就可以单独创建一个Styles.axaml。以后样式可以独立在这里书写,我这里写了一个RadioButton的样式。

<Styles xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><Design.PreviewWith><Border Padding="20"><!-- Add Controls for Previewer Here --></Border></Design.PreviewWith><!--RadioButton自定义样式--><Style Selector="RadioButton.toggle-button"><Setter Property="Background" Value="Transparent"/><Setter Property="Padding" Value="6"/><Setter Property="Template"><ControlTemplate><Border Padding="{TemplateBinding Padding}"Background="{TemplateBinding Background}"BorderBrush="{TemplateBinding BorderBrush}"CornerRadius="6"BorderThickness="1"><ContentPresenterContent="{TemplateBinding Content}"ContentTemplate="{TemplateBinding ContentTemplate}"HorizontalAlignment="Center"VerticalAlignment="Center"/></Border></ControlTemplate></Setter><!-- 默认样式 --><Style Selector="^:normal"><Setter Property="BorderBrush" Value="Transparent"/><Setter Property="Background" Value="Transparent"/></Style><!-- 悬停样式 --><Style Selector="^:pointerover"><Setter Property="BorderBrush" Value="#BFDFFF"/><Setter Property="Background" Value="#F6FBFF"/></Style><!-- 选中样式 --><Style Selector="^:checked"><Setter Property="BorderBrush" Value="SteelBlue"/><Setter Property="Background" Value="#E8F7FF"/></Style></Style></Styles>

VisualLayer.axaml代码

<Window xmlns="https://github.com/avaloniaui"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"Height="350.4" Width="496.8" Background="AliceBlue"x:Class="AvaloniaUI.VisualLayer"Title="VisualLayer"><Grid ColumnDefinitions="auto,*"><ToolBarTray Orientation="Vertical"><ToolBar Orientation="Vertical">        <RadioButton Classes="toggle-button" Margin="0,3" Name="cmdSelectMove"><StackPanel><Image Source="avares://AvaloniaUI/Resources/Images/pointer.png" Width="35" Height="35"></Image><TextBlock>移动</TextBlock></StackPanel></RadioButton><RadioButton Classes="toggle-button" Margin="0,3" Name="cmdAdd"><StackPanel><Rectangle Width="35" Height="35" Stroke="SteelBlue" StrokeThickness="3" Fill="AliceBlue"></Rectangle><TextBlock>添加</TextBlock></StackPanel></RadioButton><RadioButton Classes="toggle-button" Margin="0,3" Name="cmdDelete"><StackPanel><Path Stroke="SteelBlue" StrokeThickness="4" StrokeLineCap="Round"Fill="Red" VerticalAlignment="Center" HorizontalAlignment="Center"><Path.Data><GeometryGroup><PathGeometry><PathFigure StartPoint="0,0"><LineSegment Point="30,30"></LineSegment></PathFigure><PathFigure StartPoint="0,30"><LineSegment Point="30,0"></LineSegment></PathFigure></PathGeometry></GeometryGroup></Path.Data></Path><TextBlock>删除</TextBlock></StackPanel></RadioButton><RadioButton Classes="toggle-button" Margin="0,3" Name="cmdSelectMultiple"><StackPanel><Image Source="avares://AvaloniaUI/Resources/Images/pointer.png" Width="35" Height="35"></Image><TextBlock>多选</TextBlock></StackPanel></RadioButton></ToolBar></ToolBarTray><Border Grid.Column="1" Margin="3" BorderBrush="SteelBlue" BorderThickness="1" Background="White"><Canvas x:Name="drawingSurface" ClipToBounds="True"></Canvas></Border></Grid>
</Window>

VisualLayer.axaml.cs代码

using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Media;
using Shares.Avalonia;
using System;
using System.Collections.Generic;
using System.Linq;namespace AvaloniaUI;public class RectangleVisual : Control
{public Point TopLeft { get; set; }public Size Size { get; set; }public IBrush Fill { get; set; }public Pen Pen { get; set; }private bool isSelection = false;public bool IsSelected => isSelection;public RectangleVisual(Point topLeft, Size size, IBrush fill, Pen pen, bool selection = false){TopLeft = topLeft;Size = size;Fill = fill;Pen = pen;isSelection = selection;}public void SetSelected(bool selected){isSelection = selected;InvalidateVisual();}public new Rect Bounds => new Rect(TopLeft, Size);public override void Render(DrawingContext context){var brush = isSelection ? Brushes.LightGoldenrodYellow : Fill;context.DrawRectangle(brush, Pen, this.Bounds);}
}public partial class VisualLayer : Window
{private List<RectangleVisual> visuals = new List<RectangleVisual>();private IBrush drawingBrush = Brushes.AliceBlue;private Pen drawingPen = new Pen(Brushes.SteelBlue, 1);private Size squareSize = new Size(35, 35);private bool isDragging = false;private Point dragStartPoint;private bool isMultiSelecting = false;private Point selectionSquareTopLeft;private RectangleVisual? selectionSquare;private Pen selectionSquarePen = new Pen(Brushes.Black, 1, dashStyle: new DashStyle(new double[] { 4, 2 }, 0));private IBrush selectionSquareBrush = Brushes.Transparent;private void AddVisual(RectangleVisual visual){visuals.Add(visual);drawingSurface.Children.Add(visual);}private void DeleteVisual(RectangleVisual visual){visuals.Remove(visual);drawingSurface.Children.Remove(visual);}private RectangleVisual? GetVisualAt(Point point){foreach (var v in visuals){if (v.Bounds.Contains(point)) return v;}return null;}private void SelectVisual(RectangleVisual? visual){foreach (var v in visuals)v.SetSelected(v == visual);}private void ClearSelection(){foreach (var v in visuals)v.SetSelected(false);}public VisualLayer(){InitializeComponent();this.Load("avares://Shares/Avalonia/Styles/Styles.axaml");drawingSurface.Background = Brushes.Transparent;drawingSurface.PointerPressed += DrawingSurface_PointerPressed;drawingSurface.PointerMoved += DrawingSurface_PointerMoved;drawingSurface.PointerReleased += DrawingSurface_PointerReleased;// 模式切换时清空选中cmdAdd.IsCheckedChanged += ModeRadioButton_IsCheckedChanged;cmdDelete.IsCheckedChanged += ModeRadioButton_IsCheckedChanged;cmdSelectMultiple.IsCheckedChanged+= ModeRadioButton_IsCheckedChanged;// 测试矩形var rect = new RectangleVisual(new Point(10, 10), squareSize, drawingBrush, drawingPen);AddVisual(rect);}private void ModeRadioButton_IsCheckedChanged(object? sender, RoutedEventArgs e){if (sender is RadioButton rb && rb.IsChecked == true){ClearSelection();}}private void DrawingSurface_PointerPressed(object? sender, PointerPressedEventArgs e){Point pointClicked = e.GetPosition(drawingSurface);if (cmdSelectMove?.IsChecked == true){var visual = GetVisualAt(pointClicked);if (visual != null){if (!visual.IsSelected)SelectVisual(visual);isDragging = true;dragStartPoint = pointClicked;e.Pointer.Capture(drawingSurface);}elseClearSelection();}else if (cmdAdd?.IsChecked == true){var visual = new RectangleVisual(pointClicked, squareSize, drawingBrush, drawingPen);AddVisual(visual);}else if (cmdDelete?.IsChecked == true){var visual = GetVisualAt(pointClicked);if (visual != null)DeleteVisual(visual);}else if (cmdSelectMultiple?.IsChecked == true){selectionSquareTopLeft = pointClicked;isMultiSelecting = true;selectionSquare = new RectangleVisual(selectionSquareTopLeft, new Size(0, 0),selectionSquareBrush, selectionSquarePen, true);selectionSquare.SetSelected(false);AddVisual(selectionSquare);e.Pointer.Capture(drawingSurface);}}private void DrawingSurface_PointerMoved(object? sender, PointerEventArgs e){Point pos = e.GetPosition(drawingSurface);if (isDragging){var delta = pos - dragStartPoint;foreach (var v in visuals.Where(v => v.IsSelected)){v.TopLeft += delta;v.InvalidateVisual();}dragStartPoint = pos;}else if (isMultiSelecting && selectionSquare != null){selectionSquare.Size = new Size(Math.Abs(pos.X - selectionSquareTopLeft.X),Math.Abs(pos.Y - selectionSquareTopLeft.Y));selectionSquare.TopLeft = new Point(Math.Min(pos.X, selectionSquareTopLeft.X),Math.Min(pos.Y, selectionSquareTopLeft.Y));selectionSquare.InvalidateVisual();}}private void DrawingSurface_PointerReleased(object? sender, PointerReleasedEventArgs e){if (isDragging){isDragging = false;e.Pointer.Capture(null);}else if (isMultiSelecting && selectionSquare != null){foreach (var v in visuals){if (selectionSquare.Bounds.Intersects(v.Bounds))v.SetSelected(true);elsev.SetSelected(false);}DeleteVisual(selectionSquare);selectionSquare = null;isMultiSelecting = false;e.Pointer.Capture(null);}}
}

运行效果

image

 

http://www.wxhsa.cn/company.asp?id=945

相关文章:

  • Linux 设置nginx 以及java jar自启动
  • DevelPy-TryHackMe
  • 记录一次解决phpstudy启动数据库自动关闭的问题方法
  • cache redis
  • 《爱上情感:自然魅力的社交》
  • Java的基本数据类型
  • H5游戏性能优化系列-----配置相关优化
  • 300 毫秒生成情感 AI 视频,Nuance Labs 获千万美元融资;AirPods Pro 3 将集成实时语音翻译丨日报
  • 认知引擎:企业下一个决胜分水岭
  • node.js安装地址
  • 【已解决】git Encountered 3 file(s) that should have been pointers, but werent
  • 接雨水-leetcode
  • Codeforces Round 1049 (Div. 2) E
  • ES深度分页优化
  • 2025年8月国产数据库大事记:东莞银行1078万采购OceanBase、821万采购腾讯TDSQL,2025上半年达梦净利2亿、金仓净利润飙升……
  • VSCode安装Jupyter的常见问题
  • 批量设置Excel样式格式(如:纸张大小,排版,字体等)+ 支持windows系统
  • 张瑜:牛市进程之十大观察指标 - Leone
  • QT-控件使用-获取lable标签宽高尺寸设置图片
  • 初识python:一些基础的知识(推导式)
  • RK3588+preemrt+ethercat搭建
  • Windows 11 系统优化
  • 碎碎念(十六)
  • PK-2600-ALG-2 三同轴转鳄鱼夹测试线应用案例
  • RK3588+xenomai3+ethercat搭建
  • 从英伟达到国产算力:一场必须打赢的“迁移之战”
  • 小说写法分析-个人随记
  • Nuget的不是所配置的源之一
  • part 3
  • 微服务高可用高并发方案