Browse Source

Merge remote-tracking branch 'origin/master' into fixes/gpu-memory-spike-leak

Dan Walmsley 5 years ago
parent
commit
d5eec3821d

+ 1 - 2
samples/ControlCatalog/App.xaml

@@ -1,8 +1,7 @@
 <Application xmlns="https://github.com/avaloniaui"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              x:Class="ControlCatalog.App">
-  <Application.Styles>        
-    <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Default.xaml"/>
+  <Application.Styles>
     <Style Selector="TextBlock.h1">
       <Setter Property="FontSize" Value="16" />
       <Setter Property="FontWeight" Value="Medium" />

+ 14 - 0
samples/ControlCatalog/App.xaml.cs

@@ -9,12 +9,23 @@ namespace ControlCatalog
 {
     public class App : Application
     {
+        private static readonly StyleInclude DataGridFluent = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
+        {
+            Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml")
+        };
+
+        private static readonly StyleInclude DataGridDefault = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
+        {
+            Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Default.xaml")
+        };
+
         public static Styles FluentDark = new Styles
         {
             new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
             {
                 Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/FluentDark.xaml")
             },
+            DataGridFluent
         };
 
         public static Styles FluentLight = new Styles
@@ -23,6 +34,7 @@ namespace ControlCatalog
             {
                 Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/FluentLight.xaml")
             },
+            DataGridFluent
         };
 
         public static Styles DefaultLight = new Styles
@@ -43,6 +55,7 @@ namespace ControlCatalog
             {
                 Source = new Uri("avares://Avalonia.Themes.Default/DefaultTheme.xaml")
             },
+            DataGridDefault
         };
 
         public static Styles DefaultDark = new Styles
@@ -63,6 +76,7 @@ namespace ControlCatalog
             {
                 Source = new Uri("avares://Avalonia.Themes.Default/DefaultTheme.xaml")
             },
+            DataGridDefault
         };
 
         public override void Initialize()

+ 4 - 4
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();
         }
     }
-}
+}

+ 12 - 0
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<string, List<string>> _errorLookup = new Dictionary<string, List<string>>();
 
         void SetError(string propertyName, string error)

+ 3 - 2
samples/ControlCatalog/Pages/DataGridPage.xaml

@@ -18,7 +18,7 @@
     </StackPanel>
     <TabControl Grid.Row="1">
       <TabItem Header="DataGrid">
-        <DataGrid Name="dataGrid1" Margin="12" CanUserResizeColumns="True" CanUserReorderColumns="True">
+        <DataGrid Name="dataGrid1" Margin="12" CanUserResizeColumns="True" CanUserReorderColumns="True" CanUserSortColumns="True" HeadersVisibility="All">
           <DataGrid.Columns>
             <DataGridTextColumn Header="Country" Binding="{Binding Name}" Width="6*" />
             <DataGridTextColumn Header="Region" Binding="{Binding Region}" Width="4*" />
@@ -44,7 +44,8 @@
           <DataGrid Name="dataGridEdit" Margin="12" Grid.Row="0">
             <DataGrid.Columns>
               <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" Width="2*" />
-              <DataGridTextColumn Header="Last" Binding="{Binding LastName}" Width="*" />
+              <DataGridTextColumn Header="Last" Binding="{Binding LastName}" Width="2*" />
+              <DataGridCheckBoxColumn Header="Is Banned" Binding="{Binding IsBanned}" Width="*" />
             </DataGrid.Columns>
           </DataGrid>
           <Button Grid.Row="1" Name="btnAdd" Margin="12,0,12,12" Content="Add" HorizontalAlignment="Right" />

+ 7 - 2
samples/ControlCatalog/Pages/DataGridPage.xaml.cs

@@ -13,7 +13,7 @@ namespace ControlCatalog.Pages
             this.InitializeComponent();
             var dg1 = this.FindControl<DataGrid>("dataGrid1");
             dg1.IsReadOnly = true;
-
+            dg1.LoadingRow += Dg1_LoadingRow;
             var collectionView1 = new DataGridCollectionView(Countries.All);
             //collectionView.GroupDescriptions.Add(new PathGroupDescription("Region"));
 
@@ -33,7 +33,7 @@ namespace ControlCatalog.Pages
             var items = new List<Person>
             {
                 new Person { FirstName = "John", LastName = "Doe" },
-                new Person { FirstName = "Elizabeth", LastName = "Thomas" },
+                new Person { FirstName = "Elizabeth", LastName = "Thomas", IsBanned = true },
                 new Person { FirstName = "Zack", LastName = "Ward" }
             };
             var collectionView3 = new DataGridCollectionView(items);
@@ -44,6 +44,11 @@ namespace ControlCatalog.Pages
             addButton.Click += (a, b) => collectionView3.AddNew();
         }
 
+        private void Dg1_LoadingRow(object sender, DataGridRowEventArgs e)
+        {
+            e.Row.Header = e.Row.GetIndex() + 1;
+        }
+
         private void InitializeComponent()
         {
             AvaloniaXamlLoader.Load(this);

+ 64 - 10
src/Avalonia.Controls.DataGrid/DataGrid.cs

@@ -39,6 +39,7 @@ namespace Avalonia.Controls
         private const string DATAGRID_elementRowHeadersPresenterName = "PART_RowHeadersPresenter";
         private const string DATAGRID_elementTopLeftCornerHeaderName = "PART_TopLeftCornerHeader";
         private const string DATAGRID_elementTopRightCornerHeaderName = "PART_TopRightCornerHeader";
+        private const string DATAGRID_elementBottomRightCornerHeaderName = "PART_BottomRightCorner";
         private const string DATAGRID_elementValidationSummary = "PART_ValidationSummary";
         private const string DATAGRID_elementVerticalScrollbarName = "PART_VerticalScrollbar";
 
@@ -79,6 +80,7 @@ namespace Avalonia.Controls
         private INotifyCollectionChanged _topLevelGroup;
         private ContentControl _clipboardContentControl;
 
+        private IVisual _bottomRightCorner;
         private DataGridColumnHeadersPresenter _columnHeadersPresenter;
         private DataGridRowsPresenter _rowsPresenter;
         private ScrollBar _vScrollBar;
@@ -1825,6 +1827,22 @@ namespace Avalonia.Controls
             }
         }
 
+        private bool IsHorizontalScrollBarOverCells
+        {
+            get
+            {
+                return _columnHeadersPresenter != null && Grid.GetColumnSpan(_columnHeadersPresenter) == 2;
+            }
+        }
+
+        private bool IsVerticalScrollBarOverCells
+        {
+            get
+            {
+                return _rowsPresenter != null && Grid.GetRowSpan(_rowsPresenter) == 2;
+            }
+        }
+
         private int NoSelectionChangeCount
         {
             get
@@ -2323,6 +2341,7 @@ namespace Avalonia.Controls
             _topLeftCornerHeader = e.NameScope.Find<ContentControl>(DATAGRID_elementTopLeftCornerHeaderName);
             EnsureTopLeftCornerHeader(); // EnsureTopLeftCornerHeader checks for a null _topLeftCornerHeader;
             _topRightCornerHeader = e.NameScope.Find<ContentControl>(DATAGRID_elementTopRightCornerHeaderName);
+            _bottomRightCorner = e.NameScope.Find<IVisual>(DATAGRID_elementBottomRightCornerHeaderName);
         }
 
         /// <summary>
@@ -2753,7 +2772,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();
                         }
                     }
 
@@ -3293,6 +3312,10 @@ namespace Avalonia.Controls
                 //  
 
             }
+
+            bool isHorizontalScrollBarOverCells = IsHorizontalScrollBarOverCells;
+            bool isVerticalScrollBarOverCells = IsVerticalScrollBarOverCells;
+
             double cellsWidth = CellsWidth;
             double cellsHeight = CellsHeight;
 
@@ -3308,10 +3331,17 @@ namespace Avalonia.Controls
                 // Compensate if the horizontal scrollbar is already taking up space
                 if (!forceHorizScrollbar && _hScrollBar.IsVisible)
                 {
-                    cellsHeight += _hScrollBar.DesiredSize.Height;
+                    if (!isHorizontalScrollBarOverCells)
+                    {
+                        cellsHeight += _hScrollBar.DesiredSize.Height;
+                    }
+                }
+                if (!isHorizontalScrollBarOverCells)
+                {
+                    horizScrollBarHeight = _hScrollBar.Height + _hScrollBar.Margin.Top + _hScrollBar.Margin.Bottom;
                 }
-                horizScrollBarHeight = _hScrollBar.Height + _hScrollBar.Margin.Top + _hScrollBar.Margin.Bottom;
             }
+
             bool allowVertScrollbar = false;
             bool forceVertScrollbar = false;
             double vertScrollBarWidth = 0;
@@ -3324,9 +3354,15 @@ namespace Avalonia.Controls
                 // Compensate if the vertical scrollbar is already taking up space
                 if (!forceVertScrollbar && _vScrollBar.IsVisible)
                 {
-                    cellsWidth += _vScrollBar.DesiredSize.Width;
+                    if (!isVerticalScrollBarOverCells)
+                    {
+                        cellsWidth += _vScrollBar.DesiredSize.Width;
+                    }
+                }
+                if (!isVerticalScrollBarOverCells)
+                {
+                    vertScrollBarWidth = _vScrollBar.Width + _vScrollBar.Margin.Left + _vScrollBar.Margin.Right;
                 }
-                vertScrollBarWidth = _vScrollBar.Width + _vScrollBar.Margin.Left + _vScrollBar.Margin.Right;
             }
 
             // Now cellsWidth is the width potentially available for displaying data cells.
@@ -3354,7 +3390,9 @@ namespace Avalonia.Controls
                     cellsHeight -= horizScrollBarHeight;
                     Debug.Assert(cellsHeight >= 0);
                     needHorizScrollbarWithoutVertScrollbar = needHorizScrollbar = true;
-                    if (allowVertScrollbar && (MathUtilities.LessThanOrClose(totalVisibleWidth - cellsWidth, vertScrollBarWidth) ||
+
+                    if (vertScrollBarWidth > 0 && 
+                        allowVertScrollbar && (MathUtilities.LessThanOrClose(totalVisibleWidth - cellsWidth, vertScrollBarWidth) ||
                         MathUtilities.LessThanOrClose(cellsWidth - totalVisibleFrozenWidth, vertScrollBarWidth)))
                     {
                         // Would we still need a horizontal scrollbar without the vertical one?
@@ -3372,7 +3410,12 @@ namespace Avalonia.Controls
                     }
                 }
 
-                UpdateDisplayedRows(DisplayData.FirstScrollingSlot, cellsHeight);
+                // Store the current FirstScrollingSlot because removing the horizontal scrollbar could scroll
+                // the DataGrid up; however, if we realize later that we need to keep the horizontal scrollbar
+                // then we should use the first slot stored here which is not scrolled.
+                int firstScrollingSlot = DisplayData.FirstScrollingSlot;
+
+                UpdateDisplayedRows(firstScrollingSlot, cellsHeight);
                 if (allowVertScrollbar &&
                     MathUtilities.GreaterThan(cellsHeight, 0) &&
                     MathUtilities.LessThanOrClose(vertScrollBarWidth, cellsWidth) &&
@@ -3384,10 +3427,12 @@ namespace Avalonia.Controls
                 }
 
                 DisplayData.FirstDisplayedScrollingCol = ComputeFirstVisibleScrollingColumn();
+
                 // we compute the number of visible columns only after we set up the vertical scroll bar.
                 ComputeDisplayedColumns();
 
-                if (allowHorizScrollbar &&
+                if ((vertScrollBarWidth > 0 || horizScrollBarHeight > 0) && 
+                    allowHorizScrollbar &&
                     needVertScrollbar && !needHorizScrollbar &&
                     MathUtilities.GreaterThan(totalVisibleWidth, cellsWidth) &&
                     MathUtilities.LessThan(totalVisibleFrozenWidth, cellsWidth) &&
@@ -3398,7 +3443,7 @@ namespace Avalonia.Controls
                     Debug.Assert(cellsHeight >= 0);
                     needVertScrollbar = false;
 
-                    UpdateDisplayedRows(DisplayData.FirstScrollingSlot, cellsHeight);
+                    UpdateDisplayedRows(firstScrollingSlot, cellsHeight);
                     if (cellsHeight > 0 &&
                         vertScrollBarWidth <= cellsWidth &&
                         DisplayData.NumTotallyDisplayedScrollingElements != VisibleSlotCount)
@@ -3479,6 +3524,15 @@ namespace Avalonia.Controls
                     _topRightCornerHeader.IsVisible = false;
                 }
             }
+
+            if (_bottomRightCorner != null)
+            {
+                // Show the BottomRightCorner when both scrollbars are visible.
+                _bottomRightCorner.IsVisible =
+                    _hScrollBar != null && _hScrollBar.IsVisible &&
+                    _vScrollBar != null && _vScrollBar.IsVisible;
+            }
+
             DisplayData.FullyRecycleElements();
         }
 
@@ -5417,7 +5471,7 @@ namespace Avalonia.Controls
             }
             else if (displayedElement is DataGridRowGroupHeader groupHeader)
             {
-                groupHeader.ApplyState(useTransitions: true);
+                groupHeader.UpdatePseudoClasses();
                 if (AreRowHeadersVisible)
                 {
                     groupHeader.ApplyHeaderStatus();

+ 12 - 1
src/Avalonia.Controls.DataGrid/DataGridCell.cs

@@ -19,7 +19,7 @@ namespace Avalonia.Controls
         private Rectangle _rightGridLine;
         private DataGridColumn _owningColumn;
 
-        bool _isValid;
+        bool _isValid = true;
 
         public static readonly DirectProperty<DataGridCell, bool> IsValidProperty =
             AvaloniaProperty.RegisterDirect<DataGridCell, bool>(
@@ -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 

+ 8 - 7
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
 {
@@ -39,7 +40,7 @@ namespace Avalonia.Controls
         private static Cursor _originalCursor;
         private static double _originalHorizontalOffset;
         private static double _originalWidth;
-        private bool _desiredSeparatorVisibility;
+        private bool _desiredSeparatorVisibility = true;
         private static Point? _dragStart;
         private static DataGridColumn _dragColumn;
         private static double _frozenColumnsWidth;
@@ -68,6 +69,7 @@ namespace Avalonia.Controls
         static DataGridColumnHeader()
         {
             AreSeparatorsVisibleProperty.Changed.AddClassHandler<DataGridColumnHeader>((x, e) => x.OnAreSeparatorsVisibleChanged(e));
+            PressedMixin.Attach<DataGridColumnHeader>();
         }
 
         /// <summary>
@@ -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)

+ 1 - 1
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();
             }
         }
 

+ 4 - 4
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();
             } 
         }

+ 14 - 8
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<DataGridRowGroupHeader>((x,e) => x.OnSublevelIndentChanged(e));
+            PressedMixin.Attach<DataGridRowGroupHeader>();
         }
 
         /// <summary>
@@ -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)
@@ -328,7 +334,7 @@ namespace Avalonia.Controls
         {
             if (_headerElement != null && OwningGrid != null)
             {
-                _headerElement.IsVisible = OwningGrid.AreColumnHeadersVisible;
+                _headerElement.IsVisible = OwningGrid.AreRowHeadersVisible;
             }
         }
 
@@ -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();
             }
         }
 

+ 19 - 4
src/Avalonia.Controls.DataGrid/DataGridRowHeader.cs

@@ -14,7 +14,7 @@ namespace Avalonia.Controls.Primitives
     /// </summary>
     public class DataGridRowHeader : ContentControl
     {
-        private const string DATAGRIDROWHEADER_elementRootName = "Root";
+        private const string DATAGRIDROWHEADER_elementRootName = "PART_Root";
         private const double DATAGRIDROWHEADER_separatorThickness = 1;
 
         private Control _rootElement;
@@ -99,7 +99,7 @@ namespace Avalonia.Controls.Primitives
             _rootElement = e.NameScope.Find<Control>(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);
+                }
             }
         }
 

+ 1 - 1
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();
             }
         }
 

+ 3 - 1
src/Avalonia.Controls.DataGrid/DataGridTextColumn.cs

@@ -9,6 +9,7 @@ using Avalonia.Media;
 using System;
 using System.ComponentModel;
 using Avalonia.Layout;
+using Avalonia.Markup.Xaml.MarkupExtensions;
 
 namespace Avalonia.Controls
 {
@@ -17,6 +18,7 @@ namespace Avalonia.Controls
     /// </summary>
     public class DataGridTextColumn : DataGridBoundColumn
     {
+        private const string DATAGRID_TextColumnCellTextBlockMarginKey = "DataGridTextColumnCellTextBlockMargin";
 
         private double? _fontSize;
         private FontStyle? _fontStyle;
@@ -186,7 +188,7 @@ namespace Avalonia.Controls
         {
             TextBlock textBlockElement = new TextBlock
             {
-                Margin = new Thickness(4),
+                [!Layoutable.MarginProperty] = new DynamicResourceExtension(DATAGRID_TextColumnCellTextBlockMarginKey),
                 VerticalAlignment = VerticalAlignment.Center
             };
 

+ 9 - 3
src/Avalonia.Controls.DataGrid/Themes/Default.xaml

@@ -1,5 +1,11 @@
-<Styles xmlns="https://github.com/avaloniaui">
+<Styles xmlns="https://github.com/avaloniaui"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <!--TODO: Validation and Focus-->
+
+  <Styles.Resources>
+    <Thickness x:Key="DataGridTextColumnCellTextBlockMargin">4</Thickness>
+  </Styles.Resources>
+  
   <Style Selector="DataGridCell">
     <Setter Property="Background" Value="Transparent"/>
     <Setter Property="HorizontalContentAlignment" Value="Stretch" />
@@ -133,7 +139,7 @@
   <Style Selector="DataGridRowHeader">
     <Setter Property="Template">
       <ControlTemplate>
-        <Grid
+        <Grid x:Name="PART_Root"
         RowDefinitions="*,*,Auto"
         ColumnDefinitions="Auto,*">
 
@@ -218,7 +224,7 @@
             <Rectangle Name="PART_ColumnHeadersAndRowsSeparator" Grid.ColumnSpan="3" VerticalAlignment="Bottom" StrokeThickness="1" Height="1" Fill="{DynamicResource ThemeControlMidHighBrush}"/>
 
             <DataGridRowsPresenter Name="PART_RowsPresenter" Grid.ColumnSpan="2" Grid.Row="1" />
-            <Rectangle Name="BottomRightCorner" Fill="{DynamicResource ThemeControlMidHighBrush}" Grid.Column="2" Grid.Row="2" />
+            <Rectangle Name="PART_BottomRightCorner" Fill="{DynamicResource ThemeControlMidHighBrush}" Grid.Column="2" Grid.Row="2" />
             <Rectangle Name="BottomLeftCorner" Fill="{DynamicResource ThemeControlMidHighBrush}" Grid.Row="2" Grid.ColumnSpan="2" />
             <ScrollBar Name="PART_VerticalScrollbar" Orientation="Vertical" Grid.Column="2" Grid.Row="1" Width="{DynamicResource ScrollBarThickness}"/>
 

+ 645 - 0
src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml

@@ -0,0 +1,645 @@
+<Styles xmlns="https://github.com/avaloniaui"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+  <Styles.Resources>
+    <Thickness x:Key="DataGridTextColumnCellTextBlockMargin">12,0,12,0</Thickness>
+
+    <x:Double x:Key="ListAccentLowOpacity">0.6</x:Double>
+    <x:Double x:Key="ListAccentMediumOpacity">0.8</x:Double>
+
+    <StreamGeometry x:Key="DataGridSortIconAscendingPath">M1875 1011l-787 787v-1798h-128v1798l-787 -787l-90 90l941 941l941 -941z</StreamGeometry>
+    <StreamGeometry x:Key="DataGridSortIconDescendingPath">M1965 947l-941 -941l-941 941l90 90l787 -787v1798h128v-1798l787 787z</StreamGeometry>
+    <StreamGeometry x:Key="DataGridRowGroupHeaderIconClosedPath">M515 93l930 931l-930 931l90 90l1022 -1021l-1022 -1021z</StreamGeometry>
+    <StreamGeometry x:Key="DataGridRowGroupHeaderIconOpenedPath">M1939 1581l90 -90l-1005 -1005l-1005 1005l90 90l915 -915z</StreamGeometry>
+
+    <SolidColorBrush x:Key="DataGridGridLinesBrush"
+                     Color="{StaticResource SystemBaseMediumLowColor}"
+                     Opacity="0.4" />
+    <SolidColorBrush x:Key="DataGridDropLocationIndicatorBackground"
+                     Color="#3F4346" />
+    <SolidColorBrush x:Key="DataGridDisabledVisualElementBackground"
+                     Color="#8CFFFFFF" />
+    <SolidColorBrush x:Key="DataGridFillerGridLinesBrush"
+                     Color="Transparent" />
+    <SolidColorBrush x:Key="DataGridCurrencyVisualPrimaryBrush"
+                     Color="Transparent" />
+    <StaticResource x:Key="DataGridColumnHeaderBackgroundColor"
+                    ResourceKey="SystemAltHighColor" />
+    <SolidColorBrush x:Key="DataGridColumnHeaderBackgroundBrush"
+                     Color="{StaticResource DataGridColumnHeaderBackgroundColor}" />
+    <StaticResource x:Key="DataGridScrollBarsSeparatorBackground"
+                    ResourceKey="SystemChromeLowColor" />
+    <StaticResource x:Key="DataGridColumnHeaderForegroundBrush"
+                    ResourceKey="SystemControlForegroundBaseMediumBrush" />
+    <StaticResource x:Key="DataGridColumnHeaderHoveredBackgroundColor"
+                    ResourceKey="SystemListLowColor" />
+    <StaticResource x:Key="DataGridColumnHeaderPressedBackgroundColor"
+                    ResourceKey="SystemListMediumColor" />
+    <StaticResource x:Key="DataGridColumnHeaderDraggedBackgroundBrush"
+                    ResourceKey="SystemControlBackgroundChromeMediumLowBrush" />
+    <StaticResource x:Key="DataGridColumnHeaderPointerOverBrush"
+                    ResourceKey="SystemControlHighlightListLowBrush" />
+    <StaticResource x:Key="DataGridColumnHeaderPressedBrush"
+                    ResourceKey="SystemControlHighlightListMediumBrush" />
+    <StaticResource x:Key="DataGridDetailsPresenterBackgroundBrush"
+                    ResourceKey="SystemControlBackgroundChromeMediumLowBrush" />
+    <StaticResource x:Key="DataGridFillerColumnGridLinesBrush"
+                    ResourceKey="DataGridFillerGridLinesBrush" />
+    <StaticResource x:Key="DataGridRowSelectedBackgroundColor"
+                    ResourceKey="SystemAccentColor" />
+    <StaticResource x:Key="DataGridRowSelectedBackgroundOpacity"
+                    ResourceKey="ListAccentLowOpacity" />
+    <StaticResource x:Key="DataGridRowSelectedHoveredBackgroundColor"
+                    ResourceKey="SystemAccentColor" />
+    <StaticResource x:Key="DataGridRowSelectedHoveredBackgroundOpacity"
+                    ResourceKey="ListAccentMediumOpacity" />
+    <StaticResource x:Key="DataGridRowSelectedUnfocusedBackgroundColor"
+                    ResourceKey="SystemAccentColor" />
+    <StaticResource x:Key="DataGridRowSelectedUnfocusedBackgroundOpacity"
+                    ResourceKey="ListAccentLowOpacity" />
+    <StaticResource x:Key="DataGridRowSelectedHoveredUnfocusedBackgroundColor"
+                    ResourceKey="SystemAccentColor" />
+    <StaticResource x:Key="DataGridRowSelectedHoveredUnfocusedBackgroundOpacity"
+                    ResourceKey="ListAccentMediumOpacity" />
+    <StaticResource x:Key="DataGridRowHeaderForegroundBrush"
+                    ResourceKey="SystemControlForegroundBaseMediumBrush" />
+    <StaticResource x:Key="DataGridRowHeaderBackgroundBrush"
+                    ResourceKey="SystemControlBackgroundAltHighBrush" />
+    <StaticResource x:Key="DataGridRowGroupHeaderBackgroundBrush"
+                    ResourceKey="SystemControlBackgroundChromeMediumBrush" />
+    <StaticResource x:Key="DataGridRowGroupHeaderHoveredBackgroundBrush"
+                    ResourceKey="SystemControlBackgroundListLowBrush" />
+    <StaticResource x:Key="DataGridRowGroupHeaderPressedBackgroundBrush"
+                    ResourceKey="SystemControlBackgroundListMediumBrush" />
+    <StaticResource x:Key="DataGridRowGroupHeaderForegroundBrush"
+                    ResourceKey="SystemControlForegroundBaseHighBrush" />
+    <StaticResource x:Key="DataGridRowInvalidBrush"
+                    ResourceKey="SystemErrorTextColor" />
+    <StaticResource x:Key="DataGridCellBackgroundBrush"
+                    ResourceKey="SystemControlTransparentBrush" />
+    <StaticResource x:Key="DataGridCellFocusVisualPrimaryBrush"
+                    ResourceKey="SystemControlFocusVisualPrimaryBrush" />
+    <StaticResource x:Key="DataGridCellFocusVisualSecondaryBrush"
+                    ResourceKey="SystemControlFocusVisualSecondaryBrush" />
+    <StaticResource x:Key="DataGridCellInvalidBrush"
+                    ResourceKey="SystemErrorTextColor" />
+  </Styles.Resources>
+
+  <Style Selector="DataGridCell">
+    <Setter Property="Background" Value="{DynamicResource DataGridCellBackgroundBrush}" />
+    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
+    <Setter Property="VerticalContentAlignment" Value="Stretch" />
+    <Setter Property="FontSize" Value="15" />
+    <Setter Property="MinHeight" Value="32" />
+    <Setter Property="Focusable" Value="False" />
+    <Setter Property="Template">
+      <ControlTemplate>
+        <Grid x:Name="PART_CellRoot"
+              ColumnDefinitions="*,Auto"
+              Background="{TemplateBinding Background}">
+
+          <Rectangle x:Name="CurrencyVisual"
+                     HorizontalAlignment="Stretch"
+                     VerticalAlignment="Stretch"
+                     Fill="Transparent"
+                     IsHitTestVisible="False"
+                     Stroke="{DynamicResource DataGridCurrencyVisualPrimaryBrush}"
+                     StrokeThickness="1" />
+          <Grid x:Name="FocusVisual"
+                IsHitTestVisible="False">
+            <Rectangle HorizontalAlignment="Stretch"
+                       VerticalAlignment="Stretch"
+                       Fill="Transparent"
+                       IsHitTestVisible="False"
+                       Stroke="{DynamicResource DataGridCellFocusVisualPrimaryBrush}"
+                       StrokeThickness="2" />
+            <Rectangle Margin="2"
+                       HorizontalAlignment="Stretch"
+                       VerticalAlignment="Stretch"
+                       Fill="Transparent"
+                       IsHitTestVisible="False"
+                       Stroke="{DynamicResource DataGridCellFocusVisualSecondaryBrush}"
+                       StrokeThickness="1" />
+          </Grid>
+
+          <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"
+                            Content="{TemplateBinding Content}"
+                            Margin="{TemplateBinding Padding}"
+                            TextBlock.Foreground="{TemplateBinding Foreground}"
+                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
+                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
+
+          <Rectangle x:Name="InvalidVisualElement"
+                     HorizontalAlignment="Stretch"
+                     VerticalAlignment="Stretch"
+                     IsHitTestVisible="False"
+                     Stroke="{DynamicResource DataGridCellInvalidBrush}"
+                     StrokeThickness="1" />
+
+          <Rectangle Name="PART_RightGridLine"
+                     Grid.Column="1"
+                     VerticalAlignment="Stretch"
+                     Width="1"
+                     Fill="{DynamicResource DataGridFillerColumnGridLinesBrush}" />
+        </Grid>
+      </ControlTemplate>
+    </Setter>
+  </Style>
+
+  <Style Selector="DataGridCell /template/ Rectangle#CurrencyVisual">
+    <Setter Property="IsVisible" Value="False" />
+  </Style>
+  <Style Selector="DataGridCell /template/ Grid#FocusVisual">
+    <Setter Property="IsVisible" Value="False" />
+  </Style>
+  <Style Selector="DataGridCell:current /template/ Rectangle#CurrencyVisual">
+    <Setter Property="IsVisible" Value="True" />
+  </Style>
+  <Style Selector="DataGrid:focus DataGridCell:current /template/ Grid#FocusVisual">
+    <Setter Property="IsVisible" Value="True" />
+  </Style>
+  <Style Selector="DataGridCell /template/ Rectangle#InvalidVisualElement">
+    <Setter Property="IsVisible" Value="False" />
+  </Style>
+  <Style Selector="DataGridCell:invalid /template/ Rectangle#InvalidVisualElement">
+    <Setter Property="IsVisible" Value="True" />
+  </Style>
+
+  <Style Selector="DataGridColumnHeader">
+    <Setter Property="Foreground" Value="{DynamicResource DataGridColumnHeaderForegroundBrush}" />
+    <Setter Property="Background" Value="{DynamicResource DataGridColumnHeaderBackgroundBrush}" />
+    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
+    <Setter Property="VerticalContentAlignment" Value="Center" />
+    <Setter Property="Focusable" Value="False" />
+    <Setter Property="SeparatorBrush" Value="{DynamicResource DataGridGridLinesBrush}" />
+    <Setter Property="Padding" Value="12,0,0,0" />
+    <Setter Property="FontSize" Value="12" />
+    <Setter Property="MinHeight" Value="32" />
+    <Setter Property="Template">
+      <ControlTemplate>
+        <Grid Name="PART_ColumnHeaderRoot"
+              ColumnDefinitions="*,Auto"
+              Background="{TemplateBinding Background}">
+
+          <Grid HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
+                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
+                Margin="{TemplateBinding Padding}">
+            <Grid.ColumnDefinitions>
+              <ColumnDefinition Width="*" />
+              <ColumnDefinition MinWidth="32"
+                                Width="Auto" />
+            </Grid.ColumnDefinitions>
+
+            <ContentPresenter Content="{TemplateBinding Content}" />
+
+            <Path Name="SortIcon"
+                  Grid.Column="1"
+                  Fill="{TemplateBinding Foreground}"
+                  HorizontalAlignment="Center"
+                  VerticalAlignment="Center"
+                  Stretch="Uniform"
+                  Height="12" />
+          </Grid>
+
+          <Rectangle Name="VerticalSeparator"
+                     Grid.Column="1"
+                     Width="1"
+                     VerticalAlignment="Stretch"
+                     Fill="{TemplateBinding SeparatorBrush}"
+                     IsVisible="{TemplateBinding AreSeparatorsVisible}" />
+
+          <Grid x:Name="FocusVisual"
+                IsHitTestVisible="False">
+            <Rectangle x:Name="FocusVisualPrimary"
+                       HorizontalAlignment="Stretch"
+                       VerticalAlignment="Stretch"
+                       Fill="Transparent"
+                       IsHitTestVisible="False"
+                       Stroke="{DynamicResource DataGridCellFocusVisualPrimaryBrush}"
+                       StrokeThickness="2" />
+            <Rectangle x:Name="FocusVisualSecondary"
+                       Margin="2"
+                       HorizontalAlignment="Stretch"
+                       VerticalAlignment="Stretch"
+                       Fill="Transparent"
+                       IsHitTestVisible="False"
+                       Stroke="{DynamicResource DataGridCellFocusVisualSecondaryBrush}"
+                       StrokeThickness="1" />
+          </Grid>
+        </Grid>
+      </ControlTemplate>
+    </Setter>
+  </Style>
+
+  <Style Selector="DataGridColumnHeader /template/ Grid#FocusVisual">
+    <Setter Property="IsVisible" Value="False" />
+  </Style>
+  <Style Selector="DataGridColumnHeader:focus-visible /template/ Grid#FocusVisual">
+    <Setter Property="IsVisible" Value="True" />
+  </Style>
+
+  <Style Selector="DataGridColumnHeader:pointerover /template/ Grid#PART_ColumnHeaderRoot">
+    <Setter Property="Background" Value="{DynamicResource DataGridColumnHeaderHoveredBackgroundColor}" />
+  </Style>
+  <Style Selector="DataGridColumnHeader:pressed /template/ Grid#PART_ColumnHeaderRoot">
+    <Setter Property="Background" Value="{DynamicResource DataGridColumnHeaderPressedBackgroundColor}" />
+  </Style>
+
+  <Style Selector="DataGridColumnHeader:dragIndicator">
+    <Setter Property="Opacity" Value="0.5" />
+  </Style>
+
+  <Style Selector="DataGridColumnHeader /template/ Path#SortIcon">
+    <Setter Property="IsVisible" Value="False" />
+  </Style>
+
+  <Style Selector="DataGridColumnHeader:sortascending /template/ Path#SortIcon">
+    <Setter Property="IsVisible" Value="True" />
+    <Setter Property="Data" Value="{StaticResource DataGridSortIconAscendingPath}" />
+  </Style>
+
+  <Style Selector="DataGridColumnHeader:sortdescending /template/ Path#SortIcon">
+    <Setter Property="IsVisible" Value="True" />
+    <Setter Property="Data" Value="{StaticResource DataGridSortIconDescendingPath}" />
+  </Style>
+
+  <Style Selector="DataGridRow">
+    <Setter Property="Focusable" Value="False" />
+    <Setter Property="Template">
+      <ControlTemplate>
+        <DataGridFrozenGrid Name="PART_Root"
+                            RowDefinitions="*,Auto,Auto"
+                            ColumnDefinitions="Auto,*">
+
+          <Rectangle Name="BackgroundRectangle"
+                     Grid.RowSpan="2"
+                     Grid.ColumnSpan="2" />
+          <Rectangle x:Name="InvalidVisualElement"
+                     Grid.ColumnSpan="2"
+                     Fill="{DynamicResource DataGridRowInvalidBrush}" />
+
+          <DataGridRowHeader Name="PART_RowHeader"
+                             Grid.RowSpan="3"
+                             DataGridFrozenGrid.IsFrozen="True" />
+          <DataGridCellsPresenter Name="PART_CellsPresenter"
+                                  Grid.Column="1"
+                                  DataGridFrozenGrid.IsFrozen="True" />
+          <DataGridDetailsPresenter Name="PART_DetailsPresenter"
+                                    Grid.Row="1"
+                                    Grid.Column="1"
+                                    Background="{DynamicResource DataGridDetailsPresenterBackgroundBrush}" />
+          <Rectangle Name="PART_BottomGridLine"
+                     Grid.Row="2"
+                     Grid.Column="1"
+                     HorizontalAlignment="Stretch"
+                     Height="1" />
+
+        </DataGridFrozenGrid>
+      </ControlTemplate>
+    </Setter>
+  </Style>
+
+  <Style Selector="DataGridRow /template/ Rectangle#InvalidVisualElement">
+    <Setter Property="Opacity" Value="0" />
+  </Style>
+  <Style Selector="DataGridRow:invalid /template/ Rectangle#InvalidVisualElement">
+    <Setter Property="Opacity" Value="0.4" />
+  </Style>
+  <Style Selector="DataGridRow:invalid /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Opacity" Value="0" />
+  </Style>
+
+  <Style Selector="DataGridRow /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Fill" Value="{DynamicResource SystemControlTransparentBrush}" />
+  </Style>
+  <Style Selector="DataGridRow:pointerover /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Fill" Value="{DynamicResource SystemListLowColor}" />
+  </Style>
+  <Style Selector="DataGridRow:selected /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Fill" Value="{DynamicResource DataGridRowSelectedUnfocusedBackgroundColor}" />
+    <Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedUnfocusedBackgroundOpacity}" />
+  </Style>
+  <Style Selector="DataGridRow:selected:pointerover /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Fill" Value="{DynamicResource DataGridRowSelectedHoveredUnfocusedBackgroundColor}" />
+    <Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedHoveredUnfocusedBackgroundOpacity}" />
+  </Style>
+  <Style Selector="DataGridRow:selected:focus /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Fill" Value="{DynamicResource DataGridRowSelectedBackgroundColor}" />
+    <Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedBackgroundOpacity}" />
+  </Style>
+  <Style Selector="DataGridRow:selected:pointerover:focus /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Fill" Value="{DynamicResource DataGridRowSelectedHoveredBackgroundColor}" />
+    <Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedHoveredBackgroundOpacity}" />
+  </Style>
+
+  <Style Selector="DataGridRowHeader">
+    <Setter Property="Background" Value="{DynamicResource DataGridRowHeaderBackgroundBrush}" />
+    <Setter Property="Focusable" Value="False" />
+    <Setter Property="SeparatorBrush" Value="{DynamicResource DataGridGridLinesBrush}" />
+    <Setter Property="AreSeparatorsVisible" Value="False" />
+    <Setter Property="Template">
+      <ControlTemplate>
+        <Grid x:Name="PART_Root"
+              RowDefinitions="*,*,Auto"
+              ColumnDefinitions="Auto,*">
+          <Border Grid.RowSpan="3"
+                  Grid.ColumnSpan="2"
+                  BorderBrush="{TemplateBinding SeparatorBrush}"
+                  BorderThickness="0,0,1,0">
+            <Grid Background="{TemplateBinding Background}">
+              <Rectangle x:Name="RowInvalidVisualElement"
+                         Fill="{DynamicResource DataGridRowInvalidBrush}"
+                         Stretch="Fill" />
+              <Rectangle x:Name="BackgroundRectangle"
+                         Stretch="Fill" />
+            </Grid>
+          </Border>
+          <Rectangle x:Name="HorizontalSeparator"
+                     Grid.Row="2"
+                     Grid.ColumnSpan="2"
+                     Height="1"
+                     Margin="1,0,1,0"
+                     HorizontalAlignment="Stretch"
+                     Fill="{TemplateBinding SeparatorBrush}"
+                     IsVisible="{TemplateBinding AreSeparatorsVisible}" />
+
+          <ContentPresenter Grid.RowSpan="2"
+                            Grid.Column="1"
+                            HorizontalAlignment="Center"
+                            VerticalAlignment="Center"
+                            Content="{TemplateBinding Content}" />
+        </Grid>
+      </ControlTemplate>
+    </Setter>
+  </Style>
+
+  <Style Selector="DataGridRowHeader /template/ Rectangle#RowInvalidVisualElement">
+    <Setter Property="Opacity" Value="0" />
+  </Style>
+  <Style Selector="DataGridRowHeader:invalid /template/ Rectangle#RowInvalidVisualElement">
+    <Setter Property="Opacity" Value="0.4" />
+  </Style>
+  <Style Selector="DataGridRowHeader:invalid /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Opacity" Value="0" />
+  </Style>
+
+  <Style Selector="DataGridRowHeader /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Fill" Value="{DynamicResource SystemControlTransparentBrush}" />
+  </Style>
+  <Style Selector="DataGridRow:pointerover DataGridRowHeader /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Fill" Value="{DynamicResource SystemListLowColor}" />
+  </Style>
+  <Style Selector="DataGridRowHeader:selected /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Fill" Value="{DynamicResource DataGridRowSelectedUnfocusedBackgroundColor}" />
+    <Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedUnfocusedBackgroundOpacity}" />
+  </Style>
+  <Style Selector="DataGridRow:pointerover DataGridRowHeader:selected /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Fill" Value="{DynamicResource DataGridRowSelectedHoveredUnfocusedBackgroundColor}" />
+    <Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedHoveredUnfocusedBackgroundOpacity}" />
+  </Style>
+  <Style Selector="DataGridRowHeader:selected:focus /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Fill" Value="{DynamicResource DataGridRowSelectedBackgroundColor}" />
+    <Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedBackgroundOpacity}" />
+  </Style>
+  <Style Selector="DataGridRow:pointerover DataGridRowHeader:selected:focus /template/ Rectangle#BackgroundRectangle">
+    <Setter Property="Fill" Value="{DynamicResource DataGridRowSelectedHoveredBackgroundColor}" />
+    <Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedHoveredBackgroundOpacity}" />
+  </Style>
+
+  <Style Selector="DataGridRowGroupHeader">
+    <Setter Property="Focusable" Value="False" />
+    <Setter Property="Foreground" Value="{DynamicResource DataGridRowGroupHeaderForegroundBrush}" />
+    <Setter Property="Background" Value="{DynamicResource DataGridRowGroupHeaderBackgroundBrush}" />
+    <Setter Property="FontSize" Value="15" />
+    <Setter Property="MinHeight" Value="32" />
+    <Setter Property="Template">
+      <ControlTemplate>
+        <DataGridFrozenGrid Name="PART_Root"
+                            MinHeight="{TemplateBinding MinHeight}"
+                            ColumnDefinitions="Auto,Auto,Auto,Auto,*"
+                            RowDefinitions="*,Auto">
+
+          <Rectangle Name="IndentSpacer"
+                     Grid.Column="1" />
+          <ToggleButton Name="ExpanderButton"
+                        Grid.Column="2"
+                        Width="12"
+                        Height="12"
+                        Margin="12,0,0,0"
+                        Background="{TemplateBinding Background}"
+                        Foreground="{TemplateBinding Foreground}"
+                        Focusable="False" />
+
+          <StackPanel Grid.Column="3"
+                      Orientation="Horizontal"
+                      VerticalAlignment="Center"
+                      Margin="12,0,0,0">
+            <TextBlock Name="PropertyNameElement"
+                       Margin="4,0,0,0"
+                       IsVisible="{TemplateBinding IsPropertyNameVisible}"
+                       Foreground="{TemplateBinding Foreground}" />
+            <TextBlock Margin="4,0,0,0"
+                       Text="{Binding Key}"
+                       Foreground="{TemplateBinding Foreground}" />
+            <TextBlock Name="ItemCountElement"
+                       Margin="4,0,0,0"
+                       IsVisible="{TemplateBinding IsItemCountVisible}"
+                       Foreground="{TemplateBinding Foreground}" />
+          </StackPanel>
+
+          <Rectangle x:Name="CurrencyVisual"
+                     Grid.ColumnSpan="5"
+                     HorizontalAlignment="Stretch"
+                     VerticalAlignment="Stretch"
+                     Fill="Transparent"
+                     IsHitTestVisible="False"
+                     Stroke="{DynamicResource DataGridCurrencyVisualPrimaryBrush}"
+                     StrokeThickness="1" />
+          <Grid x:Name="FocusVisual"
+                Grid.ColumnSpan="5"
+                IsHitTestVisible="False">
+            <Rectangle HorizontalAlignment="Stretch"
+                       VerticalAlignment="Stretch"
+                       Fill="Transparent"
+                       IsHitTestVisible="False"
+                       Stroke="{DynamicResource DataGridCellFocusVisualPrimaryBrush}"
+                       StrokeThickness="2" />
+            <Rectangle Margin="2"
+                       HorizontalAlignment="Stretch"
+                       VerticalAlignment="Stretch"
+                       Fill="Transparent"
+                       IsHitTestVisible="False"
+                       Stroke="{DynamicResource DataGridCellFocusVisualSecondaryBrush}"
+                       StrokeThickness="1" />
+          </Grid>
+
+          <DataGridRowHeader Name="PART_RowHeader"
+                             Grid.RowSpan="2"
+                             DataGridFrozenGrid.IsFrozen="True" />
+
+          <Rectangle x:Name="PART_BottomGridLine"
+                     Grid.Row="1"
+                     Grid.ColumnSpan="5"
+                     Height="1" />
+        </DataGridFrozenGrid>
+      </ControlTemplate>
+    </Setter>
+  </Style>
+
+  <Style Selector="DataGridRowGroupHeader /template/ ToggleButton#ExpanderButton">
+    <Setter Property="Template">
+      <ControlTemplate>
+        <Border Grid.Column="0"
+                Width="12"
+                Height="12"
+                Background="Transparent"
+                HorizontalAlignment="Center"
+                VerticalAlignment="Center">
+          <Path Fill="{TemplateBinding Foreground}"
+                HorizontalAlignment="Right"
+                VerticalAlignment="Center"
+                Stretch="Uniform" />
+        </Border>
+      </ControlTemplate>
+    </Setter>
+  </Style>
+
+  <Style Selector="DataGridRowGroupHeader /template/ ToggleButton#ExpanderButton /template/ Path">
+    <Setter Property="Data" Value="{StaticResource DataGridRowGroupHeaderIconOpenedPath}" />
+    <Setter Property="Stretch" Value="Uniform" />
+  </Style>
+
+  <Style Selector="DataGridRowGroupHeader /template/ ToggleButton#ExpanderButton:checked /template/ Path">
+    <Setter Property="Data" Value="{StaticResource DataGridRowGroupHeaderIconClosedPath}" />
+    <Setter Property="Stretch" Value="UniformToFill" />
+  </Style>
+
+  <Style Selector="DataGridRowGroupHeader /template/ DataGridFrozenGrid#PART_Root">
+    <Setter Property="Background" Value="{Binding $parent[DataGridRowGroupHeader].Background}" />
+  </Style>
+  <Style Selector="DataGridRowGroupHeader:pointerover /template/ DataGridFrozenGrid#PART_Root">
+    <Setter Property="Background" Value="{DynamicResource DataGridRowGroupHeaderHoveredBackgroundBrush}" />
+  </Style>
+  <Style Selector="DataGridRowGroupHeader:pressed /template/ DataGridFrozenGrid#PART_Root">
+    <Setter Property="Background" Value="{DynamicResource DataGridRowGroupHeaderPressedBackgroundBrush}" />
+  </Style>
+
+  <Style Selector="DataGridRowGroupHeader /template/ Rectangle#CurrencyVisual">
+    <Setter Property="IsVisible" Value="False" />
+  </Style>
+  <Style Selector="DataGridRowGroupHeader /template/ Grid#FocusVisual">
+    <Setter Property="IsVisible" Value="False" />
+  </Style>
+  <Style Selector="DataGridRowGroupHeader:current /template/ Rectangle#CurrencyVisual">
+    <Setter Property="IsVisible" Value="True" />
+  </Style>
+  <Style Selector="DataGrid:focus DataGridRowGroupHeader:current /template/ Grid#FocusVisual">
+    <Setter Property="IsVisible" Value="True" />
+  </Style>
+
+  <Style Selector="DataGrid">
+    <Setter Property="RowBackground" Value="Transparent" />
+    <Setter Property="AlternatingRowBackground" Value="Transparent" />
+    <Setter Property="HeadersVisibility" Value="Column" />
+    <Setter Property="HorizontalScrollBarVisibility" Value="Auto" />
+    <Setter Property="VerticalScrollBarVisibility" Value="Auto" />
+    <Setter Property="SelectionMode" Value="Extended" />
+    <Setter Property="GridLinesVisibility" Value="None" />
+    <Setter Property="HorizontalGridLinesBrush" Value="{DynamicResource DataGridGridLinesBrush}" />
+    <Setter Property="VerticalGridLinesBrush" Value="{DynamicResource DataGridGridLinesBrush}" />
+    <Setter Property="DropLocationIndicatorTemplate">
+      <Template>
+        <Rectangle Fill="{DynamicResource DataGridDropLocationIndicatorBackground}"
+                   Width="2" />
+      </Template>
+    </Setter>
+    <Setter Property="Template">
+      <ControlTemplate>
+        <Border Background="{TemplateBinding Background}"
+                BorderThickness="{TemplateBinding BorderThickness}"
+                BorderBrush="{TemplateBinding BorderBrush}">
+          <Grid RowDefinitions="Auto,*,Auto,Auto"
+                ColumnDefinitions="Auto,*,Auto">
+            <Grid.Resources>
+              <ControlTemplate x:Key="TopLeftHeaderTemplate"
+                               TargetType="DataGridColumnHeader">
+                <Grid x:Name="TopLeftHeaderRoot"
+                      RowDefinitions="*,*,Auto">
+                  <Border Grid.RowSpan="2"
+                          BorderThickness="0,0,1,0"
+                          BorderBrush="{DynamicResource DataGridGridLinesBrush}" />
+                  <Rectangle Grid.RowSpan="2"
+                             VerticalAlignment="Bottom"
+                             StrokeThickness="1"
+                             Height="1"
+                             Fill="{DynamicResource DataGridGridLinesBrush}" />
+                </Grid>
+              </ControlTemplate>
+              <ControlTemplate x:Key="TopRightHeaderTemplate"
+                               TargetType="DataGridColumnHeader">
+                <Grid x:Name="RootElement" />
+              </ControlTemplate>
+            </Grid.Resources>
+
+            <DataGridColumnHeader Name="PART_TopLeftCornerHeader"
+                                  Template="{StaticResource TopLeftHeaderTemplate}" />
+            <DataGridColumnHeadersPresenter Name="PART_ColumnHeadersPresenter"
+                                            Grid.Column="1"
+                                            Grid.ColumnSpan="2" />
+            <!--<DataGridColumnHeader Name="PART_TopRightCornerHeader"
+                                  Grid.Column="2"
+                                  Template="{StaticResource TopRightHeaderTemplate}" />-->
+            <!--<Rectangle Name="PART_ColumnHeadersAndRowsSeparator"
+                       Grid.ColumnSpan="3"
+                       VerticalAlignment="Bottom"
+                       StrokeThickness="1"
+                       Height="1"
+                       Fill="{DynamicResource DataGridGridLinesBrush}" />-->
+            <Border Name="PART_ColumnHeadersAndRowsSeparator"
+                    Grid.ColumnSpan="3"
+                    Height="2"
+                    VerticalAlignment="Bottom"
+                    BorderThickness="0,0,0,1"
+                    BorderBrush="{DynamicResource DataGridGridLinesBrush}" />
+
+            <DataGridRowsPresenter Name="PART_RowsPresenter"
+                                   Grid.Row="1"
+                                   Grid.RowSpan="2"
+                                   Grid.ColumnSpan="3" />
+            <Rectangle Name="PART_BottomRightCorner"
+                       Fill="{DynamicResource DataGridScrollBarsSeparatorBackground}"
+                       Grid.Column="2"
+                       Grid.Row="2" />
+            <!--<Rectangle Name="BottomLeftCorner"
+                       Fill="{DynamicResource DataGridScrollBarsSeparatorBackground}"
+                       Grid.Row="2"
+                       Grid.ColumnSpan="2" />-->
+            <ScrollBar Name="PART_VerticalScrollbar"
+                       Orientation="Vertical"
+                       Grid.Column="2"
+                       Grid.Row="1"
+                       Width="{DynamicResource ScrollBarSize}" />
+
+            <Grid Grid.Column="1"
+                  Grid.Row="2"
+                  ColumnDefinitions="Auto,*">
+              <Rectangle Name="PART_FrozenColumnScrollBarSpacer" />
+              <ScrollBar Name="PART_HorizontalScrollbar"
+                         Grid.Column="1"
+                         Orientation="Horizontal"
+                         Height="{DynamicResource ScrollBarSize}" />
+            </Grid>
+            <Border x:Name="PART_DisabledVisualElement"
+                    Grid.ColumnSpan="3"
+                    Grid.RowSpan="4"
+                    IsHitTestVisible="False"
+                    HorizontalAlignment="Stretch"
+                    VerticalAlignment="Stretch"
+                    CornerRadius="2"
+                    Background="{DynamicResource DataGridDisabledVisualElementBackground}"
+                    IsVisible="{Binding !$parent[DataGrid].IsEnabled}" />
+          </Grid>
+        </Border>
+      </ControlTemplate>
+    </Setter>
+  </Style>
+</Styles>