Add DataGrid Column reorder

This commit is contained in:
chinboy
2025-07-14 22:02:28 +08:00
parent 13e04caa01
commit f7573fcbc7
7 changed files with 117 additions and 9 deletions
@@ -613,15 +613,10 @@ internal partial class DataGridColumnHeader : ContentControl
foreach (DataGridColumn column in OwningGrid.ColumnsInternal.GetVisibleColumns())
{
Point mousePosition = OwningGrid.ColumnHeaders.Translate(column.HeaderCell, mousePositionHeaders);
double columnMiddle = column.HeaderCell.Bounds.Width / 2;
if (mousePosition.X >= 0 && mousePosition.X <= columnMiddle)
if (mousePosition.X >= 0 && mousePosition.X <= column.HeaderCell.Bounds.Width)
{
return column;
}
if (mousePosition.X > columnMiddle && mousePosition.X < column.HeaderCell.Bounds.Width)
{
return OwningGrid.ColumnsInternal.GetNextVisibleColumn(column);
}
}
return null;
@@ -639,7 +634,7 @@ internal partial class DataGridColumnHeader : ContentControl
DataGridColumn? targetColumn = GetReorderingTargetColumn(mousePositionHeaders, false /*scroll*/, out double scrollAmount);
if (targetColumn != null)
{
return targetColumn.DisplayIndex > OwningColumn.DisplayIndex ? targetColumn.DisplayIndex - 1 : targetColumn.DisplayIndex;
return targetColumn.DisplayIndex;
}
return OwningGrid.Columns.Count - 1;
}
@@ -0,0 +1,87 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Documents;
using Avalonia.Media;
namespace AtomUI.Controls;
internal class DataGridDraggingOverIndicator : Control
{
internal static readonly DirectProperty<DataGridDraggingOverIndicator, DataGridColumn?> DraggingOverColumnProperty =
AvaloniaProperty.RegisterDirect<DataGridDraggingOverIndicator, DataGridColumn?>(
nameof(DraggingOverColumn),
o => o.DraggingOverColumn,
(o, v) => o.DraggingOverColumn = v);
internal static readonly DirectProperty<DataGridDraggingOverIndicator, DataGridColumn?> DraggedColumnProperty =
AvaloniaProperty.RegisterDirect<DataGridDraggingOverIndicator, DataGridColumn?>(
nameof(DraggedColumn),
o => o.DraggedColumn,
(o, v) => o.DraggedColumn = v);
internal DataGridColumn? DraggingOverColumn
{
get => _draggingOverColumn;
set => SetAndRaise(DraggingOverColumnProperty, ref _draggingOverColumn, value);
}
private DataGridColumn? _draggingOverColumn;
internal DataGridColumn? DraggedColumn
{
get => _draggedColumn;
set => SetAndRaise(DraggedColumnProperty, ref _draggedColumn, value);
}
private DataGridColumn? _draggedColumn;
static DataGridDraggingOverIndicator()
{
AffectsRender<DataGridDraggingOverIndicator>(DraggingOverColumnProperty, DraggedColumnProperty);
}
private double _indicatorOffsetX;
private double _indicatorLineWidth = 1.0;
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == DraggingOverColumnProperty ||
change.Property == DraggedColumnProperty)
{
CalculateIndicatorOffset();
}
}
private void CalculateIndicatorOffset()
{
if (DraggingOverColumn != null && DraggedColumn != null)
{
var offset = DraggingOverColumn.HeaderCell.TranslatePoint(new Point(0, 0), this);
if (offset.HasValue)
{
var headerSize = DraggingOverColumn.HeaderCell.Bounds.Size;
if (DraggedColumn.DisplayIndex < DraggingOverColumn.DisplayIndex)
{
_indicatorOffsetX = offset.Value.X + headerSize.Width;
}
else
{
_indicatorOffsetX = offset.Value.X;
}
}
}
}
public override void Render(DrawingContext context)
{
if (DraggingOverColumn != null)
{
using var state = context.PushRenderOptions(new RenderOptions
{
EdgeMode = EdgeMode.Aliased
});
var startPoint = new Point(_indicatorOffsetX, 0);
var endPoint = new Point(_indicatorOffsetX, Bounds.Height);
context.DrawLine(new Pen(TextElement.GetForeground(this), _indicatorLineWidth, DashStyle.Dash), startPoint, endPoint);
}
}
}
@@ -105,6 +105,7 @@ public partial class DataGrid
private DataGridColumnHeadersPresenter? _columnHeadersPresenter;
private DataGridGroupColumnHeadersPresenter? _groupColumnHeadersPresenter;
private DataGridDraggingOverIndicator? _dataGridDraggingOverIndicator;
protected virtual void NotifyColumnDisplayIndexChanged(DataGridColumnEventArgs e)
{
@@ -124,6 +125,22 @@ public partial class DataGrid
protected internal virtual void NotifyColumnDraggingOver(DataGridColumnDraggingOverEventArgs e)
{
if (_dataGridDraggingOverIndicator != null)
{
if (e.DraggedColumn != null && e.DraggingOverColumn != null && e.DraggedColumn != e.DraggingOverColumn)
{
_dataGridDraggingOverIndicator.IsVisible = true;
_dataGridDraggingOverIndicator.DraggingOverColumn = e.DraggingOverColumn;
_dataGridDraggingOverIndicator.DraggedColumn = e.DraggedColumn;
}
else
{
_dataGridDraggingOverIndicator.IsVisible = false;
_dataGridDraggingOverIndicator.DraggingOverColumn = null;
_dataGridDraggingOverIndicator.DraggedColumn = null;
}
}
ColumnDraggingOver?.Invoke(this, e);
}
@@ -11,7 +11,6 @@ using System.Diagnostics;
using System.Reactive.Disposables;
using AtomUI.Controls.Data;
using AtomUI.Controls.Utils;
using AtomUI.Data;
using AtomUI.Theme;
using AtomUI.Utils;
using Avalonia;
@@ -32,6 +31,7 @@ public partial class DataGrid
internal const bool DefaultCanUserSortColumns = false;
internal const bool DefaultCanUserFilterColumns = false;
internal const bool DefaultShowSorterTooltip = false;
internal const int DraggingOverIndicatorZIndex = 1000;
#region 内部属性定义
+1 -1
View File
@@ -1404,7 +1404,7 @@ public partial class DataGrid : TemplatedControl,
_columnHeadersPresenter =
e.NameScope.Find<DataGridColumnHeadersPresenter>(DataGridThemeConstants.ColumnHeadersPresenterPart);
_groupColumnHeadersPresenter = e.NameScope.Find<DataGridGroupColumnHeadersPresenter>(DataGridThemeConstants.GroupColumnHeadersPresenterPart);
_dataGridDraggingOverIndicator = e.NameScope.Find<DataGridDraggingOverIndicator>(DataGridThemeConstants.DraggingOverIndicatorPart);
if (_groupColumnHeadersPresenter != null)
{
_groupColumnHeadersPresenter.OwningGrid = this;
@@ -103,6 +103,14 @@
VerticalAlignment="Stretch"
CornerRadius="{TemplateBinding HeaderCornerRadius}"
IsEnabled="{TemplateBinding IsEnabled}" />
<atom:DataGridDraggingOverIndicator
Name="{x:Static atom:DataGridThemeConstants.DraggingOverIndicatorPart}"
Grid.Row="1"
Grid.Column="0"
Grid.RowSpan="2"
Grid.ColumnSpan="3"
IsVisible="False"/>
</Grid>
</DockPanel>
@@ -102,6 +102,7 @@ internal static class DataGridThemeConstants
public const string DisabledVisualElementPart = "PART_DisabledVisualElement";
public const string TitlePart = "PART_Title";
public const string FooterPart = "PART_Footer";
public const string DraggingOverIndicatorPart = "PART_DraggingOverIndicator";
}
internal static class DataGridTopLeftColumnHeaderThemeConstants