Browse Source

Merge branch 'master' into findresource-bench

pull/7971/head
Steven Kirk 4 years ago
committed by GitHub
parent
commit
653d9c0e35
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      samples/ControlCatalog/Pages/DataGridPage.xaml
  2. 4
      src/Avalonia.Base/LogicalTree/ChildIndexChangedEventArgs.cs
  3. 10
      src/Avalonia.Controls.DataGrid/DataGrid.cs
  4. 2
      src/Avalonia.Controls.DataGrid/DataGridColumn.cs
  5. 36
      src/Avalonia.Controls.DataGrid/DataGridColumnCollection.cs
  6. 9
      src/Avalonia.Controls.DataGrid/DataGridColumns.cs
  7. 36
      src/Avalonia.Controls.DataGrid/DataGridDataConnection.cs
  8. 39
      src/Avalonia.Controls.DataGrid/DataGridRow.cs
  9. 7
      src/Avalonia.Controls.DataGrid/DataGridRows.cs
  10. 5
      src/Avalonia.Controls.DataGrid/DataGridTextColumn.cs
  11. 39
      src/Avalonia.Controls.DataGrid/Primitives/DataGridCellsPresenter.cs
  12. 36
      src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs
  13. 29
      src/Avalonia.Controls.DataGrid/Primitives/DataGridRowsPresenter.cs
  14. 145
      src/Avalonia.Controls.DataGrid/Themes/Default.xaml
  15. 264
      src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml
  16. 5
      src/Avalonia.Controls/Calendar/DateTimeHelper.cs
  17. 2
      src/Avalonia.Controls/ItemsControl.cs
  18. 2
      src/Avalonia.Controls/Panel.cs
  19. 2
      src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs

19
samples/ControlCatalog/Pages/DataGridPage.xaml

@ -13,9 +13,22 @@
</UserControl.Resources> </UserControl.Resources>
<UserControl.Styles> <UserControl.Styles>
<Style Selector="DataGridCell.gdp"> <Style Selector="DataGridCell.gdp">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Background" Value="{Binding Path=GDP, Mode=OneWay, Converter={StaticResource GDPConverter}}" /> <Setter Property="Background" Value="{Binding Path=GDP, Mode=OneWay, Converter={StaticResource GDPConverter}}" />
</Style> </Style>
<Style Selector="DataGridColumnHeader:nth-last-child(1)">
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Style Selector="DataGridCell:nth-last-child(1)">
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Style Selector="DataGrid#dataGridGrouping DataGridRow:nth-child(5n+3)">
<Setter Property="Foreground" Value="Red" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Style Selector="DataGrid#dataGridGrouping DataGridRow:nth-last-child(5n+1)">
<Setter Property="Foreground" Value="Blue" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
</UserControl.Styles> </UserControl.Styles>
<Grid RowDefinitions="Auto,Auto,*"> <Grid RowDefinitions="Auto,Auto,*">
<StackPanel Orientation="Vertical" Spacing="4" Grid.Row="0"> <StackPanel Orientation="Vertical" Spacing="4" Grid.Row="0">
@ -31,7 +44,9 @@
<DockPanel> <DockPanel>
<CheckBox x:Name="ShowGDP" IsChecked="True" Content="Toggle GDP Column Visibility" <CheckBox x:Name="ShowGDP" IsChecked="True" Content="Toggle GDP Column Visibility"
DockPanel.Dock="Top"/> DockPanel.Dock="Top"/>
<DataGrid Name="dataGrid1" Margin="12" CanUserResizeColumns="True" CanUserReorderColumns="True" CanUserSortColumns="True" HeadersVisibility="All"> <DataGrid Name="dataGrid1" Margin="12" CanUserResizeColumns="True" CanUserReorderColumns="True" CanUserSortColumns="True" HeadersVisibility="All"
RowBackground="#1000"
AlternatingRowBackground="#1fff">
<DataGrid.Columns> <DataGrid.Columns>
<!-- Using HeaderTemplate --> <!-- Using HeaderTemplate -->
<DataGridTextColumn Header="Country" HeaderTemplate="{StaticResource Demo.DataTemplates.CountryHeader}" Binding="{Binding Name}" Width="6*" /> <DataGridTextColumn Header="Country" HeaderTemplate="{StaticResource Demo.DataTemplates.CountryHeader}" Binding="{Binding Name}" Width="6*" />

4
src/Avalonia.Base/LogicalTree/ChildIndexChangedEventArgs.cs

@ -8,7 +8,9 @@ namespace Avalonia.LogicalTree
/// </summary> /// </summary>
public class ChildIndexChangedEventArgs : EventArgs public class ChildIndexChangedEventArgs : EventArgs
{ {
public ChildIndexChangedEventArgs() public static new ChildIndexChangedEventArgs Empty { get; } = new ChildIndexChangedEventArgs();
private ChildIndexChangedEventArgs()
{ {
} }

10
src/Avalonia.Controls.DataGrid/DataGrid.cs

@ -669,8 +669,6 @@ namespace Avalonia.Controls
ItemsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnItemsPropertyChanged(e)); ItemsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnItemsPropertyChanged(e));
CanUserResizeColumnsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnCanUserResizeColumnsChanged(e)); CanUserResizeColumnsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnCanUserResizeColumnsChanged(e));
ColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnColumnWidthChanged(e)); ColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnColumnWidthChanged(e));
RowBackgroundProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowBackgroundChanged(e));
AlternatingRowBackgroundProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowBackgroundChanged(e));
FrozenColumnCountProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnFrozenColumnCountChanged(e)); FrozenColumnCountProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnFrozenColumnCountChanged(e));
GridLinesVisibilityProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnGridLinesVisibilityChanged(e)); GridLinesVisibilityProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnGridLinesVisibilityChanged(e));
HeadersVisibilityProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnHeadersVisibilityChanged(e)); HeadersVisibilityProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnHeadersVisibilityChanged(e));
@ -1144,14 +1142,6 @@ namespace Avalonia.Controls
InvalidateCellsArrange(); InvalidateCellsArrange();
} }
private void OnRowBackgroundChanged(AvaloniaPropertyChangedEventArgs e)
{
foreach (DataGridRow row in GetAllRows())
{
row.EnsureBackground();
}
}
private void OnColumnWidthChanged(AvaloniaPropertyChangedEventArgs e) private void OnColumnWidthChanged(AvaloniaPropertyChangedEventArgs e)
{ {
var value = (DataGridLength)e.NewValue; var value = (DataGridLength)e.NewValue;

2
src/Avalonia.Controls.DataGrid/DataGridColumn.cs

@ -199,7 +199,7 @@ namespace Avalonia.Controls
if (change.Property == IsVisibleProperty) if (change.Property == IsVisibleProperty)
{ {
OwningGrid?.OnColumnVisibleStateChanging(this); OwningGrid?.OnColumnVisibleStateChanging(this);
var isVisible = (change as AvaloniaPropertyChangedEventArgs<bool>).NewValue.Value; var isVisible = change.NewValue.GetValueOrDefault<bool>();
if (_headerCell != null) if (_headerCell != null)
{ {

36
src/Avalonia.Controls.DataGrid/DataGridColumnCollection.cs

@ -12,7 +12,8 @@ namespace Avalonia.Controls
{ {
internal class DataGridColumnCollection : ObservableCollection<DataGridColumn> internal class DataGridColumnCollection : ObservableCollection<DataGridColumn>
{ {
private DataGrid _owningGrid; private readonly Dictionary<int, int> _columnsMap = new Dictionary<int, int>();
private readonly DataGrid _owningGrid;
public DataGridColumnCollection(DataGrid owningGrid) public DataGridColumnCollection(DataGrid owningGrid)
{ {
@ -124,18 +125,8 @@ namespace Avalonia.Controls
internal int VisibleColumnCount internal int VisibleColumnCount
{ {
get get;
{ private set;
int visibleColumnCount = 0;
for (int columnIndex = 0; columnIndex < ItemsInternal.Count; columnIndex++)
{
if (ItemsInternal[columnIndex].IsVisible)
{
visibleColumnCount++;
}
}
return visibleColumnCount;
}
} }
internal double VisibleEdgedColumnsWidth internal double VisibleEdgedColumnsWidth
@ -287,20 +278,31 @@ namespace Avalonia.Controls
{ {
VisibleStarColumnCount = 0; VisibleStarColumnCount = 0;
VisibleEdgedColumnsWidth = 0; VisibleEdgedColumnsWidth = 0;
VisibleColumnCount = 0;
_columnsMap.Clear();
for (int columnIndex = 0; columnIndex < ItemsInternal.Count; columnIndex++) for (int columnIndex = 0; columnIndex < ItemsInternal.Count; columnIndex++)
{ {
if (ItemsInternal[columnIndex].IsVisible) var item = ItemsInternal[columnIndex];
_columnsMap[columnIndex] = item.DisplayIndex;
if (item.IsVisible)
{ {
ItemsInternal[columnIndex].EnsureWidth(); VisibleColumnCount++;
if (ItemsInternal[columnIndex].Width.IsStar) item.EnsureWidth();
if (item.Width.IsStar)
{ {
VisibleStarColumnCount++; VisibleStarColumnCount++;
} }
VisibleEdgedColumnsWidth += ItemsInternal[columnIndex].ActualWidth; VisibleEdgedColumnsWidth += item.ActualWidth;
} }
} }
} }
internal int GetColumnDisplayIndex(int columnIndex)
{
return _columnsMap.TryGetValue(columnIndex, out var displayIndex) ? displayIndex : -1;
}
internal DataGridColumn GetColumnAtDisplayIndex(int displayIndex) internal DataGridColumn GetColumnAtDisplayIndex(int displayIndex)
{ {
if (displayIndex < 0 || displayIndex >= ItemsInternal.Count || displayIndex >= DisplayIndexMap.Count) if (displayIndex < 0 || displayIndex >= ItemsInternal.Count || displayIndex >= DisplayIndexMap.Count)

9
src/Avalonia.Controls.DataGrid/DataGridColumns.cs

@ -444,12 +444,11 @@ namespace Avalonia.Controls
// We need to explicitly collapse the cells of the invisible column because layout only goes through // We need to explicitly collapse the cells of the invisible column because layout only goes through
// visible ones // visible ones
if (!updatedColumn.IsVisible) ColumnHeaders?.InvalidateChildIndex();
foreach (var row in GetAllRows())
{ {
foreach (DataGridRow row in GetAllRows()) row.Cells[updatedColumn.Index].IsVisible = updatedColumn.IsVisible;
{ row.InvalidateCellsIndex();
row.Cells[updatedColumn.Index].IsVisible = false;
}
} }
} }

36
src/Avalonia.Controls.DataGrid/DataGridDataConnection.cs

@ -77,7 +77,7 @@ namespace Avalonia.Controls
private set; private set;
} }
public int Count => GetCount(true); public int Count => TryGetCount(true, false, out var count) ? count : 0;
public bool DataIsPrimitive public bool DataIsPrimitive
{ {
@ -193,22 +193,25 @@ namespace Avalonia.Controls
} }
} }
internal bool Any()
{
return GetCount(false) > 0;
}
/// <param name="allowSlow">When "allowSlow" is false, method will not use Linq.Count() method and will return 0 or 1 instead.</param> /// <param name="allowSlow">When "allowSlow" is false, method will not use Linq.Count() method and will return 0 or 1 instead.</param>
private int GetCount(bool allowSlow) /// <param name="getAny">If "getAny" is true, method can use Linq.Any() method to speedup.</param>
internal bool TryGetCount(bool allowSlow, bool getAny, out int count)
{ {
return DataSource switch bool result;
(result, count) = DataSource switch
{ {
ICollection collection => collection.Count, ICollection collection => (true, collection.Count),
DataGridCollectionView cv => cv.Count, DataGridCollectionView cv => (true, cv.Count),
IEnumerable enumerable when allowSlow => enumerable.Cast<object>().Count(), IEnumerable enumerable when allowSlow && !getAny => (true, enumerable.Cast<object>().Count()),
IEnumerable enumerable when !allowSlow => enumerable.Cast<object>().Any() ? 1 : 0, IEnumerable enumerable when getAny => (true, enumerable.Cast<object>().Any() ? 1 : 0),
_ => 0 _ => (false, 0)
}; };
return result;
}
internal bool Any()
{
return TryGetCount(false, true, out var count) && count > 0;
} }
/// <summary> /// <summary>
@ -383,7 +386,7 @@ namespace Avalonia.Controls
List<string> propertyNames = TypeHelper.SplitPropertyPath(propertyName); List<string> propertyNames = TypeHelper.SplitPropertyPath(propertyName);
for (int i = 0; i < propertyNames.Count; i++) for (int i = 0; i < propertyNames.Count; i++)
{ {
propertyInfo = propertyType.GetPropertyOrIndexer(propertyNames[i], out object[] index); propertyInfo = propertyType.GetPropertyOrIndexer(propertyNames[i], out _);
if (propertyInfo == null || propertyType.GetIsReadOnly() || propertyInfo.GetIsReadOnly()) if (propertyInfo == null || propertyType.GetIsReadOnly() || propertyInfo.GetIsReadOnly())
{ {
// Either the data type is read-only, the property doesn't exist, or it does exist but is read-only // Either the data type is read-only, the property doesn't exist, or it does exist but is read-only
@ -391,11 +394,10 @@ namespace Avalonia.Controls
} }
// Check if EditableAttribute is defined on the property and if it indicates uneditable // Check if EditableAttribute is defined on the property and if it indicates uneditable
object[] attributes = propertyInfo.GetCustomAttributes(typeof(EditableAttribute), true); var attributes = propertyInfo.GetCustomAttributes(typeof(EditableAttribute), true);
if (attributes != null && attributes.Length > 0) if (attributes != null && attributes.Length > 0)
{ {
EditableAttribute editableAttribute = attributes[0] as EditableAttribute; var editableAttribute = (EditableAttribute)attributes[0];
Debug.Assert(editableAttribute != null);
if (!editableAttribute.AllowEdit) if (!editableAttribute.AllowEdit)
{ {
return true; return true;

39
src/Avalonia.Controls.DataGrid/DataGridRow.cs

@ -543,7 +543,6 @@ namespace Avalonia.Controls
RootElement = e.NameScope.Find<Panel>(DATAGRIDROW_elementRoot); RootElement = e.NameScope.Find<Panel>(DATAGRIDROW_elementRoot);
if (RootElement != null) if (RootElement != null)
{ {
EnsureBackground();
UpdatePseudoClasses(); UpdatePseudoClasses();
} }
@ -668,43 +667,9 @@ namespace Avalonia.Controls
Slot = -1; Slot = -1;
} }
// Make sure the row's background is set to its correct value. It could be explicity set or inherit internal void InvalidateCellsIndex()
// DataGrid.RowBackground or DataGrid.AlternatingRowBackground
internal void EnsureBackground()
{ {
// Inherit the DataGrid's RowBackground properties only if this row doesn't explicity have a background set _cellsElement?.InvalidateChildIndex();
if (RootElement != null && OwningGrid != null)
{
IBrush newBackground = null;
if (Background == null)
{
if (Index % 2 == 0 || OwningGrid.AlternatingRowBackground == null)
{
// Use OwningGrid.RowBackground if the index is even or if the OwningGrid.AlternatingRowBackground is null
if (OwningGrid.RowBackground != null)
{
newBackground = OwningGrid.RowBackground;
}
}
else
{
// Alternate row
if (OwningGrid.AlternatingRowBackground != null)
{
newBackground = OwningGrid.AlternatingRowBackground;
}
}
}
else
{
newBackground = Background;
}
if (RootElement.Background != newBackground)
{
RootElement.Background = newBackground;
}
}
} }
internal void EnsureFillerVisibility() internal void EnsureFillerVisibility()

7
src/Avalonia.Controls.DataGrid/DataGridRows.cs

@ -5,6 +5,7 @@
using Avalonia.Collections; using Avalonia.Collections;
using Avalonia.Controls.Utils; using Avalonia.Controls.Utils;
using Avalonia.LogicalTree;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Utilities; using Avalonia.Utilities;
using System; using System;
@ -811,7 +812,7 @@ namespace Avalonia.Controls
if (row.Slot > slotDeleted) if (row.Slot > slotDeleted)
{ {
CorrectRowAfterDeletion(row, wasRow); CorrectRowAfterDeletion(row, wasRow);
row.EnsureBackground(); _rowsPresenter?.InvalidateChildIndex(row);
} }
} }
@ -867,7 +868,7 @@ namespace Avalonia.Controls
if (row.Slot >= slotInserted) if (row.Slot >= slotInserted)
{ {
DataGrid.CorrectRowAfterInsertion(row, rowInserted); DataGrid.CorrectRowAfterInsertion(row, rowInserted);
row.EnsureBackground(); _rowsPresenter?.InvalidateChildIndex(row);
} }
} }
@ -1485,8 +1486,8 @@ namespace Avalonia.Controls
// If the row has been recycled, reapply the BackgroundBrush // If the row has been recycled, reapply the BackgroundBrush
if (row.IsRecycled) if (row.IsRecycled)
{ {
row.EnsureBackground();
row.ApplyCellsState(); row.ApplyCellsState();
_rowsPresenter?.InvalidateChildIndex(row);
} }
else if (row == EditingRow) else if (row == EditingRow)
{ {

5
src/Avalonia.Controls.DataGrid/DataGridTextColumn.cs

@ -19,8 +19,6 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public class DataGridTextColumn : DataGridBoundColumn public class DataGridTextColumn : DataGridBoundColumn
{ {
private const string DATAGRID_TextColumnCellTextBlockMarginKey = "DataGridTextColumnCellTextBlockMargin";
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:Avalonia.Controls.DataGridTextColumn" /> class. /// Initializes a new instance of the <see cref="T:Avalonia.Controls.DataGridTextColumn" /> class.
/// </summary> /// </summary>
@ -178,8 +176,7 @@ namespace Avalonia.Controls
{ {
TextBlock textBlockElement = new TextBlock TextBlock textBlockElement = new TextBlock
{ {
[!Layoutable.MarginProperty] = new DynamicResourceExtension(DATAGRID_TextColumnCellTextBlockMarginKey), Name = "CellTextBlock"
VerticalAlignment = VerticalAlignment.Center
}; };
SyncProperties(textBlockElement); SyncProperties(textBlockElement);

39
src/Avalonia.Controls.DataGrid/Primitives/DataGridCellsPresenter.cs

@ -3,12 +3,13 @@
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved. // All other rights reserved.
using Avalonia.LogicalTree;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Utilities; using Avalonia.Utilities;
using System; using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics; using System.Diagnostics;
using Avalonia.Controls;
using Avalonia.Controls.Utils;
namespace Avalonia.Controls.Primitives namespace Avalonia.Controls.Primitives
{ {
@ -16,9 +17,10 @@ namespace Avalonia.Controls.Primitives
/// Used within the template of a <see cref="T:Avalonia.Controls.DataGrid" /> /// Used within the template of a <see cref="T:Avalonia.Controls.DataGrid" />
/// to specify the location in the control's visual tree where the cells are to be added. /// to specify the location in the control's visual tree where the cells are to be added.
/// </summary> /// </summary>
public sealed class DataGridCellsPresenter : Panel public sealed class DataGridCellsPresenter : Panel, IChildIndexProvider
{ {
private double _fillerLeftEdge; private double _fillerLeftEdge;
private EventHandler<ChildIndexChangedEventArgs> _childIndexChanged;
// The desired height needs to be cached due to column virtualization; otherwise, the cells // The desired height needs to be cached due to column virtualization; otherwise, the cells
// would grow and shrink as the DataGrid scrolls horizontally // would grow and shrink as the DataGrid scrolls horizontally
@ -42,6 +44,25 @@ namespace Avalonia.Controls.Primitives
set; set;
} }
event EventHandler<ChildIndexChangedEventArgs> IChildIndexProvider.ChildIndexChanged
{
add => _childIndexChanged += value;
remove => _childIndexChanged -= value;
}
int IChildIndexProvider.GetChildIndex(ILogical child)
{
return child is DataGridCell cell
? OwningGrid.ColumnsInternal.GetColumnDisplayIndex(cell.ColumnIndex)
: throw new InvalidOperationException("Invalid cell type");
}
bool IChildIndexProvider.TryGetTotalCount(out int count)
{
count = OwningGrid.ColumnsInternal.VisibleColumnCount;
return true;
}
/// <summary> /// <summary>
/// Arranges the content of the <see cref="T:Avalonia.Controls.Primitives.DataGridCellsPresenter" />. /// Arranges the content of the <see cref="T:Avalonia.Controls.Primitives.DataGridCellsPresenter" />.
/// </summary> /// </summary>
@ -120,6 +141,13 @@ namespace Avalonia.Controls.Primitives
} }
} }
protected override void ChildrenChanged(object sender, NotifyCollectionChangedEventArgs e)
{
base.ChildrenChanged(sender, e);
InvalidateChildIndex();
}
private static void EnsureCellDisplay(DataGridCell cell, bool displayColumn) private static void EnsureCellDisplay(DataGridCell cell, bool displayColumn)
{ {
if (cell.IsCurrent) if (cell.IsCurrent)
@ -304,6 +332,11 @@ namespace Avalonia.Controls.Primitives
DesiredHeight = 0; DesiredHeight = 0;
} }
internal void InvalidateChildIndex()
{
_childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.Empty);
}
private bool ShouldDisplayCell(DataGridColumn column, double frozenLeftEdge, double scrollingLeftEdge) private bool ShouldDisplayCell(DataGridColumn column, double frozenLeftEdge, double scrollingLeftEdge)
{ {
if (!column.IsVisible) if (!column.IsVisible)

36
src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs

@ -3,8 +3,10 @@
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved. // All other rights reserved.
using Avalonia.LogicalTree;
using Avalonia.Media; using Avalonia.Media;
using System; using System;
using System.Collections.Specialized;
using System.Diagnostics; using System.Diagnostics;
namespace Avalonia.Controls.Primitives namespace Avalonia.Controls.Primitives
@ -13,10 +15,11 @@ namespace Avalonia.Controls.Primitives
/// Used within the template of a <see cref="T:Avalonia.Controls.DataGrid" /> to specify the /// Used within the template of a <see cref="T:Avalonia.Controls.DataGrid" /> to specify the
/// location in the control's visual tree where the column headers are to be added. /// location in the control's visual tree where the column headers are to be added.
/// </summary> /// </summary>
public sealed class DataGridColumnHeadersPresenter : Panel public sealed class DataGridColumnHeadersPresenter : Panel, IChildIndexProvider
{ {
private Control _dragIndicator; private Control _dragIndicator;
private IControl _dropLocationIndicator; private IControl _dropLocationIndicator;
private EventHandler<ChildIndexChangedEventArgs> _childIndexChanged;
/// <summary> /// <summary>
/// Tracks which column is currently being dragged. /// Tracks which column is currently being dragged.
@ -104,6 +107,25 @@ namespace Avalonia.Controls.Primitives
set; set;
} }
event EventHandler<ChildIndexChangedEventArgs> IChildIndexProvider.ChildIndexChanged
{
add => _childIndexChanged += value;
remove => _childIndexChanged -= value;
}
int IChildIndexProvider.GetChildIndex(ILogical child)
{
return child is DataGridColumnHeader header
? OwningGrid.ColumnsInternal.GetColumnDisplayIndex(header.ColumnIndex)
: throw new InvalidOperationException("Invalid cell type");
}
bool IChildIndexProvider.TryGetTotalCount(out int count)
{
count = OwningGrid.ColumnsInternal.VisibleColumnCount;
return true;
}
/// <summary> /// <summary>
/// Arranges the content of the <see cref="T:Avalonia.Controls.Primitives.DataGridColumnHeadersPresenter" />. /// Arranges the content of the <see cref="T:Avalonia.Controls.Primitives.DataGridColumnHeadersPresenter" />.
/// </summary> /// </summary>
@ -391,5 +413,17 @@ namespace Avalonia.Controls.Primitives
OwningGrid.ColumnsInternal.EnsureVisibleEdgedColumnsWidth(); OwningGrid.ColumnsInternal.EnsureVisibleEdgedColumnsWidth();
return new Size(OwningGrid.ColumnsInternal.VisibleEdgedColumnsWidth, height); return new Size(OwningGrid.ColumnsInternal.VisibleEdgedColumnsWidth, height);
} }
protected override void ChildrenChanged(object sender, NotifyCollectionChangedEventArgs e)
{
base.ChildrenChanged(sender, e);
InvalidateChildIndex();
}
internal void InvalidateChildIndex()
{
_childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.Empty);
}
} }
} }

29
src/Avalonia.Controls.DataGrid/Primitives/DataGridRowsPresenter.cs

@ -7,8 +7,8 @@ using System;
using System.Diagnostics; using System.Diagnostics;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.GestureRecognizers;
using Avalonia.Layout; using Avalonia.Layout;
using Avalonia.LogicalTree;
using Avalonia.Media; using Avalonia.Media;
namespace Avalonia.Controls.Primitives namespace Avalonia.Controls.Primitives
@ -17,8 +17,10 @@ namespace Avalonia.Controls.Primitives
/// Used within the template of a <see cref="T:Avalonia.Controls.DataGrid" /> to specify the /// Used within the template of a <see cref="T:Avalonia.Controls.DataGrid" /> to specify the
/// location in the control's visual tree where the rows are to be added. /// location in the control's visual tree where the rows are to be added.
/// </summary> /// </summary>
public sealed class DataGridRowsPresenter : Panel public sealed class DataGridRowsPresenter : Panel, IChildIndexProvider
{ {
private EventHandler<ChildIndexChangedEventArgs> _childIndexChanged;
public DataGridRowsPresenter() public DataGridRowsPresenter()
{ {
AddHandler(Gestures.ScrollGestureEvent, OnScrollGesture); AddHandler(Gestures.ScrollGestureEvent, OnScrollGesture);
@ -44,6 +46,29 @@ namespace Avalonia.Controls.Primitives
} }
} }
event EventHandler<ChildIndexChangedEventArgs> IChildIndexProvider.ChildIndexChanged
{
add => _childIndexChanged += value;
remove => _childIndexChanged -= value;
}
int IChildIndexProvider.GetChildIndex(ILogical child)
{
return child is DataGridRow row
? row.Index
: throw new InvalidOperationException("Invalid DataGrid child");
}
bool IChildIndexProvider.TryGetTotalCount(out int count)
{
return OwningGrid.DataConnection.TryGetCount(false, true, out count);
}
internal void InvalidateChildIndex(DataGridRow row)
{
_childIndexChanged?.Invoke(this, new ChildIndexChangedEventArgs(row));
}
/// <summary> /// <summary>
/// Arranges the content of the <see cref="T:Avalonia.Controls.Primitives.DataGridRowsPresenter" />. /// Arranges the content of the <see cref="T:Avalonia.Controls.Primitives.DataGridRowsPresenter" />.
/// </summary> /// </summary>

145
src/Avalonia.Controls.DataGrid/Themes/Default.xaml

@ -12,23 +12,32 @@
<Setter Property="VerticalContentAlignment" Value="Stretch" /> <Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Grid ColumnDefinitions="*,Auto" <Border x:Name="CellBorder"
Background="{TemplateBinding Background}"> Background="{TemplateBinding Background}"
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" BorderBrush="{TemplateBinding BorderBrush}"
Content="{TemplateBinding Content}" BorderThickness="{TemplateBinding BorderThickness}"
Margin="{TemplateBinding Padding}" CornerRadius="{TemplateBinding CornerRadius}">
TextElement.Foreground="{TemplateBinding Foreground}" <Grid ColumnDefinitions="*,Auto">
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}"
<Rectangle Name="PART_RightGridLine" Foreground="{TemplateBinding Foreground}"
Grid.Column="1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="Stretch" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
Width="1" />
</Grid> <Rectangle Name="PART_RightGridLine"
Grid.Column="1"
VerticalAlignment="Stretch"
Width="1" />
</Grid>
</Border>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </Style>
<Style Selector="DataGridCell > TextBlock#CellTextBlock">
<Setter Property="Margin" Value="{DynamicResource DataGridTextColumnCellTextBlockMargin}" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style Selector="DataGridColumnHeader"> <Style Selector="DataGridColumnHeader">
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}" /> <Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}" />
@ -40,35 +49,40 @@
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Grid ColumnDefinitions="*,Auto" <Border x:Name="HeaderBorder"
Background="{TemplateBinding Background}"> Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
<Grid ColumnDefinitions="*,Auto" BorderThickness="{TemplateBinding BorderThickness}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" CornerRadius="{TemplateBinding CornerRadius}">
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" <Grid ColumnDefinitions="*,Auto">
Margin="{TemplateBinding Padding}">
<ContentPresenter Content="{TemplateBinding Content}" <Grid ColumnDefinitions="*,Auto"
ContentTemplate="{TemplateBinding ContentTemplate}" /> HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
<Path Name="SortIcon" Margin="{TemplateBinding Padding}">
Grid.Column="1" <ContentPresenter Content="{TemplateBinding Content}"
Fill="{TemplateBinding Foreground}" ContentTemplate="{TemplateBinding ContentTemplate}" />
HorizontalAlignment="Left"
VerticalAlignment="Center" <Path Name="SortIcon"
Stretch="Uniform" Grid.Column="1"
Width="8" Fill="{TemplateBinding Foreground}"
Margin="4,0,0,0" HorizontalAlignment="Left"
Data="F1 M -5.215,6.099L 5.215,6.099L 0,0L -5.215,6.099 Z "/> VerticalAlignment="Center"
Stretch="Uniform"
Width="8"
Margin="4,0,0,0"
Data="F1 M -5.215,6.099L 5.215,6.099L 0,0L -5.215,6.099 Z "/>
</Grid> </Grid>
<Rectangle Name="VerticalSeparator" <Rectangle Name="VerticalSeparator"
Grid.Column="1" Width="1" Grid.Column="1" Width="1"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
Fill="{TemplateBinding SeparatorBrush}" Fill="{TemplateBinding SeparatorBrush}"
IsVisible="{TemplateBinding AreSeparatorsVisible}" /> IsVisible="{TemplateBinding AreSeparatorsVisible}" />
</Grid> </Grid>
</Border>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </Style>
@ -102,22 +116,35 @@
<Style Selector="DataGridRow"> <Style Selector="DataGridRow">
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<DataGridFrozenGrid Name="PART_Root" <Border x:Name="RowBorder"
RowDefinitions="*,Auto,Auto" Background="{TemplateBinding Background}"
ColumnDefinitions="Auto,*"> BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<DataGridFrozenGrid Name="PART_Root"
RowDefinitions="*,Auto,Auto"
ColumnDefinitions="Auto,*">
<Rectangle Name="BackgroundRectangle" Grid.RowSpan="2" Grid.ColumnSpan="2"/> <Rectangle Name="BackgroundRectangle" Grid.RowSpan="2" Grid.ColumnSpan="2"/>
<DataGridRowHeader Grid.RowSpan="3" Name="PART_RowHeader" DataGridFrozenGrid.IsFrozen="True" /> <DataGridRowHeader Grid.RowSpan="3" Name="PART_RowHeader" DataGridFrozenGrid.IsFrozen="True" />
<DataGridCellsPresenter Grid.Column="1" Name="PART_CellsPresenter" DataGridFrozenGrid.IsFrozen="True" /> <DataGridCellsPresenter Grid.Column="1" Name="PART_CellsPresenter" DataGridFrozenGrid.IsFrozen="True" />
<DataGridDetailsPresenter Grid.Row="1" Grid.Column="1" Name="PART_DetailsPresenter"/> <DataGridDetailsPresenter Grid.Row="1" Grid.Column="1" Name="PART_DetailsPresenter"/>
<Rectangle Grid.Row="2" Grid.Column="1" Name="PART_BottomGridLine" HorizontalAlignment="Stretch" Height="1" /> <Rectangle Grid.Row="2" Grid.Column="1" Name="PART_BottomGridLine" HorizontalAlignment="Stretch" Height="1" />
</DataGridFrozenGrid> </DataGridFrozenGrid>
</Border>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </Style>
<Style Selector="DataGridRow">
<Setter Property="Background" Value="{Binding $parent[DataGrid].RowBackground}" />
</Style>
<Style Selector="DataGridRow:nth-child(even)">
<Setter Property="Background" Value="{Binding $parent[DataGrid].AlternatingRowBackground}" />
</Style>
<Style Selector="DataGridRow /template/ Rectangle#BackgroundRectangle"> <Style Selector="DataGridRow /template/ Rectangle#BackgroundRectangle">
<Setter Property="IsVisible" Value="False"/> <Setter Property="IsVisible" Value="False"/>
<Setter Property="Fill" Value="{DynamicResource HighlightBrush}" /> <Setter Property="Fill" Value="{DynamicResource HighlightBrush}" />
@ -180,12 +207,18 @@
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<DataGridFrozenGrid Name="Root" <DataGridFrozenGrid Name="Root"
Background="{TemplateBinding Background}" ColumnDefinitions="Auto,Auto,Auto,Auto"
ColumnDefinitions="Auto,Auto,Auto,Auto" RowDefinitions="Auto,*,Auto">
RowDefinitions="Auto,*,Auto">
<Rectangle Grid.Column="1" Grid.Row="1" Name="IndentSpacer" /> <Rectangle Grid.Column="1" Grid.Row="1" Name="IndentSpacer" />
<ToggleButton Grid.Column="2" Grid.Row="1" Name="ExpanderButton" Margin="2,0,0,0"/> <ToggleButton Grid.Column="2" Grid.Row="1"
Name="ExpanderButton"
Margin="2,0,0,0"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
CornerRadius="{TemplateBinding CornerRadius}"
Foreground="{TemplateBinding Foreground}" />
<StackPanel Grid.Column="3" Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center" Margin="0,1,0,1"> <StackPanel Grid.Column="3" Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center" Margin="0,1,0,1">
<TextBlock Name="PropertyNameElement" Margin="4,0,0,0" IsVisible="{TemplateBinding IsPropertyNameVisible}"/> <TextBlock Name="PropertyNameElement" Margin="4,0,0,0" IsVisible="{TemplateBinding IsPropertyNameVisible}"/>
@ -238,9 +271,11 @@
</Setter> </Setter>
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border Background="{TemplateBinding Background}" <Border x:Name="DataGridBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"> CornerRadius="{TemplateBinding CornerRadius}">
<Grid RowDefinitions="Auto,*,Auto,Auto" ColumnDefinitions="Auto,*,Auto"> <Grid RowDefinitions="Auto,*,Auto,Auto" ColumnDefinitions="Auto,*,Auto">
<DataGridColumnHeader Name="PART_TopLeftCornerHeader" Width="22" /> <DataGridColumnHeader Name="PART_TopLeftCornerHeader" Width="22" />

264
src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml

@ -93,58 +93,66 @@
<Setter Property="Focusable" Value="False" /> <Setter Property="Focusable" Value="False" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Grid x:Name="PART_CellRoot" <Border x:Name="CellBorder"
ColumnDefinitions="*,Auto" Background="{TemplateBinding Background}"
Background="{TemplateBinding Background}"> BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid x:Name="PART_CellRoot" ColumnDefinitions="*,Auto">
<Rectangle x:Name="CurrencyVisual" <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" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
Fill="Transparent" Fill="Transparent"
IsHitTestVisible="False" IsHitTestVisible="False"
Stroke="{DynamicResource DataGridCellFocusVisualSecondaryBrush}" Stroke="{DynamicResource DataGridCurrencyVisualPrimaryBrush}"
StrokeThickness="1" /> StrokeThickness="1" />
</Grid> <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}" <ContentPresenter Margin="{TemplateBinding Padding}"
Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
TextElement.Foreground="{TemplateBinding Foreground}" Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" ContentTemplate="{TemplateBinding ContentTemplate}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> Foreground="{TemplateBinding Foreground}" />
<Rectangle x:Name="InvalidVisualElement" <Rectangle x:Name="InvalidVisualElement"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
IsHitTestVisible="False" IsHitTestVisible="False"
Stroke="{DynamicResource DataGridCellInvalidBrush}" Stroke="{DynamicResource DataGridCellInvalidBrush}"
StrokeThickness="1" /> StrokeThickness="1" />
<Rectangle Name="PART_RightGridLine" <Rectangle Name="PART_RightGridLine"
Grid.Column="1" Grid.Column="1"
VerticalAlignment="Stretch" Width="1"
Width="1" VerticalAlignment="Stretch"
Fill="{DynamicResource DataGridFillerColumnGridLinesBrush}" /> Fill="{DynamicResource DataGridFillerColumnGridLinesBrush}" />
</Grid> </Grid>
</Border>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </Style>
<Style Selector="DataGridCell > TextBlock#CellTextBlock">
<Setter Property="Margin" Value="{DynamicResource DataGridTextColumnCellTextBlockMargin}" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style Selector="DataGridCell /template/ Rectangle#CurrencyVisual"> <Style Selector="DataGridCell /template/ Rectangle#CurrencyVisual">
<Setter Property="IsVisible" Value="False" /> <Setter Property="IsVisible" Value="False" />
</Style> </Style>
@ -180,57 +188,58 @@
<Setter Property="MinHeight" Value="32" /> <Setter Property="MinHeight" Value="32" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Grid Name="PART_ColumnHeaderRoot" <Border x:Name="HeaderBorder"
ColumnDefinitions="*,Auto" Background="{TemplateBinding Background}"
Background="{TemplateBinding Background}"> BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
<Grid HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" CornerRadius="{TemplateBinding CornerRadius}">
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" <Grid Name="PART_ColumnHeaderRoot" ColumnDefinitions="*,Auto">
Margin="{TemplateBinding Padding}">
<Grid.ColumnDefinitions> <Grid Margin="{TemplateBinding Padding}"
<ColumnDefinition Width="*" /> HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
<ColumnDefinition MinWidth="32" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
Width="Auto" /> <Grid.ColumnDefinitions>
</Grid.ColumnDefinitions> <ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" MinWidth="32" />
<ContentPresenter Content="{TemplateBinding Content}" </Grid.ColumnDefinitions>
ContentTemplate="{TemplateBinding ContentTemplate}" />
<ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" />
<Path Name="SortIcon"
Grid.Column="1" <Path Name="SortIcon"
Fill="{TemplateBinding Foreground}" Grid.Column="1"
HorizontalAlignment="Center" Height="12"
VerticalAlignment="Center" HorizontalAlignment="Center"
Stretch="Uniform" VerticalAlignment="Center"
Height="12" /> Fill="{TemplateBinding Foreground}"
</Grid> Stretch="Uniform" />
</Grid>
<Rectangle Name="VerticalSeparator"
Grid.Column="1"
Width="1"
VerticalAlignment="Stretch"
Fill="{TemplateBinding SeparatorBrush}"
IsVisible="{TemplateBinding AreSeparatorsVisible}" />
<Grid x:Name="FocusVisual" <Rectangle Name="VerticalSeparator"
IsHitTestVisible="False"> Grid.Column="1"
<Rectangle x:Name="FocusVisualPrimary" Width="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
Fill="Transparent" Fill="{TemplateBinding SeparatorBrush}"
IsHitTestVisible="False" IsVisible="{TemplateBinding AreSeparatorsVisible}" />
Stroke="{DynamicResource DataGridCellFocusVisualPrimaryBrush}"
StrokeThickness="2" /> <Grid x:Name="FocusVisual" IsHitTestVisible="False">
<Rectangle x:Name="FocusVisualSecondary" <Rectangle x:Name="FocusVisualPrimary"
Margin="2" HorizontalAlignment="Stretch"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
VerticalAlignment="Stretch" Fill="Transparent"
Fill="Transparent" IsHitTestVisible="False"
IsHitTestVisible="False" Stroke="{DynamicResource DataGridCellFocusVisualPrimaryBrush}"
Stroke="{DynamicResource DataGridCellFocusVisualSecondaryBrush}" StrokeThickness="2" />
StrokeThickness="1" /> <Rectangle x:Name="FocusVisualSecondary"
Margin="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="Transparent"
IsHitTestVisible="False"
Stroke="{DynamicResource DataGridCellFocusVisualSecondaryBrush}"
StrokeThickness="1" />
</Grid>
</Grid> </Grid>
</Grid> </Border>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </Style>
@ -271,38 +280,51 @@
<Setter Property="Focusable" Value="False" /> <Setter Property="Focusable" Value="False" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<DataGridFrozenGrid Name="PART_Root" <Border x:Name="RowBorder"
RowDefinitions="*,Auto,Auto" Background="{TemplateBinding Background}"
ColumnDefinitions="Auto,*"> BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
<Rectangle Name="BackgroundRectangle" CornerRadius="{TemplateBinding CornerRadius}">
Grid.RowSpan="2" <DataGridFrozenGrid Name="PART_Root"
Grid.ColumnSpan="2" /> ColumnDefinitions="Auto,*"
<Rectangle x:Name="InvalidVisualElement" RowDefinitions="*,Auto,Auto">
Grid.ColumnSpan="2"
Fill="{DynamicResource DataGridRowInvalidBrush}" /> <Rectangle Name="BackgroundRectangle"
Grid.RowSpan="2"
<DataGridRowHeader Name="PART_RowHeader" Grid.ColumnSpan="2" />
Grid.RowSpan="3" <Rectangle x:Name="InvalidVisualElement"
DataGridFrozenGrid.IsFrozen="True" /> Grid.ColumnSpan="2"
<DataGridCellsPresenter Name="PART_CellsPresenter" Fill="{DynamicResource DataGridRowInvalidBrush}" />
Grid.Column="1"
DataGridFrozenGrid.IsFrozen="True" /> <DataGridRowHeader Name="PART_RowHeader"
<DataGridDetailsPresenter Name="PART_DetailsPresenter" Grid.RowSpan="3"
Grid.Row="1" DataGridFrozenGrid.IsFrozen="True" />
<DataGridCellsPresenter Name="PART_CellsPresenter"
Grid.Column="1" Grid.Column="1"
Background="{DynamicResource DataGridDetailsPresenterBackgroundBrush}" /> DataGridFrozenGrid.IsFrozen="True" />
<Rectangle Name="PART_BottomGridLine" <DataGridDetailsPresenter Name="PART_DetailsPresenter"
Grid.Row="2" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
HorizontalAlignment="Stretch" Background="{DynamicResource DataGridDetailsPresenterBackgroundBrush}" />
Height="1" /> <Rectangle Name="PART_BottomGridLine"
Grid.Row="2"
Grid.Column="1"
Height="1"
HorizontalAlignment="Stretch" />
</DataGridFrozenGrid> </DataGridFrozenGrid>
</Border>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </Style>
<Style Selector="DataGridRow">
<Setter Property="Background" Value="{Binding $parent[DataGrid].RowBackground}" />
</Style>
<Style Selector="DataGridRow:nth-child(even)">
<Setter Property="Background" Value="{Binding $parent[DataGrid].AlternatingRowBackground}" />
</Style>
<Style Selector="DataGridRow /template/ Rectangle#InvalidVisualElement"> <Style Selector="DataGridRow /template/ Rectangle#InvalidVisualElement">
<Setter Property="Opacity" Value="0" /> <Setter Property="Opacity" Value="0" />
</Style> </Style>
@ -430,9 +452,12 @@
Width="12" Width="12"
Height="12" Height="12"
Margin="12,0,0,0" Margin="12,0,0,0"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
Foreground="{TemplateBinding Foreground}" CornerRadius="{TemplateBinding CornerRadius}"
Focusable="False" /> Focusable="False"
Foreground="{TemplateBinding Foreground}" />
<StackPanel Grid.Column="3" <StackPanel Grid.Column="3"
Orientation="Horizontal" Orientation="Horizontal"
@ -559,11 +584,12 @@
</Setter> </Setter>
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border Background="{TemplateBinding Background}" <Border x:Name="DataGridBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"> CornerRadius="{TemplateBinding CornerRadius}">
<Grid RowDefinitions="Auto,*,Auto,Auto" <Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto,*,Auto,Auto">
ColumnDefinitions="Auto,*,Auto">
<Grid.Resources> <Grid.Resources>
<ControlTemplate x:Key="TopLeftHeaderTemplate" <ControlTemplate x:Key="TopLeftHeaderTemplate"
TargetType="DataGridColumnHeader"> TargetType="DataGridColumnHeader">

5
src/Avalonia.Controls/Calendar/DateTimeHelper.cs

@ -68,10 +68,7 @@ namespace Avalonia.Controls
public static DateTime DiscardDayTime(DateTime d) public static DateTime DiscardDayTime(DateTime d)
{ {
int year = d.Year; return new DateTime(d.Year, d.Month, 1, 0, 0, 0);
int month = d.Month;
DateTime newD = new DateTime(year, month, 1, 0, 0, 0);
return newD;
} }
[return: NotNullIfNotNull("d")] [return: NotNullIfNotNull("d")]

2
src/Avalonia.Controls/ItemsControl.cs

@ -166,7 +166,7 @@ namespace Avalonia.Controls
if (Presenter is IChildIndexProvider innerProvider) if (Presenter is IChildIndexProvider innerProvider)
{ {
innerProvider.ChildIndexChanged += PresenterChildIndexChanged; innerProvider.ChildIndexChanged += PresenterChildIndexChanged;
_childIndexChanged?.Invoke(this, new ChildIndexChangedEventArgs()); _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.Empty);
} }
} }

2
src/Avalonia.Controls/Panel.cs

@ -147,7 +147,7 @@ namespace Avalonia.Controls
throw new NotSupportedException(); throw new NotSupportedException();
} }
_childIndexChanged?.Invoke(this, new ChildIndexChangedEventArgs()); _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.Empty);
InvalidateMeasureOnChildrenChanged(); InvalidateMeasureOnChildrenChanged();
} }

2
src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs

@ -158,7 +158,7 @@ namespace Avalonia.Controls.Presenters
{ {
ItemsChanged(e); ItemsChanged(e);
_childIndexChanged?.Invoke(this, new ChildIndexChangedEventArgs()); _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.Empty);
} }
} }

Loading…
Cancel
Save