From fc0ce75e4a1b371f7594d38353db3b82ed04542a Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Thu, 19 Dec 2019 00:12:14 +0200 Subject: [PATCH 01/25] add failing test for Geometry Parse -> it should be expected result be PathGeometry (as in WPF) --- .../Media/PathMarkupParserTests.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs index e1475dce80..ba5bcd7953 100644 --- a/tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs @@ -161,6 +161,13 @@ namespace Avalonia.Visuals.UnitTests.Media } } + [Fact] + public void Geometry_Parse_Should_Create_PathGeometry() + { + var target = Geometry.Parse("M0 0L10 10z"); + Assert.IsType(target); + } + [Theory] [InlineData("M5.5.5 5.5.5 5.5.5")] [InlineData("F1M9.0771,11C9.1161,10.701,9.1801,10.352,9.3031,10L9.0001,10 9.0001,6.166 3.0001,9.767 3.0001,10 " From 599e36860ab6abb3e372dfbcc19fcec7127ba677 Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Thu, 19 Dec 2019 00:14:08 +0200 Subject: [PATCH 02/25] add failing tests for PathGeometry.ToString() --- .../Media/PathMarkupParserTests.cs | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs index ba5bcd7953..6cae79de70 100644 --- a/tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs @@ -228,6 +228,48 @@ namespace Avalonia.Visuals.UnitTests.Media context.Verify(v => v.EndFigure(It.IsAny()), Times.AtLeastOnce()); } + [Theory] + [InlineData("M 5.5, 5 L 5.5, 5 L 5.5, 5")] + [InlineData("F1 M 9.0771, 11 C 9.1161, 10.701 9.1801, 10.352 9.3031, 10 L 9.0001, 10 L 9.0001, 6.166 L 3.0001, 9.767 L 3.0001, 10 " + + "L 9.99999999997669E-05, 10 L 9.99999999997669E-05, 0 L 3.0001, 0 L 3.0001, 0.234 L 9.0001, 3.834 L 9.0001, 0 " + + "L 12.0001, 0 L 12.0001, 8.062 C 12.1861, 8.043 12.3821, 8.031 12.5941, 8.031 C 15.3481, 8.031 15.7961, 9.826 " + + "15.9201, 11 L 16.0001, 16 L 9.0001, 16 L 9.0001, 12.562 L 9.0001, 11Z")] + [InlineData("F1 M 24, 14 A 2, 2 0 1 1 20, 14 A 2, 2 0 1 1 24, 14Z")] + [InlineData("M 0, 0 L 10, 10Z")] + [InlineData("M 50, 50 L 100, 100 L 150, 50")] + [InlineData("M 50, 50 L -10, -10 L 10, 50")] + [InlineData("M 50, 50 L 100, 100 L 150, 50Z M 50, 50 L 70, 70 L 120, 50Z")] + [InlineData("M 80, 200 A 100, 50 45 1 0 100, 50")] + [InlineData("F1 M 16, 12 C 16, 14.209 14.209, 16 12, 16 C 9.791, 16 8, 14.209 8, 12 C 8, 11.817 8.03, 11.644 8.054, 11.467 L 6.585, 10 " + + "L 4, 10 L 4, 6.414 L 2.5, 7.914 L 0, 5.414 L 0, 3.586 L 3.586, 0 L 4.414, 0 L 7.414, 3 L 7.586, 3 L 9, 1.586 L " + + "11.914, 4.5 L 10.414, 6 L 12.461, 8.046 C 14.45, 8.278 16, 9.949 16, 12")] + public void Parsed_Geometry_ToString_Should_Produce_Valid_Value(string pathData) + { + var target = PathGeometry.Parse(pathData); + + string output = target.ToString(); + + Assert.Equal(pathData, output); + } + + [Theory] + [InlineData("M5.5.5 5.5.5 5.5.5", "M 5.5, 0.5 L 5.5, 0.5 L 5.5, 0.5")] + [InlineData("F1 M24,14 A2,2,0,1,1,20,14 A2,2,0,1,1,24,14 z", "F1 M 24, 14 A 2, 2 0 1 1 20, 14 A 2, 2 0 1 1 24, 14Z")] + [InlineData("F1M16,12C16,14.209 14.209,16 12,16 9.791,16 8,14.209 8,12 8,11.817 8.03,11.644 8.054,11.467L6.585,10 4,10 " + + "4,6.414 2.5,7.914 0,5.414 0,3.586 3.586,0 4.414,0 7.414,3 7.586,3 9,1.586 11.914,4.5 10.414,6 " + + "12.461,8.046C14.45,8.278,16,9.949,16,12", + "F1 M 16, 12 C 16, 14.209 14.209, 16 12, 16 C 9.791, 16 8, 14.209 8, 12 C 8, 11.817 8.03, 11.644 8.054, 11.467 L 6.585, 10 " + + "L 4, 10 L 4, 6.414 L 2.5, 7.914 L 0, 5.414 L 0, 3.586 L 3.586, 0 L 4.414, 0 L 7.414, 3 L 7.586, 3 L 9, 1.586 L " + + "11.914, 4.5 L 10.414, 6 L 12.461, 8.046 C 14.45, 8.278 16, 9.949 16, 12")] + public void Parsed_Geometry_ToString_Should_Format_Value(string pathData, string formattedPathData) + { + var target = PathGeometry.Parse(pathData); + + string output = target.ToString(); + + Assert.Equal(formattedPathData, output); + } + [Theory] [InlineData("0 0")] [InlineData("j")] From 15700ea0421c868f9cd83d0ac5134be78cf1a082 Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Thu, 19 Dec 2019 00:17:49 +0200 Subject: [PATCH 03/25] fix Geometry.Parse create PathGeometry --- src/Avalonia.Visuals/Media/Geometry.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Visuals/Media/Geometry.cs b/src/Avalonia.Visuals/Media/Geometry.cs index f9bcea85af..507b5201a1 100644 --- a/src/Avalonia.Visuals/Media/Geometry.cs +++ b/src/Avalonia.Visuals/Media/Geometry.cs @@ -74,7 +74,7 @@ namespace Avalonia.Media /// /// The string. /// A . - public static Geometry Parse(string s) => StreamGeometry.Parse(s); + public static Geometry Parse(string s) => PathGeometry.Parse(s); /// /// Clones the geometry. From 9283fd404935d517f4320d603803d10c1a35d6e9 Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Thu, 19 Dec 2019 00:18:18 +0200 Subject: [PATCH 04/25] make PathGeometry.ToString work properly --- src/Avalonia.Visuals/Media/ArcSegment.cs | 5 +++++ src/Avalonia.Visuals/Media/BezierSegment .cs | 3 +++ src/Avalonia.Visuals/Media/LineSegment.cs | 3 +++ src/Avalonia.Visuals/Media/PathFigure.cs | 3 +++ src/Avalonia.Visuals/Media/PathGeometry.cs | 4 ++++ src/Avalonia.Visuals/Media/QuadraticBezierSegment .cs | 3 +++ 6 files changed, 21 insertions(+) diff --git a/src/Avalonia.Visuals/Media/ArcSegment.cs b/src/Avalonia.Visuals/Media/ArcSegment.cs index 0e9c4548a4..8502c09895 100644 --- a/src/Avalonia.Visuals/Media/ArcSegment.cs +++ b/src/Avalonia.Visuals/Media/ArcSegment.cs @@ -1,6 +1,8 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System.Globalization; + namespace Avalonia.Media { public sealed class ArcSegment : PathSegment @@ -99,5 +101,8 @@ namespace Avalonia.Media { ctx.ArcTo(Point, Size, RotationAngle, IsLargeArc, SweepDirection); } + + public override string ToString() + => $"A {Size} {RotationAngle.ToString(CultureInfo.InvariantCulture)} {(IsLargeArc ? 1 : 0)} {(int)SweepDirection} {Point}"; } } \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/BezierSegment .cs b/src/Avalonia.Visuals/Media/BezierSegment .cs index 8bea03bc23..ddb818c3ac 100644 --- a/src/Avalonia.Visuals/Media/BezierSegment .cs +++ b/src/Avalonia.Visuals/Media/BezierSegment .cs @@ -61,5 +61,8 @@ namespace Avalonia.Media { ctx.CubicBezierTo(Point1, Point2, Point3); } + + public override string ToString() + => $"C {Point1} {Point2} {Point3}"; } } \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/LineSegment.cs b/src/Avalonia.Visuals/Media/LineSegment.cs index d81f67d99f..81e53ff7c6 100644 --- a/src/Avalonia.Visuals/Media/LineSegment.cs +++ b/src/Avalonia.Visuals/Media/LineSegment.cs @@ -27,5 +27,8 @@ namespace Avalonia.Media { ctx.LineTo(Point); } + + public override string ToString() + => $"L {Point}"; } } \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/PathFigure.cs b/src/Avalonia.Visuals/Media/PathFigure.cs index 6a438a85ee..720fca8337 100644 --- a/src/Avalonia.Visuals/Media/PathFigure.cs +++ b/src/Avalonia.Visuals/Media/PathFigure.cs @@ -98,5 +98,8 @@ namespace Avalonia.Media } private PathSegments _segments; + + public override string ToString() + => $"M {StartPoint} {string.Join(" ", _segments)}{(IsClosed ? "Z" : "")}"; } } \ No newline at end of file diff --git a/src/Avalonia.Visuals/Media/PathGeometry.cs b/src/Avalonia.Visuals/Media/PathGeometry.cs index 3a91c924d2..be7ffe57a7 100644 --- a/src/Avalonia.Visuals/Media/PathGeometry.cs +++ b/src/Avalonia.Visuals/Media/PathGeometry.cs @@ -112,5 +112,9 @@ namespace Avalonia.Media () => InvalidateGeometry()); _figuresPropertiesObserver = figures?.TrackItemPropertyChanged(_ => InvalidateGeometry()); } + + + public override string ToString() + => $"{(FillRule != FillRule.EvenOdd ? "F1 " : "")}{(string.Join(" ", Figures))}"; } } diff --git a/src/Avalonia.Visuals/Media/QuadraticBezierSegment .cs b/src/Avalonia.Visuals/Media/QuadraticBezierSegment .cs index 31c364edf4..f1a0ccaaa0 100644 --- a/src/Avalonia.Visuals/Media/QuadraticBezierSegment .cs +++ b/src/Avalonia.Visuals/Media/QuadraticBezierSegment .cs @@ -42,5 +42,8 @@ namespace Avalonia.Media { ctx.QuadraticBezierTo(Point1, Point2); } + + public override string ToString() + => $"Q {Point1} {Point2}"; } } \ No newline at end of file From 05672c67f7bcbe137fdf427a880ffe5309a2dd8c Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Fri, 24 Jan 2020 16:49:50 +0200 Subject: [PATCH 05/25] revert Geometry.Parse to call StreamGeometry.Parse --- src/Avalonia.Visuals/Media/Geometry.cs | 2 +- .../Media/PathMarkupParserTests.cs | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Avalonia.Visuals/Media/Geometry.cs b/src/Avalonia.Visuals/Media/Geometry.cs index 507b5201a1..f9bcea85af 100644 --- a/src/Avalonia.Visuals/Media/Geometry.cs +++ b/src/Avalonia.Visuals/Media/Geometry.cs @@ -74,7 +74,7 @@ namespace Avalonia.Media /// /// The string. /// A . - public static Geometry Parse(string s) => PathGeometry.Parse(s); + public static Geometry Parse(string s) => StreamGeometry.Parse(s); /// /// Clones the geometry. diff --git a/tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs index 6cae79de70..3e589ef3df 100644 --- a/tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs @@ -161,13 +161,6 @@ namespace Avalonia.Visuals.UnitTests.Media } } - [Fact] - public void Geometry_Parse_Should_Create_PathGeometry() - { - var target = Geometry.Parse("M0 0L10 10z"); - Assert.IsType(target); - } - [Theory] [InlineData("M5.5.5 5.5.5 5.5.5")] [InlineData("F1M9.0771,11C9.1161,10.701,9.1801,10.352,9.3031,10L9.0001,10 9.0001,6.166 3.0001,9.767 3.0001,10 " From 71d1f80d5a12e7dfdd20bbe987d141375f584ba1 Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Tue, 11 Feb 2020 23:37:37 +0100 Subject: [PATCH 06/25] Benchmark attaching styles. --- .../Styling/StyleAttachBenchmark.cs | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 tests/Avalonia.Benchmarks/Styling/StyleAttachBenchmark.cs diff --git a/tests/Avalonia.Benchmarks/Styling/StyleAttachBenchmark.cs b/tests/Avalonia.Benchmarks/Styling/StyleAttachBenchmark.cs new file mode 100644 index 0000000000..7bccd65c81 --- /dev/null +++ b/tests/Avalonia.Benchmarks/Styling/StyleAttachBenchmark.cs @@ -0,0 +1,47 @@ +using System; +using System.Runtime.CompilerServices; +using Avalonia.Controls; +using Avalonia.UnitTests; +using BenchmarkDotNet.Attributes; + +namespace Avalonia.Benchmarks.Styling +{ + [MemoryDiagnoser] + public class StyleAttachBenchmark : IDisposable + { + private readonly IDisposable _app; + private readonly TestRoot _root; + private readonly TextBox _control; + + public StyleAttachBenchmark() + { + _app = UnitTestApplication.Start( + TestServices.StyledWindow.With( + renderInterface: new NullRenderingPlatform(), + threadingInterface: new NullThreadingPlatform())); + + _root = new TestRoot(true, null) + { + Renderer = new NullRenderer(), + }; + + _control = new TextBox(); + } + + [Benchmark] + [MethodImpl(MethodImplOptions.NoInlining)] + public void AttachTextBoxStyles() + { + var styles = UnitTestApplication.Current.Styles; + + styles.Attach(_control, UnitTestApplication.Current); + + styles.Detach(); + } + + public void Dispose() + { + _app.Dispose(); + } + } +} From 2b6a2f4a9bc790e9deaf5832c37ea22312bef419 Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Tue, 11 Feb 2020 23:46:27 +0100 Subject: [PATCH 07/25] Optimize memory allocations when attaching styles. --- src/Avalonia.Styling/Styling/Setter.cs | 4 +-- src/Avalonia.Styling/Styling/Style.cs | 35 ++++++++++++++++++-------- src/Avalonia.Styling/Styling/Styles.cs | 4 ++- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/Avalonia.Styling/Styling/Setter.cs b/src/Avalonia.Styling/Styling/Setter.cs index 9244232ff5..b880ecb01c 100644 --- a/src/Avalonia.Styling/Styling/Setter.cs +++ b/src/Avalonia.Styling/Styling/Setter.cs @@ -78,8 +78,6 @@ namespace Avalonia.Styling { Contract.Requires(control != null); - var description = style?.ToString(); - if (Property == null) { throw new InvalidOperationException("Setter.Property must be set."); @@ -107,6 +105,8 @@ namespace Avalonia.Styling } else { + var description = style?.ToString(); + var activated = new ActivatedValue(activator, value, description); return control.Bind(Property, activated, BindingPriority.StyleTrigger); } diff --git a/src/Avalonia.Styling/Styling/Style.cs b/src/Avalonia.Styling/Styling/Style.cs index 99ee8d8563..22db7adfe4 100644 --- a/src/Avalonia.Styling/Styling/Style.cs +++ b/src/Avalonia.Styling/Styling/Style.cs @@ -116,13 +116,21 @@ namespace Avalonia.Styling if (match.IsMatch) { var controlSubscriptions = GetSubscriptions(control); - - var subs = new CompositeDisposable(Setters.Count + Animations.Count); - if (control is Animatable animatable) + var animatable = control as Animatable; + + var setters = Setters; + var settersCount = setters.Count; + var animations = Animations; + var animationsCount = animations.Count; + + var subs = new CompositeDisposable(settersCount + (animatable != null ? animationsCount : 0) + 1); + + if (animatable != null) { - foreach (var animation in Animations) + for (var i = 0; i < animationsCount; i++) { + var animation = animations[i]; var obsMatch = match.Activator; if (match.Result == SelectorMatchResult.AlwaysThisType || @@ -133,17 +141,19 @@ namespace Avalonia.Styling var sub = animation.Apply(animatable, null, obsMatch); subs.Add(sub); - } + } } - foreach (var setter in Setters) + for (var i = 0; i < settersCount; i++) { + var setter = setters[i]; var sub = setter.Apply(this, control, match.Activator); subs.Add(sub); } + subs.Add(Disposable.Create((subs, Subscriptions) , state => state.Subscriptions.Remove(state.subs))); + controlSubscriptions.Add(subs); - controlSubscriptions.Add(Disposable.Create(() => Subscriptions.Remove(subs))); Subscriptions.Add(subs); } @@ -151,18 +161,23 @@ namespace Avalonia.Styling } else if (control == container) { + var setters = Setters; + var settersCount = setters.Count; + var controlSubscriptions = GetSubscriptions(control); - var subs = new CompositeDisposable(Setters.Count); + var subs = new CompositeDisposable(settersCount + 1); - foreach (var setter in Setters) + for (var i = 0; i < settersCount; i++) { + var setter = setters[i]; var sub = setter.Apply(this, control, null); subs.Add(sub); } + subs.Add(Disposable.Create((subs, Subscriptions), state => state.Subscriptions.Remove(state.subs))); + controlSubscriptions.Add(subs); - controlSubscriptions.Add(Disposable.Create(() => Subscriptions.Remove(subs))); Subscriptions.Add(subs); return true; } diff --git a/src/Avalonia.Styling/Styling/Styles.cs b/src/Avalonia.Styling/Styling/Styles.cs index 0226288998..fd38c39650 100644 --- a/src/Avalonia.Styling/Styling/Styles.cs +++ b/src/Avalonia.Styling/Styling/Styles.cs @@ -239,8 +239,10 @@ namespace Avalonia.Styling /// public bool Remove(IStyle item) => _styles.Remove(item); + public AvaloniaList.Enumerator GetEnumerator() => _styles.GetEnumerator(); + /// - public IEnumerator GetEnumerator() => _styles.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => _styles.GetEnumerator(); /// IEnumerator IEnumerable.GetEnumerator() => _styles.GetEnumerator(); From c91559548e8e21ad7c90718e465dace3648c9c2f Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Wed, 12 Feb 2020 00:02:32 +0100 Subject: [PATCH 08/25] Remove LINQ from Visual and StyledElement attach/detach funtions. --- src/Avalonia.Styling/StyledElement.cs | 27 +++++++++++++++++++++------ src/Avalonia.Visuals/Visual.cs | 26 ++++++++++++++++++++------ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/Avalonia.Styling/StyledElement.cs b/src/Avalonia.Styling/StyledElement.cs index 13cfa905d4..f351e3a93d 100644 --- a/src/Avalonia.Styling/StyledElement.cs +++ b/src/Avalonia.Styling/StyledElement.cs @@ -650,9 +650,12 @@ namespace Avalonia element._dataContextUpdating = true; element.OnDataContextBeginUpdate(); - foreach (var child in element.LogicalChildren) + var logicalChildren = element.LogicalChildren; + var logicalChildrenCount = logicalChildren.Count; + + for (var i = 0; i < logicalChildrenCount; i++) { - if (child is StyledElement s && + if (element.LogicalChildren[i] is StyledElement s && s.InheritanceParent == element && !s.IsSet(DataContextProperty)) { @@ -723,9 +726,15 @@ namespace Avalonia AttachedToLogicalTree?.Invoke(this, e); } - foreach (var child in LogicalChildren.OfType()) + var logicalChildren = LogicalChildren; + var logicalChildrenCount = logicalChildren.Count; + + for (var i = 0; i < logicalChildrenCount; i++) { - child.OnAttachedToLogicalTreeCore(e); + if (logicalChildren[i] is StyledElement child) + { + child.OnAttachedToLogicalTreeCore(e); + } } } @@ -738,9 +747,15 @@ namespace Avalonia OnDetachedFromLogicalTree(e); DetachedFromLogicalTree?.Invoke(this, e); - foreach (var child in LogicalChildren.OfType()) + var logicalChildren = LogicalChildren; + var logicalChildrenCount = logicalChildren.Count; + + for (var i = 0; i < logicalChildrenCount; i++) { - child.OnDetachedFromLogicalTreeCore(e); + if (logicalChildren[i] is StyledElement child) + { + child.OnDetachedFromLogicalTreeCore(e); + } } #if DEBUG diff --git a/src/Avalonia.Visuals/Visual.cs b/src/Avalonia.Visuals/Visual.cs index ef7a254f86..bd2ab6e614 100644 --- a/src/Avalonia.Visuals/Visual.cs +++ b/src/Avalonia.Visuals/Visual.cs @@ -386,11 +386,18 @@ namespace Avalonia AttachedToVisualTree?.Invoke(this, e); InvalidateVisual(); - if (VisualChildren != null) + var visualChildren = VisualChildren; + + if (visualChildren != null) { - foreach (Visual child in VisualChildren.OfType()) + var visualChildrenCount = visualChildren.Count; + + for (var i = 0; i < visualChildrenCount; i++) { - child.OnAttachedToVisualTreeCore(e); + if (visualChildren[i] is Visual child) + { + child.OnAttachedToVisualTreeCore(e); + } } } } @@ -415,11 +422,18 @@ namespace Avalonia DetachedFromVisualTree?.Invoke(this, e); e.Root?.Renderer?.AddDirty(this); - if (VisualChildren != null) + var visualChildren = VisualChildren; + + if (visualChildren != null) { - foreach (Visual child in VisualChildren.OfType()) + var visualChildrenCount = visualChildren.Count; + + for (var i = 0; i < visualChildrenCount; i++) { - child.OnDetachedFromVisualTreeCore(e); + if (visualChildren[i] is Visual child) + { + child.OnDetachedFromVisualTreeCore(e); + } } } } From 8b0e291f41529fe7f147709fcbad38aedfc78130 Mon Sep 17 00:00:00 2001 From: Symbai <14368203+Symbai@users.noreply.github.com> Date: Thu, 13 Feb 2020 14:52:09 +0100 Subject: [PATCH 09/25] Update Default.xaml --- src/Avalonia.Controls.DataGrid/Themes/Default.xaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.Controls.DataGrid/Themes/Default.xaml b/src/Avalonia.Controls.DataGrid/Themes/Default.xaml index 0e039f01cb..17e7ecba43 100644 --- a/src/Avalonia.Controls.DataGrid/Themes/Default.xaml +++ b/src/Avalonia.Controls.DataGrid/Themes/Default.xaml @@ -202,7 +202,7 @@ @@ -215,11 +215,11 @@ - + - - + + Date: Fri, 14 Feb 2020 14:07:35 +0100 Subject: [PATCH 10/25] change selected row background brush --- src/Avalonia.Controls.DataGrid/Themes/Default.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Controls.DataGrid/Themes/Default.xaml b/src/Avalonia.Controls.DataGrid/Themes/Default.xaml index 17e7ecba43..4cbe9d27f2 100644 --- a/src/Avalonia.Controls.DataGrid/Themes/Default.xaml +++ b/src/Avalonia.Controls.DataGrid/Themes/Default.xaml @@ -113,7 +113,7 @@