From fe6a735c6f375cf985a36cd8135efd88cc991c54 Mon Sep 17 00:00:00 2001 From: Maksym Katsydan Date: Tue, 18 Aug 2020 14:11:41 -0400 Subject: [PATCH 1/8] Create DataGrid Fluent.xaml theme based on Default --- samples/ControlCatalog/App.xaml | 3 +- samples/ControlCatalog/App.xaml.cs | 14 + .../Themes/Fluent.xaml | 294 ++++++++++++++++++ 3 files changed, 309 insertions(+), 2 deletions(-) create mode 100644 src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml diff --git a/samples/ControlCatalog/App.xaml b/samples/ControlCatalog/App.xaml index bab57f3544..9bac320c79 100644 --- a/samples/ControlCatalog/App.xaml +++ b/samples/ControlCatalog/App.xaml @@ -1,8 +1,7 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 60546c68de3b9c4549a37c33d9c00494377de0df Mon Sep 17 00:00:00 2001 From: Maksym Katsydan Date: Thu, 20 Aug 2020 02:13:17 -0400 Subject: [PATCH 2/8] DataGrid: implement missed pseudoclasses --- src/Avalonia.Controls.DataGrid/DataGrid.cs | 4 ++-- .../DataGridCell.cs | 11 ++++++++++ .../DataGridColumnHeader.cs | 13 ++++++------ .../DataGridDataConnection.cs | 2 +- src/Avalonia.Controls.DataGrid/DataGridRow.cs | 8 +++---- .../DataGridRowGroupHeader.cs | 20 +++++++++++------- .../DataGridRowHeader.cs | 21 ++++++++++++++++--- .../DataGridRows.cs | 2 +- 8 files changed, 57 insertions(+), 24 deletions(-) diff --git a/src/Avalonia.Controls.DataGrid/DataGrid.cs b/src/Avalonia.Controls.DataGrid/DataGrid.cs index 7e921944ea..78c696a3ba 100644 --- a/src/Avalonia.Controls.DataGrid/DataGrid.cs +++ b/src/Avalonia.Controls.DataGrid/DataGrid.cs @@ -2753,7 +2753,7 @@ namespace Avalonia.Controls //We don't need to refresh the state of AutoGenerated column headers because they're up-to-date if (!column.IsAutoGenerated && column.HasHeaderCell) { - column.HeaderCell.ApplyState(); + column.HeaderCell.UpdatePseudoClasses(); } } @@ -5417,7 +5417,7 @@ namespace Avalonia.Controls } else if (displayedElement is DataGridRowGroupHeader groupHeader) { - groupHeader.ApplyState(useTransitions: true); + groupHeader.UpdatePseudoClasses(); if (AreRowHeadersVisible) { groupHeader.ApplyHeaderStatus(); diff --git a/src/Avalonia.Controls.DataGrid/DataGridCell.cs b/src/Avalonia.Controls.DataGrid/DataGridCell.cs index 3973f1e86f..99efc5743d 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridCell.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridCell.cs @@ -180,7 +180,18 @@ namespace Avalonia.Controls internal void UpdatePseudoClasses() { + if (OwningGrid == null || OwningColumn == null || OwningRow == null || !OwningRow.IsVisible || OwningRow.Slot == -1) + { + return; + } + + PseudoClasses.Set(":selected", OwningRow.IsSelected); + + PseudoClasses.Set(":current", IsCurrent); + + PseudoClasses.Set(":edited", IsEdited); + // PseudoClasses.Set(":invalid", !IsValid); } // Makes sure the right gridline has the proper stroke and visibility. If lastVisibleColumn is specified, the diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs index e6cc7e5e40..c6e5e896a1 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs @@ -13,6 +13,7 @@ using System.Diagnostics; using Avalonia.Utilities; using System; using Avalonia.Controls.Utils; +using Avalonia.Controls.Mixins; namespace Avalonia.Controls { @@ -68,6 +69,7 @@ namespace Avalonia.Controls static DataGridColumnHeader() { AreSeparatorsVisibleProperty.Changed.AddClassHandler((x, e) => x.OnAreSeparatorsVisibleChanged(e)); + PressedMixin.Attach(); } /// @@ -149,8 +151,7 @@ namespace Avalonia.Controls } } - //TODO Implement - internal void ApplyState() + internal void UpdatePseudoClasses() { CurrentSortingState = null; if (OwningGrid != null @@ -441,7 +442,7 @@ namespace Avalonia.Controls Point mousePosition = e.GetPosition(this); OnMouseEnter(mousePosition); - ApplyState(); + UpdatePseudoClasses(); } private void DataGridColumnHeader_PointerLeave(object sender, PointerEventArgs e) @@ -452,7 +453,7 @@ namespace Avalonia.Controls } OnMouseLeave(); - ApplyState(); + UpdatePseudoClasses(); } private void DataGridColumnHeader_PointerPressed(object sender, PointerPressedEventArgs e) @@ -467,7 +468,7 @@ namespace Avalonia.Controls OnMouseLeftButtonDown(ref handled, e, mousePosition); e.Handled = handled; - ApplyState(); + UpdatePseudoClasses(); } private void DataGridColumnHeader_PointerReleased(object sender, PointerReleasedEventArgs e) @@ -483,7 +484,7 @@ namespace Avalonia.Controls OnMouseLeftButtonUp(ref handled, e, mousePosition, mousePositionHeaders); e.Handled = handled; - ApplyState(); + UpdatePseudoClasses(); } private void DataGridColumnHeader_PointerMove(object sender, PointerEventArgs e) diff --git a/src/Avalonia.Controls.DataGrid/DataGridDataConnection.cs b/src/Avalonia.Controls.DataGrid/DataGridDataConnection.cs index e21ee3be37..19539bf032 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridDataConnection.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridDataConnection.cs @@ -610,7 +610,7 @@ namespace Avalonia.Controls // refresh sort description foreach (DataGridColumn column in _owner.ColumnsItemsInternal) { - column.HeaderCell.ApplyState(); + column.HeaderCell.UpdatePseudoClasses(); } } diff --git a/src/Avalonia.Controls.DataGrid/DataGridRow.cs b/src/Avalonia.Controls.DataGrid/DataGridRow.cs index d5115c983a..aa0ac11b64 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridRow.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridRow.cs @@ -624,17 +624,17 @@ namespace Avalonia.Controls { if (_headerElement != null && OwningGrid.AreRowHeadersVisible) { - _headerElement.ApplyOwnerStatus(); + _headerElement.UpdatePseudoClasses(); } } - //TODO Implement internal void UpdatePseudoClasses() { - PseudoClasses.Set(":selected", IsSelected); - PseudoClasses.Set(":editing", IsEditing); if (RootElement != null && OwningGrid != null && IsVisible) { + PseudoClasses.Set(":selected", IsSelected); + PseudoClasses.Set(":editing", IsEditing); + PseudoClasses.Set(":invalid", !IsValid); ApplyHeaderStatus(); } } diff --git a/src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs b/src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs index 0790fcf5d5..e504fe73a8 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs @@ -3,6 +3,7 @@ // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. // All other rights reserved. +using Avalonia.Controls.Mixins; using Avalonia.Controls.Primitives; using Avalonia.Input; using Avalonia.Media; @@ -96,6 +97,7 @@ namespace Avalonia.Controls static DataGridRowGroupHeader() { SublevelIndentProperty.Changed.AddClassHandler((x,e) => x.OnSublevelIndentChanged(e)); + PressedMixin.Attach(); } /// @@ -205,14 +207,18 @@ namespace Avalonia.Controls { if (_headerElement != null && OwningGrid.AreRowHeadersVisible) { - _headerElement.ApplyOwnerStatus(); + _headerElement.UpdatePseudoClasses(); } } - //TODO Implement - internal void ApplyState(bool useTransitions) + internal void UpdatePseudoClasses() { + PseudoClasses.Set(":current", IsCurrent); + if (RowGroupInfo?.CollectionViewGroup != null) + { + PseudoClasses.Set(":expanded", RowGroupInfo.IsVisible && RowGroupInfo.CollectionViewGroup.ItemCount > 0); + } } protected override Size ArrangeOverride(Size finalSize) @@ -344,7 +350,7 @@ namespace Avalonia.Controls { EnsureExpanderButtonIsChecked(); EnsureHeaderVisibility(); - ApplyState(useTransitions: false); + UpdatePseudoClasses(); ApplyHeaderStatus(); } @@ -353,7 +359,7 @@ namespace Avalonia.Controls if (IsEnabled) { IsMouseOver = true; - ApplyState(useTransitions: true); + UpdatePseudoClasses(); } base.OnPointerEnter(e); @@ -364,7 +370,7 @@ namespace Avalonia.Controls if (IsEnabled) { IsMouseOver = false; - ApplyState(useTransitions: true); + UpdatePseudoClasses(); } base.OnPointerLeave(e); @@ -402,7 +408,7 @@ namespace Avalonia.Controls EnsureExpanderButtonIsChecked(); - ApplyState(true /*useTransitions*/); + UpdatePseudoClasses(); } } diff --git a/src/Avalonia.Controls.DataGrid/DataGridRowHeader.cs b/src/Avalonia.Controls.DataGrid/DataGridRowHeader.cs index 324227d749..3b121879b1 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridRowHeader.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridRowHeader.cs @@ -99,7 +99,7 @@ namespace Avalonia.Controls.Primitives _rootElement = e.NameScope.Find(DATAGRIDROWHEADER_elementRootName); if (_rootElement != null) { - ApplyOwnerStatus(); + UpdatePseudoClasses(); } } @@ -131,12 +131,27 @@ namespace Avalonia.Controls.Primitives return measuredSize; } - //TODO Implement - internal void ApplyOwnerStatus() + internal void UpdatePseudoClasses() { if (_rootElement != null && Owner != null && Owner.IsVisible) { + if (OwningRow != null) + { + PseudoClasses.Set(":invalid", !OwningRow.IsValid); + + PseudoClasses.Set(":selected", OwningRow.IsSelected); + + PseudoClasses.Set(":editing", OwningRow.IsEditing); + if (OwningGrid != null) + { + PseudoClasses.Set(":current", OwningRow.Slot == OwningGrid.CurrentSlot); + } + } + else if (OwningRowGroupHeader != null && OwningGrid != null) + { + PseudoClasses.Set(":current", OwningRowGroupHeader.RowGroupInfo.Slot == OwningGrid.CurrentSlot); + } } } diff --git a/src/Avalonia.Controls.DataGrid/DataGridRows.cs b/src/Avalonia.Controls.DataGrid/DataGridRows.cs index 924156f5f4..a69b8eafe1 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridRows.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridRows.cs @@ -1912,7 +1912,7 @@ namespace Avalonia.Controls { // Assume it's a RowGroupHeader DataGridRowGroupHeader groupHeader = element as DataGridRowGroupHeader; - groupHeader.ApplyState(useTransitions: true); + groupHeader.UpdatePseudoClasses(); } } From 8fb31061b5e933a189c04b0b6b53a082945cc325 Mon Sep 17 00:00:00 2001 From: Maksym Katsydan Date: Fri, 21 Aug 2020 00:35:32 -0400 Subject: [PATCH 3/8] Fluent DataGrid styles --- .../Themes/Fluent.xaml | 563 ++++++++++++++---- 1 file changed, 463 insertions(+), 100 deletions(-) diff --git a/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml b/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml index a32989372c..3c49999099 100644 --- a/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml +++ b/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml @@ -1,13 +1,141 @@ - - + + + + + + + + + + + + + + + + + + + + + M1875 1011l-787 787v-1798h-128v1798l-787 -787l-90 90l941 941l941 -941z + M1965 947l-941 -941l-941 941l90 90l787 -787v1798h128v-1798l787 787z + M515 93l930 931l-930 931l90 90l1022 -1021l-1022 -1021z + M1939 1581l90 -90l-1005 -1005l-1005 1005l90 90l915 -915z + + + + 0.6 + 0.8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - From 8819b2481e37a64222caac0782914928ee028662 Mon Sep 17 00:00:00 2001 From: Maksym Katsydan Date: Tue, 25 Aug 2020 03:05:47 -0400 Subject: [PATCH 6/8] DataGrid: update samples page --- samples/ControlCatalog/Models/GDPValueConverter.cs | 8 ++++---- samples/ControlCatalog/Models/Person.cs | 12 ++++++++++++ samples/ControlCatalog/Pages/DataGridPage.xaml | 3 ++- samples/ControlCatalog/Pages/DataGridPage.xaml.cs | 2 +- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/samples/ControlCatalog/Models/GDPValueConverter.cs b/samples/ControlCatalog/Models/GDPValueConverter.cs index f7975ac604..1ca3e9c8e4 100644 --- a/samples/ControlCatalog/Models/GDPValueConverter.cs +++ b/samples/ControlCatalog/Models/GDPValueConverter.cs @@ -19,11 +19,11 @@ namespace ControlCatalog.Models if (value is int gdp) { if (gdp <= 5000) - return Brushes.Orange; + return new SolidColorBrush(Colors.Orange, 0.6); else if (gdp <= 10000) - return Brushes.Yellow; + return new SolidColorBrush(Colors.Yellow, 0.6); else - return Brushes.LightGreen; + return new SolidColorBrush(Colors.LightGreen, 0.6); } return value; @@ -34,4 +34,4 @@ namespace ControlCatalog.Models throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/samples/ControlCatalog/Models/Person.cs b/samples/ControlCatalog/Models/Person.cs index a0abcfe8f4..47f41bc584 100644 --- a/samples/ControlCatalog/Models/Person.cs +++ b/samples/ControlCatalog/Models/Person.cs @@ -15,6 +15,7 @@ namespace ControlCatalog.Models { string _firstName; string _lastName; + bool _isBanned; public string FirstName { @@ -47,6 +48,17 @@ namespace ControlCatalog.Models } } + public bool IsBanned + { + get => _isBanned; + set + { + _isBanned = value; + + OnPropertyChanged(nameof(_isBanned)); + } + } + Dictionary> _errorLookup = new Dictionary>(); void SetError(string propertyName, string error) diff --git a/samples/ControlCatalog/Pages/DataGridPage.xaml b/samples/ControlCatalog/Pages/DataGridPage.xaml index 7b86bba6a9..d045626c2c 100644 --- a/samples/ControlCatalog/Pages/DataGridPage.xaml +++ b/samples/ControlCatalog/Pages/DataGridPage.xaml @@ -44,7 +44,8 @@ - + +