Avalonia如何实现一个可调整大小的Grid分割线 Avalonia GridSplitter

Avalonia 中可通过 Thumb 控件模拟 GridSplitter:将 Thumb 置于 Grid 行/列交界处,设固定宽高与对应光标,监听 DragDelta 动态调整相邻行列尺寸,并添加最小尺寸约束、悬停反馈及吸附等增强体验。

Avalonia 中没有内置的 GridSplitter 控件(不像 WPF),但可以通过组合 GridThumb 和绑定逻辑,轻松实现功能等效的可拖拽分割线。

使用 Thumb 实现分割线核心机制

Thumb 是 Avalonia 提供的用于拖拽操作的基础控件,适合做分割线手柄。它会触发 DragDelta 事件,通过监听鼠标移动偏移量,动态调整相邻行或列的尺寸。

  • Thumb 放在目标行列交界处(例如 Grid 的第1列、第2行)
  • 设置 WidthHeight 为固定值(如 4 或 6)

    ,背景设为可见色或透明(配合 Cursor 提示)
  • 设置 Cursor="SizeWE"(水平分割)或 Cursor="SizeNS"(垂直分割)提升交互感

水平分割线(调整行高)示例

以下 XAML 在两行之间插入一个可上下拖动的分割线:


  
    
     
    
  

在代码后台中处理 DragDelta

private void OnRowSplitterDragDelta(object sender, VectorEventArgs e)
{
    var grid = this.FindControl("MyGrid"); // 假设 Grid 有 Name
    var row0 = grid.RowDefinitions[0];
    var row1 = grid.RowDefinitions[2]; // 注意:中间是 Thumb 行,跳过
// 约束最小高度(例如 50)
var newHeight0 = Math.Max(50, row0.Height.Value + e.Vector.Y);
var newHeight2 = Math.Max(50, row1.Height.Value - e.Vector.Y);

row0.Height = new GridLength(newHeight0, GridUnitType.Pixel);
row1.Height = new GridLength(newHeight2, GridUnitType.Pixel);

}

垂直分割线(调整列宽)原理相同

只需改为横向布局:ColumnDefinitionsThumb.Width 固定、Cursor="SizeWE",并在 DragDelta 中修改左右两列的 Width,注意避开 Thumb 所在列(通常设为 Auto 或固定宽度)。

  • 推荐将 Thumb 所在列为 Width="4",不参与比例分配
  • GridLength.UnitType.Pixel 保持绝对尺寸控制,避免 * 单位干扰
  • 若需响应式保存/恢复分割位置,可绑定到 ViewModel 的 double 属性并双向更新

增强体验的小技巧

让分割线更专业、易用:

  • 添加 PointerEntered/PointerExited 事件,悬停时高亮或加边框
  • 按住 Alt 键拖动时启用“吸附”(如对齐到 10px 倍数),提升精度
  • 分割线两侧区域建议设置 MinHeight/MinWidth,防止拖至消失
  • 若 Grid 嵌套较深,确保 Thumb 的 ZIndex 足够高,避免被遮挡