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

C# Avalonia 18- ControlTemplates - WrapBreakPanelTest

自己写一个WrapBreakPanel类就行了。

WrapBreakPanel.cs

using Avalonia;
using Avalonia.Controls;
using Avalonia.Layout;
using System;namespace Shares.Avalonia.CustomControls
{public class WrapBreakPanel : Panel{// Orientation propertypublic static readonly StyledProperty<Orientation> OrientationProperty =AvaloniaProperty.Register<WrapBreakPanel, Orientation>(nameof(Orientation), Orientation.Horizontal);public Orientation Orientation{get => GetValue(OrientationProperty);set => SetValue(OrientationProperty, value);}// Spacing propertypublic static readonly StyledProperty<double> SpacingProperty =AvaloniaProperty.Register<WrapBreakPanel, double>(nameof(Spacing), 0);public double Spacing{get => GetValue(SpacingProperty);set => SetValue(SpacingProperty, value);}// LineBreakBeforepublic static readonly AttachedProperty<bool> LineBreakBeforeProperty =AvaloniaProperty.RegisterAttached<WrapBreakPanel, Control, bool>("LineBreakBefore");public static void SetLineBreakBefore(Control element, bool value)=> element.SetValue(LineBreakBeforeProperty, value);public static bool GetLineBreakBefore(Control element)=> element.GetValue(LineBreakBeforeProperty);// LineBreakAfterpublic static readonly AttachedProperty<bool> LineBreakAfterProperty =AvaloniaProperty.RegisterAttached<WrapBreakPanel, Control, bool>("LineBreakAfter");public static void SetLineBreakAfter(Control element, bool value)=> element.SetValue(LineBreakAfterProperty, value);public static bool GetLineBreakAfter(Control element)=> element.GetValue(LineBreakAfterProperty);protected override Size MeasureOverride(Size availableSize){return Orientation == Orientation.Horizontal ?MeasureHorizontal(availableSize) :MeasureVertical(availableSize);}protected override Size ArrangeOverride(Size finalSize){return Orientation == Orientation.Horizontal ?ArrangeHorizontal(finalSize) :ArrangeVertical(finalSize);}// Horizontal measureprivate Size MeasureHorizontal(Size available){Size currentLine = new();Size panelSize = new();foreach (var child in Children){child.Measure(available);var desired = child.DesiredSize;bool breakBefore = GetLineBreakBefore(child);bool breakAfter = GetLineBreakAfter(child);double widthWithSpacing = desired.Width + (currentLine.Width > 0 ? Spacing : 0);if (breakBefore || currentLine.Width + widthWithSpacing > available.Width){// Add line spacingif (panelSize.Height > 0)panelSize = new Size(panelSize.Width, panelSize.Height + Spacing);panelSize = new Size(Math.Max(panelSize.Width, currentLine.Width),panelSize.Height + currentLine.Height);currentLine = desired;}else{currentLine = new Size(currentLine.Width + widthWithSpacing,Math.Max(currentLine.Height, desired.Height));}if (breakAfter){if (panelSize.Height > 0)panelSize = new Size(panelSize.Width, panelSize.Height + Spacing);panelSize = new Size(Math.Max(panelSize.Width, currentLine.Width),panelSize.Height + currentLine.Height);currentLine = new();}}return new Size(Math.Max(panelSize.Width, currentLine.Width),panelSize.Height + currentLine.Height);}// Horizontal arrangeprivate Size ArrangeHorizontal(Size final){double x = 0;double y = 0;double lineHeight = 0;foreach (var child in Children){var sz = child.DesiredSize;bool breakBefore = GetLineBreakBefore(child);bool breakAfter = GetLineBreakAfter(child);double widthWithSpacing = sz.Width + (x > 0 ? Spacing : 0);if (breakBefore || (x + widthWithSpacing > final.Width)){y += lineHeight;if (y > 0)y += Spacing;x = 0;lineHeight = 0;}child.Arrange(new Rect(x, y, sz.Width, sz.Height));x += sz.Width + Spacing;lineHeight = Math.Max(lineHeight, sz.Height);if (breakAfter){y += lineHeight + Spacing;x = 0;lineHeight = 0;}}return final;}// Vertical measureprivate Size MeasureVertical(Size available){Size currentColumn = new();Size panelSize = new();foreach (var child in Children){child.Measure(available);var desired = child.DesiredSize;bool breakBefore = GetLineBreakBefore(child);bool breakAfter = GetLineBreakAfter(child);double heightWithSpacing = desired.Height + (currentColumn.Height > 0 ? Spacing : 0);if (breakBefore || currentColumn.Height + heightWithSpacing > available.Height){if (panelSize.Width > 0)panelSize = new Size(panelSize.Width + Spacing, panelSize.Height);panelSize = new Size(panelSize.Width + currentColumn.Width,Math.Max(panelSize.Height, currentColumn.Height));currentColumn = desired;}else{currentColumn = new Size(Math.Max(currentColumn.Width, desired.Width),currentColumn.Height + heightWithSpacing);}if (breakAfter){if (panelSize.Width > 0)panelSize = new Size(panelSize.Width + Spacing, panelSize.Height);panelSize = new Size(panelSize.Width + currentColumn.Width,Math.Max(panelSize.Height, currentColumn.Height));currentColumn = new();}}return new Size(panelSize.Width + currentColumn.Width,Math.Max(panelSize.Height, currentColumn.Height));}// Vertical arrangeprivate Size ArrangeVertical(Size final){double x = 0;double y = 0;double colWidth = 0;foreach (var child in Children){var sz = child.DesiredSize;bool breakBefore = GetLineBreakBefore(child);bool breakAfter = GetLineBreakAfter(child);double heightWithSpacing = sz.Height + (y > 0 ? Spacing : 0);if (breakBefore || y + heightWithSpacing > final.Height){x += colWidth;if (x > 0)x += Spacing;y = 0;colWidth = 0;}child.Arrange(new Rect(x, y, sz.Width, sz.Height));y += sz.Height + Spacing;colWidth = Math.Max(colWidth, sz.Width);if (breakAfter){x += colWidth + Spacing;y = 0;colWidth = 0;}}return final;}}
}

WrapBreakPanelTest.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="300" Width="500" x:Class="AvaloniaUI.WrapBreakPanelTest"Title="WrapBreakPanelTest"><WrapBreakPanel Spacing="5"><Button Content="A"/><Button Content="B" WrapBreakPanel.LineBreakBefore="True"/><Button Content="C"/></WrapBreakPanel>
</Window>

WrapBreakPanelTest.axaml.cs代码

using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Shares;
using System;namespace AvaloniaUI;public partial class WrapBreakPanelTest : Window
{public WrapBreakPanelTest(){InitializeComponent();}
}

运行效果

image

 

http://www.gsyq.cn/news/65106.html

相关文章:

  • 小样本学习实现大规模计算机视觉任务
  • 实用指南:Kafka Consumer 消费流程详解
  • 2025年上海继承律师权威推荐榜单:房产律所/婚姻律所/离婚房产律所精选
  • 2025公寓床源头厂家TOP5权威推荐:口碑好的公寓床定制厂
  • 应用安全 --- 软件安全 之 选择性加固
  • 2025年工业冷风机十大品牌排行榜揭晓,工厂车间降温通风/锻打车间通风降温/铸造车间通风降温/陶瓷车间降温工业冷风机产品推荐排行榜
  • 详细介绍:2025年(第六届)“大湾区杯”粤港澳金融数学建模竞赛准备!严格遵循要求,拿下大奖!
  • 2025成都抖音短视频运营服务商权威榜单发布
  • 2025化工玻璃仪器企业TOP5权威推荐:三晶玻璃怎么样
  • 2025年上海婚姻律所权威推荐榜单:房产律所/离婚事务所/继承律所律师事务所精选
  • 2025年11月工业陶瓷厂家最新推荐,聚焦高端定制需求与全案交付能力!
  • 04-实体类与ORM映射
  • 02-框架架构与核心组件
  • 03-快速入门与环境配置
  • 小红书代运营公司TOP5权威推荐:资质齐全品牌甄选,助力企业
  • 2025 年 11 月空调机组厂家最新推荐,实力品牌深度解析采购无忧之选!
  • 深耕代码质量,筑牢工程根基——《代码大全2》第四部分读后感
  • 2025年度工部优选十大品牌排名:工部优选的十个领先品牌是什
  • 停止背诵 API:AI 时代,代码只是你的“外设”
  • 2025国产冻干机品牌TOP5权威推荐:实验室冻干设备甄选指
  • 2025年靠谱的心理智能体开发专业公司排名:售后完善、诚信企
  • VFox版本管理工具使用教程
  • unprofitable25,5
  • FileGDB代码示例
  • 04-用户界面与交互系统
  • 玻璃反应釜生产厂TOP5权威推荐:专业选型、价格解析与低温适
  • 2025年安徽乡村别墅建造公司推荐:方合乡墅的后期维护成本高
  • 切片简介
  • 在Ubuntu WSL2里配置GDAL Docker环境
  • 2025年十大公寓床实力厂商排行榜,高校公寓床生产企业推荐