mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-22 00:46:48 +08:00
Add SizeType Support for DataGrid
This commit is contained in:
@@ -34,6 +34,15 @@ public class DataGridCell : ContentControl
|
||||
#endregion
|
||||
|
||||
#region 内部属性定义
|
||||
|
||||
internal static readonly StyledProperty<SizeType> SizeTypeProperty =
|
||||
SizeTypeAwareControlProperty.SizeTypeProperty.AddOwner<DataGridCell>();
|
||||
|
||||
internal SizeType SizeType
|
||||
{
|
||||
get => GetValue(SizeTypeProperty);
|
||||
set => SetValue(SizeTypeProperty, value);
|
||||
}
|
||||
|
||||
internal DataGridRow? OwningRow { get; set; }
|
||||
|
||||
|
||||
@@ -66,10 +66,7 @@ public abstract partial class DataGridColumn
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_headerCell == null)
|
||||
{
|
||||
_headerCell = CreateHeader();
|
||||
}
|
||||
_headerCell ??= CreateHeader();;
|
||||
return _headerCell;
|
||||
}
|
||||
}
|
||||
@@ -239,9 +236,10 @@ public abstract partial class DataGridColumn
|
||||
{
|
||||
OwningColumn = this
|
||||
};
|
||||
Debug.Assert(OwningGrid != null);
|
||||
result[!ContentControl.ContentProperty] = this[!HeaderProperty];
|
||||
result[!ContentControl.ContentTemplateProperty] = this[!HeaderTemplateProperty];
|
||||
Debug.Assert(OwningGrid != null);
|
||||
result[!DataGridColumnHeader.SizeTypeProperty] = OwningGrid[!DataGrid.SizeTypeProperty];
|
||||
// TODO 需要审查,原则上我们 AtomUI 是不允许整体自定义的
|
||||
if (OwningGrid.ColumnHeaderTheme is { } columnTheme)
|
||||
{
|
||||
|
||||
@@ -64,6 +64,15 @@ public class DataGridColumnHeader : ContentControl
|
||||
#endregion
|
||||
|
||||
#region 内部属性定义
|
||||
|
||||
internal static readonly StyledProperty<SizeType> SizeTypeProperty =
|
||||
SizeTypeAwareControlProperty.SizeTypeProperty.AddOwner<DataGridColumnHeader>();
|
||||
|
||||
internal SizeType SizeType
|
||||
{
|
||||
get => GetValue(SizeTypeProperty);
|
||||
set => SetValue(SizeTypeProperty, value);
|
||||
}
|
||||
|
||||
internal DataGridColumn? OwningColumn { get; set; }
|
||||
|
||||
|
||||
@@ -8,8 +8,10 @@ using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics;
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Controls.Data;
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
@@ -161,6 +163,12 @@ public partial class DataGrid
|
||||
|
||||
internal ScrollBar? VerticalScrollBar => _vScrollBar;
|
||||
internal ScrollBar? HorizontalScrollBar => _hScrollBar;
|
||||
|
||||
Control IMotionAwareControl.PropertyBindTarget => this;
|
||||
Control IControlSharedTokenResourcesHost.HostControl => this;
|
||||
string IControlSharedTokenResourcesHost.TokenId => DataGridToken.ID;
|
||||
CompositeDisposable? IResourceBindingManager.ResourceBindingsDisposable => _resourceBindingsDisposable;
|
||||
private CompositeDisposable? _resourceBindingsDisposable;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -173,8 +181,7 @@ public partial class DataGrid
|
||||
/// some properties to be ordered at the beginning and some at the end.
|
||||
/// </remarks>
|
||||
private const int DefaultColumnDisplayOrder = 10000;
|
||||
|
||||
internal const double HorizontalGridLinesThickness = 1;
|
||||
|
||||
private const double MinimumRowHeaderWidth = 4;
|
||||
private const double MinimumColumnHeaderHeight = 4;
|
||||
internal const double MaximumStarColumnWidth = 10000;
|
||||
|
||||
@@ -6,7 +6,12 @@
|
||||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Controls.Data;
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Data;
|
||||
using AtomUI.Theme.Styling;
|
||||
using AtomUI.Theme.Utils;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
@@ -32,10 +37,17 @@ namespace AtomUI.Controls;
|
||||
[TemplatePart(DataGridTheme.TopRightCornerPart, typeof(ContentControl))]
|
||||
[TemplatePart(DataGridTheme.VerticalScrollbarPart, typeof(ScrollBar))]
|
||||
[PseudoClasses(StdPseudoClass.Invalid, DataGridPseudoClass.EmptyRows, DataGridPseudoClass.EmptyColumns)]
|
||||
public partial class DataGrid : TemplatedControl
|
||||
public partial class DataGrid : TemplatedControl,
|
||||
ISizeTypeAware,
|
||||
IMotionAwareControl,
|
||||
IControlSharedTokenResourcesHost,
|
||||
IResourceBindingManager
|
||||
{
|
||||
#region 公共属性定义
|
||||
|
||||
public static readonly StyledProperty<SizeType> SizeTypeProperty =
|
||||
SizeTypeAwareControlProperty.SizeTypeProperty.AddOwner<DataGrid>();
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the CanUserReorderColumns dependency property.
|
||||
/// </summary>
|
||||
@@ -107,6 +119,9 @@ public partial class DataGrid : TemplatedControl
|
||||
public static readonly StyledProperty<IBrush?> HorizontalGridLinesBrushProperty =
|
||||
AvaloniaProperty.Register<DataGrid, IBrush?>(nameof(HorizontalGridLinesBrush));
|
||||
|
||||
public static readonly StyledProperty<IBrush?> VerticalGridLinesBrushProperty =
|
||||
AvaloniaProperty.Register<DataGrid, IBrush?>(nameof(VerticalGridLinesBrush));
|
||||
|
||||
public static readonly StyledProperty<ScrollBarVisibility> HorizontalScrollBarVisibilityProperty =
|
||||
AvaloniaProperty.Register<DataGrid, ScrollBarVisibility>(nameof(HorizontalScrollBarVisibility));
|
||||
|
||||
@@ -159,9 +174,6 @@ public partial class DataGrid : TemplatedControl
|
||||
public static readonly StyledProperty<DataGridSelectionMode> SelectionModeProperty =
|
||||
AvaloniaProperty.Register<DataGrid, DataGridSelectionMode>(nameof(SelectionMode));
|
||||
|
||||
public static readonly StyledProperty<IBrush?> VerticalGridLinesBrushProperty =
|
||||
AvaloniaProperty.Register<DataGrid, IBrush?>(nameof(VerticalGridLinesBrush));
|
||||
|
||||
public static readonly StyledProperty<ScrollBarVisibility> VerticalScrollBarVisibilityProperty =
|
||||
AvaloniaProperty.Register<DataGrid, ScrollBarVisibility>(nameof(VerticalScrollBarVisibility));
|
||||
|
||||
@@ -209,6 +221,15 @@ public partial class DataGrid : TemplatedControl
|
||||
AvaloniaProperty.RegisterDirect<DataGrid, IDataGridCollectionView?>(nameof(CollectionView),
|
||||
o => o.CollectionView);
|
||||
|
||||
public static readonly StyledProperty<bool> IsMotionEnabledProperty
|
||||
= WaveSpiritAwareControlProperty.IsMotionEnabledProperty.AddOwner<DataGrid>();
|
||||
|
||||
public SizeType SizeType
|
||||
{
|
||||
get => GetValue(SizeTypeProperty);
|
||||
set => SetValue(SizeTypeProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that indicates whether the user can change
|
||||
/// the column display order by dragging column headers with the mouse.
|
||||
@@ -327,6 +348,15 @@ public partial class DataGrid : TemplatedControl
|
||||
set => SetValue(HorizontalGridLinesBrushProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="T:System.Windows.Media.Brush" /> that is used to paint grid lines separating columns.
|
||||
/// </summary>
|
||||
public IBrush? VerticalGridLinesBrush
|
||||
{
|
||||
get => GetValue(VerticalGridLinesBrushProperty);
|
||||
set => SetValue(VerticalGridLinesBrushProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that indicates how the horizontal scroll bar is displayed.
|
||||
/// </summary>
|
||||
@@ -437,15 +467,6 @@ public partial class DataGrid : TemplatedControl
|
||||
get => GetValue(SelectionModeProperty);
|
||||
set => SetValue(SelectionModeProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="T:System.Windows.Media.Brush" /> that is used to paint grid lines separating columns.
|
||||
/// </summary>
|
||||
public IBrush? VerticalGridLinesBrush
|
||||
{
|
||||
get => GetValue(VerticalGridLinesBrushProperty);
|
||||
set => SetValue(VerticalGridLinesBrushProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the template that is used when rendering the column headers.
|
||||
@@ -617,7 +638,13 @@ public partial class DataGrid : TemplatedControl
|
||||
/// <summary>
|
||||
/// Gets a list that contains the data items corresponding to the selected rows.
|
||||
/// </summary>
|
||||
public IList SelectedItems => _selectedItems as IList;
|
||||
public IList SelectedItems => _selectedItems;
|
||||
|
||||
public bool IsMotionEnabled
|
||||
{
|
||||
get => GetValue(IsMotionEnabledProperty);
|
||||
set => SetValue(IsMotionEnabledProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -814,6 +841,8 @@ public partial class DataGrid : TemplatedControl
|
||||
HorizontalScrollBarVisibilityProperty,
|
||||
VerticalScrollBarVisibilityProperty);
|
||||
|
||||
SizeTypeProperty.OverrideDefaultValue<DataGrid>(SizeType.Large);
|
||||
|
||||
ItemsSourceProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.HandleItemsSourcePropertyChanged(e));
|
||||
CanUserResizeColumnsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.HandleCanUserResizeColumnsChanged(e));
|
||||
ColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.HandleColumnWidthChanged(e));
|
||||
@@ -841,6 +870,8 @@ public partial class DataGrid : TemplatedControl
|
||||
|
||||
public DataGrid()
|
||||
{
|
||||
this.RegisterResources();
|
||||
this.BindMotionProperties();
|
||||
KeyDown += HandleKeyDown;
|
||||
KeyUp += HandleKeyUp;
|
||||
|
||||
@@ -875,6 +906,7 @@ public partial class DataGrid : TemplatedControl
|
||||
RowGroupHeaderHeightEstimate = DefaultRowHeight;
|
||||
RowGroupSublevelIndents = [];
|
||||
_rowGroupHeightsByLevel = [];
|
||||
_resourceBindingsDisposable = new CompositeDisposable();
|
||||
UpdatePseudoClasses();
|
||||
}
|
||||
|
||||
@@ -1030,6 +1062,10 @@ public partial class DataGrid : TemplatedControl
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToVisualTree(e);
|
||||
this.AddResourceBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, BorderThicknessProperty,
|
||||
SharedTokenKey.BorderThickness,
|
||||
BindingPriority.Template,
|
||||
new RenderScaleAwareThicknessConfigure(this)));
|
||||
if (DataConnection.DataSource != null && !DataConnection.EventsWired)
|
||||
{
|
||||
DataConnection.WireEvents(DataConnection.DataSource);
|
||||
@@ -1045,6 +1081,7 @@ public partial class DataGrid : TemplatedControl
|
||||
{
|
||||
DataConnection.UnWireEvents(DataConnection.DataSource);
|
||||
}
|
||||
this.DisposeTokenBindings();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -48,7 +48,8 @@ public partial class DataGridRow
|
||||
if (_bottomGridLine != null && OwningGrid != null && OwningGrid.AreRowBottomGridLinesRequired)
|
||||
{
|
||||
// Unfortunately, _bottomGridLine has no size yet so we can't get its actualheight
|
||||
return DataGrid.HorizontalGridLinesThickness;
|
||||
// TODO 需要审查这里不是常量可以吗?是不是会导致高度计算错误
|
||||
return OwningGrid.BorderThickness.Left;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Shapes;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Styling;
|
||||
using HorizontalAlignment = Avalonia.Layout.HorizontalAlignment;
|
||||
using VerticalAlignment = Avalonia.Layout.VerticalAlignment;
|
||||
|
||||
@@ -131,4 +132,13 @@ internal class DataGridCellTheme : BaseControlTheme
|
||||
Grid.SetColumn(focusVisualLayout, 0);
|
||||
rootLayout.Children.Add(focusVisualLayout);
|
||||
}
|
||||
|
||||
protected override void BuildStyles()
|
||||
{
|
||||
var commonStyle = new Style(selector => selector.Nesting());
|
||||
commonStyle.Add(DataGridCell.HorizontalAlignmentProperty, HorizontalAlignment.Stretch);
|
||||
commonStyle.Add(DataGridCell.VerticalAlignmentProperty, VerticalAlignment.Stretch);
|
||||
commonStyle.Add(DataGridCell.FocusableProperty, false);
|
||||
Add(commonStyle);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using AtomUI.IconPkg;
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Styling;
|
||||
using Avalonia.Controls;
|
||||
@@ -6,6 +7,7 @@ using Avalonia.Controls.Shapes;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Styling;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
@@ -39,6 +41,7 @@ internal class DataGridColumnHeaderTheme : BaseControlTheme
|
||||
{
|
||||
Name = HeaderFramePart
|
||||
};
|
||||
CreateTemplateParentBinding(headerFrame, Border.BackgroundProperty, DataGridColumnHeader.BackgroundProperty);
|
||||
|
||||
var headerRootLayout = new Grid
|
||||
{
|
||||
@@ -70,7 +73,6 @@ internal class DataGridColumnHeaderTheme : BaseControlTheme
|
||||
|
||||
private void BuildContentPresenter(Grid rootLayout)
|
||||
{
|
||||
var contentPresenterLayout = new Panel();
|
||||
var gridLayout = new Grid()
|
||||
{
|
||||
ColumnDefinitions =
|
||||
@@ -79,7 +81,8 @@ internal class DataGridColumnHeaderTheme : BaseControlTheme
|
||||
new ColumnDefinition(GridLength.Auto),
|
||||
]
|
||||
};
|
||||
|
||||
CreateTemplateParentBinding(gridLayout, Grid.HorizontalAlignmentProperty, DataGridColumnHeader.HorizontalAlignmentProperty);
|
||||
CreateTemplateParentBinding(gridLayout, Grid.VerticalAlignmentProperty, DataGridColumnHeader.VerticalAlignmentProperty);
|
||||
var contentPresenter = new ContentPresenter()
|
||||
{
|
||||
Name = ContentPresenterPart,
|
||||
@@ -89,27 +92,24 @@ internal class DataGridColumnHeaderTheme : BaseControlTheme
|
||||
Grid.SetColumn(contentPresenter, 0);
|
||||
gridLayout.Children.Add(contentPresenter);
|
||||
|
||||
var iconPresenter = new ContentPresenter()
|
||||
var iconPresenter = new IconPresenter()
|
||||
{
|
||||
Name = SortIconPresenterPart,
|
||||
IsVisible = false,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
IsVisible = false
|
||||
};
|
||||
Grid.SetColumn(iconPresenter, 1);
|
||||
gridLayout.Children.Add(iconPresenter);
|
||||
|
||||
contentPresenterLayout.Children.Add(gridLayout);
|
||||
Grid.SetColumn(rootLayout, 0);
|
||||
rootLayout.Children.Add(contentPresenterLayout);
|
||||
|
||||
Grid.SetColumn(gridLayout, 0);
|
||||
rootLayout.Children.Add(gridLayout);
|
||||
}
|
||||
|
||||
private void BuildFocusVisual(Grid rootLayout)
|
||||
{
|
||||
var focusVisualLayout = new Grid()
|
||||
var focusVisualLayout = new Panel()
|
||||
{
|
||||
IsVisible = false,
|
||||
Name = FocusVisualPart,
|
||||
Name = FocusVisualPart,
|
||||
IsVisible = false,
|
||||
IsHitTestVisible = false,
|
||||
};
|
||||
|
||||
@@ -138,4 +138,15 @@ internal class DataGridColumnHeaderTheme : BaseControlTheme
|
||||
Grid.SetColumn(focusVisualLayout, 0);
|
||||
rootLayout.Children.Add(focusVisualLayout);
|
||||
}
|
||||
|
||||
protected override void BuildStyles()
|
||||
{
|
||||
var commonStyle = new Style(selector => selector.Nesting());
|
||||
commonStyle.Add(DataGridColumnHeader.ForegroundProperty, DataGridTokenKey.TableHeaderTextColor);
|
||||
commonStyle.Add(DataGridColumnHeader.BackgroundProperty, DataGridTokenKey.TableHeaderBg);
|
||||
commonStyle.Add(DataGridColumnHeader.FontWeightProperty, SharedTokenKey.FontWeightStrong);
|
||||
commonStyle.Add(DataGridColumnHeader.HorizontalContentAlignmentProperty, HorizontalAlignment.Left);
|
||||
commonStyle.Add(DataGridColumnHeader.VerticalContentAlignmentProperty, VerticalAlignment.Center);
|
||||
Add(commonStyle);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Shapes;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Data.Converters;
|
||||
using Avalonia.Input.GestureRecognizers;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Styling;
|
||||
@@ -82,8 +84,11 @@ internal class DataGridTheme : BaseControlTheme
|
||||
{
|
||||
Name = ColumnHeadersAndRowsSeparatorPart,
|
||||
VerticalAlignment = VerticalAlignment.Bottom,
|
||||
Height = 1
|
||||
};
|
||||
|
||||
CreateTemplateParentBinding(columnHeadersAndRowsSeparator, Rectangle.HeightProperty, DataGrid.BorderThicknessProperty,
|
||||
BindingMode.Default, new FuncValueConverter<Thickness, double>(thickness => thickness.Left));
|
||||
|
||||
Grid.SetRow(columnHeadersAndRowsSeparator, 0);
|
||||
Grid.SetColumn(columnHeadersAndRowsSeparator, 0);
|
||||
Grid.SetColumnSpan(columnHeadersAndRowsSeparator, 3);
|
||||
@@ -188,6 +193,13 @@ internal class DataGridTheme : BaseControlTheme
|
||||
commonStyle.Add(DataGrid.VerticalScrollBarVisibilityProperty, ScrollBarVisibility.Auto);
|
||||
commonStyle.Add(DataGrid.SelectionModeProperty, DataGridSelectionMode.Extended);
|
||||
commonStyle.Add(DataGrid.FocusAdornerProperty, null);
|
||||
commonStyle.Add(DataGrid.HorizontalGridLinesBrushProperty, DataGridTokenKey.TableBorderColor);
|
||||
commonStyle.Add(DataGrid.VerticalGridLinesBrushProperty, DataGridTokenKey.TableBorderColor);
|
||||
|
||||
var columnHeadersAndRowsSeparatorStyle = new Style(selector => selector.Nesting().Template().Name(ColumnHeadersAndRowsSeparatorPart));
|
||||
columnHeadersAndRowsSeparatorStyle.Add(Rectangle.FillProperty, DataGridTokenKey.TableBorderColor);
|
||||
commonStyle.Add(columnHeadersAndRowsSeparatorStyle);
|
||||
|
||||
Add(commonStyle);
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using Avalonia.VisualTree;
|
||||
|
||||
namespace AtomUI.Theme.Data;
|
||||
|
||||
internal class RenderScaleAwareThicknessConfigure
|
||||
public class RenderScaleAwareThicknessConfigure
|
||||
{
|
||||
private readonly WeakReference<Control> _control;
|
||||
private readonly Func<Thickness, Thickness>? _postProcessor;
|
||||
|
||||
@@ -2,7 +2,7 @@ using Avalonia.Controls;
|
||||
|
||||
namespace AtomUI.Theme;
|
||||
|
||||
internal interface IControlSharedTokenResourcesHost
|
||||
public interface IControlSharedTokenResourcesHost
|
||||
{
|
||||
Control HostControl { get; }
|
||||
string TokenId { get; }
|
||||
|
||||
@@ -5,7 +5,7 @@ using Avalonia.LogicalTree;
|
||||
|
||||
namespace AtomUI.Theme.Utils;
|
||||
|
||||
internal static class ControlSharedTokenResourcesHostExtensions
|
||||
public static class ControlSharedTokenResourcesHostExtensions
|
||||
{
|
||||
public static void RegisterResources(this IControlSharedTokenResourcesHost host)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user