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

Avalonia 中多个 Grid 实现 SharedSizeGroup

一、前情提要

在编写 Collections 软件时,需要一个能够显示资源元数据的展示表格,样式参考了某个网站,主要特征为键值对应、键元素共享宽度、右对齐键、左对齐值、无边框、无选中标识。

<!-- 示例代码 -->
<!DOCTYPE html>
<html lang="en">
<style>table#work_outline {font-size: 13px;line-height: 1.4;}tbody {display: table-row-group;vertical-align: middle;unicode-bidi: isolate;border-color: inherit;}tr {display: table-row;vertical-align: inherit;unicode-bidi: isolate;border-color: inherit;}table#work_outline th {min-width: 100px;height: 22px;padding: 0 6px 0 0;box-sizing: border-box;}table#work_outline th {text-align: right;vertical-align: top;white-space: nowrap;}table#work_outline td {vertical-align: top;padding-bottom: 2px;}
</style>
<body><table id="work_outline"><tr><th>Company</th><td>Contact</td></tr><tr><th>Alfreds Futterkiste</th><td>Maria Anders</td></tr><tr><th>Centro comercial Moctezuma</th><td>Francisco Chang</td></tr>
</table></body>
</html>

二、失败案例

在 Avalonia 中,对应的表格实现有 DataGrid 、 ItemsControl 、 Grid 等。

1、 DataGrid

DataGrid 是一个复杂的表格控件,因为需要修改较多样式才能达到目标效果(未实际验证过),所以到目前为止不在考虑中。

2、 ItemsControl

ItemsControl 是一个基础的数据展示控件,需要自行定义要显示的样式、在什么面板中显示,是最先考虑使用的。

(1)模板内部为 Grid

<ItemsControl ItemsSource="{Binding Directories}"><ItemsControl.ItemTemplate><DataTemplate><Grid ColumnDefinitions="Auto,Auto,*"Margin="0 4"><SelectableTextBlock Grid.Column="0"Text="{Binding Key}" TextAlignment="Right"MinWidth="100"/><TextBlock Grid.Column="1"Text=":"Margin="8 0" /><ItemsControl Grid.Column="2"ItemsSource="{Binding Value,Converter={StaticResource JsonToListConverter}}"><ItemsControl.ItemsPanel><ItemsPanelTemplate><WrapPanel Orientation="Horizontal"/></ItemsPanelTemplate></ItemsControl.ItemsPanel><ItemsControl.ItemTemplate><DataTemplate><SelectableTextBlock Text="{Binding}"Margin="0 0 4 0" ><SelectableTextBlock.Styles><Style Selector="SelectableTextBlock:pointerover"><Setter Property="Foreground"Value="{DynamicResource SemiColorLinkPointerover}" /><Setter Property="Cursor" Value="Hand"/></Style></SelectableTextBlock.Styles></SelectableTextBlock></DataTemplate></ItemsControl.ItemTemplate></ItemsControl></Grid></DataTemplate></ItemsControl.ItemTemplate>
</ItemsControl>

在搭建时,最早是使用内部为 Grid 的方式,打算靠 Grid 自身内部对齐的特性实现。问题在于 ItemsControl 的每一个 Item 均包裹在 ContentPresenter 中,其 DataTemplate 中的 Grid 并不共享键元素的最大宽度,最终设置键元素的最小宽度,使其看起来右对齐了,如果字体大小变化、字数增加等情况下,该方案呈现的效果不符合目标。

(2)模板内部为 StackPanel

<ItemsControl ItemsSource="{Binding Directories}"><ItemsControl.ItemTemplate><DataTemplate><StackPanel Orientation="Horizontal"Margin="0 0 0 8"><TextBlock Text="{Binding Key, StringFormat={}{0}:}"Width="120"TextAlignment="Right" /><ItemsControl ItemsSource="{Binding Value}"><ItemsControl.ItemTemplate><DataTemplate><TextBlock Text="{Binding Value}"/></DataTemplate></ItemsControl.ItemTemplate><ItemsControl.ItemsPanel><ItemsPanelTemplate><WrapPanel ItemSpacing="10" /></ItemsPanelTemplate></ItemsControl.ItemsPanel></ItemsControl></StackPanel></DataTemplate></ItemsControl.ItemTemplate>
</ItemsControl>

这个方案是在上一个方案中优化而来,既然 DataTemplate 中的 Grid 并不共享键元素的最大宽度,那干脆固定键元素的宽度,同时将 Grid 简化为 StackPanel ,遇到的问题实质上与上一个是一样的。

3、 Grid

Grid 本身并不提供像 ItemsControl 那样自动显示数据的能力,如果是固定显示的内容,可以使用该控件进行简单展示。

三、灵感来源

在使用 Irihi.Ursa 中的 Form 控件时,发现该控件满足键值对应、键元素共享宽度、无边框、无选中标识,本想直接使用该控件的,但该控件是一个较为复杂的控件,有着预定义的样式,且主要承担表单输入快速实现的功能,与 DataGrid 一样,需要修改较多样式才能实现目标效果,最终并未选择该控件。

在修改 Form 控件的模板样式以达到预期效果的过程中,注意到了两个不同寻常的属性: Grid.IsSharedSizeScope 、 SharedSizeGroup 。

<ControlTheme x:Key="{x:Type Form}"TargetType="Form"><Style Selector="^:fixed-width"><Setter Property="Grid.IsSharedSizeScope" Value="True" /></Style>
</ControlTheme>
<Style Selector="^:not(:no-label):horizontal"><Setter Property="Template"><ControlTemplate TargetType="FormItem"><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="Auto" SharedSizeGroup="Label" /><ColumnDefinition Width="*" /></Grid.ColumnDefinitions><BorderGrid.Row="0"Grid.Column="0"Width="{TemplateBinding LabelWidth}"><!-- Content --></Border><ContentPresenterName="PART_ContentPresenter"Grid.Row="0"Grid.Column="1"VerticalAlignment="Stretch"VerticalContentAlignment="Center"ContentTemplate="{TemplateBinding ContentTemplate}"Content="{TemplateBinding Content}" /></Grid></ControlTemplate></Setter>
</Style>

四、属性解析

(1) Grid.IsSharedSizeScope

该属性是附加属性,值为 bool 类型,默认为 false , true 为开启状态,效果为附加了该属性的控件下的所有 Grid 可以共享 Size 。

(2) SharedSizeGroup

该属性是 Grid 内部的 ColumnDefinition 和 RowDefinition 的属性,值为 string? 类型,效果为同一个分组名共享 Size ,需要和 Grid.IsSharedSizeScope 附加属性配合,类似于 RadioButton 的 GroupName 。

五、最终实现

<ItemsControl ItemsSource="{Binding Metadata}"Grid.IsSharedSizeScope="True"><ItemsControl.ItemTemplate><DataTemplate><Grid Margin="0 8"><Grid.ColumnDefinitions><ColumnDefinition Width="Auto" SharedSizeGroup="Label"/><ColumnDefinition Width="*" /></Grid.ColumnDefinitions><TextBlock Grid.Column="0"Text="{Binding Name, StringFormat={}{0}:}" TextAlignment="Right"HorizontalAlignment="Stretch"/><ItemsControl Grid.Column="1"ItemsSource="{Binding Items}"><ItemsControl.ItemTemplate><DataTemplate><TextBlock Text="{Binding Value}"/></DataTemplate></ItemsControl.ItemTemplate><ItemsControl.ItemsPanel><ItemsPanelTemplate><WrapPanel ItemSpacing="10"LineSpacing="4"/></ItemsPanelTemplate></ItemsControl.ItemsPanel></ItemsControl></Grid></DataTemplate></ItemsControl.ItemTemplate>
</ItemsControl>
http://www.jsqmd.com/news/382623/

相关文章:

  • 市场竞争中的博弈论模型:价格战、信息博弈与企业长期策略
  • 【C#高级】TCP请求-应答模式的WPF应用实战 - 实践
  • BISHI46 小红的魔法药剂
  • 格雷厄姆特价股票策略在不同市场信息不对称下的表现
  • 2026年2月西安防控眼镜配镜店推荐,三维数据透视专业防控机构 - 品牌鉴赏师
  • 2026年2月贵阳高散眼镜配镜时尚眼镜店推荐,复杂散光精准适配指南 - 品牌鉴赏师
  • 题解:P6961 [NEERC 2017] Journey from Petersburg to Moscow
  • 题解:P12213 [蓝桥杯 2023 国 Python B] 最长回文前后缀
  • 沃尔玛购物卡怎么处理划算?这些妙招让你轻松回血! - 京顺回收
  • 想用U盘,必须使用windows7
  • 数字员工推动AI销冠系统与AI提效软件系统实现高效业务转型
  • 教鞭神器,网课老师必备
  • 北方水垢重灾区选购建议:2026 强力阻垢净水器排行,菲浦斯领先 - 水业策论
  • AutoGLM-Phone 9B 端侧智能体:基于 vLLM 与 Docker 的云端部署与 ADB 联调指南 - 实践
  • Win11关闭自动更新,windows11如何永久禁止自动更新
  • GTK4 GObject深度剖析
  • 【高效】Win11如何禁止系统自动更新 Win11关闭系统自动更新的方法
  • Zig 简介:C 的现代化继任者
  • 【信息科学与工程学】信息科学领域第四十八篇 计量工程
  • 智慧交通沥青路面损伤缺陷检测数据集VOC+YOLO格式547张4类别
  • web ui 测试显式等待深度解析
  • 题解:P15301 [ROI 2012 Day 2] army 汗国军队
  • CMake:现代C/C++工程的构建中枢
  • web ui 测试隐式等待深度解析
  • web ui 测试智能等待深度解析
  • Hive SQL优化:分区表+分桶表提升查询效率
  • 医疗仪器整机研发设计怎么做?2026创新合规智能化趋势指南|新纪元必读 - 匠言榜单
  • Nightwatch.js深度解析
  • 【Docker进阶篇】Docker Compose 实战:一键启动Web+数据库+缓存,微服务环境部署不再绕弯
  • C++中链表的虚拟头结点:应用场景与运用时机