Browse Source

Merge branch 'master' into default-members

robloo 2 years ago
parent
commit
abb7649824
100 changed files with 261 additions and 211 deletions
  1. 13 0
      .editorconfig
  2. 12 3
      packages/Avalonia/AvaloniaBuildTasks.targets
  3. 22 3
      samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml.cs
  4. 1 1
      samples/ControlCatalog/Pages/CompositionPage.axaml.cs
  5. 1 1
      samples/ControlCatalog/Pages/ImagePage.xaml.cs
  6. 1 1
      samples/ControlCatalog/Pages/OpenGlPage.xaml.cs
  7. 2 1
      samples/ControlCatalog/Pages/ScreenPage.cs
  8. 1 1
      samples/ControlCatalog/Pages/TabControlPage.xaml.cs
  9. 3 0
      samples/Directory.Build.props
  10. 1 1
      src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs
  11. 1 1
      src/Android/Avalonia.Android/Platform/Storage/AndroidStorageItem.cs
  12. 1 1
      src/Avalonia.Base/Animation/Animators/GradientBrushAnimator.cs
  13. 1 1
      src/Avalonia.Base/Animation/CrossFade.cs
  14. 1 1
      src/Avalonia.Base/Animation/KeySpline.cs
  15. 2 2
      src/Avalonia.Base/Controls/Classes.cs
  16. 1 1
      src/Avalonia.Base/CornerRadius.cs
  17. 1 1
      src/Avalonia.Base/Data/Core/ExpressionNode.cs
  18. 2 2
      src/Avalonia.Base/Data/Core/Parsers/ExpressionVisitorNodeBuilder.cs
  19. 1 1
      src/Avalonia.Base/Data/Core/Plugins/DataAnnotationsValidationPlugin.cs
  20. 1 1
      src/Avalonia.Base/Data/Core/Plugins/IndeiValidationPlugin.cs
  21. 1 1
      src/Avalonia.Base/Data/Core/Plugins/TaskStreamPlugin.cs
  22. 10 8
      src/Avalonia.Base/Input/AccessKeyHandler.cs
  23. 2 2
      src/Avalonia.Base/Input/DragDropDevice.cs
  24. 3 2
      src/Avalonia.Base/Input/KeyGesture.cs
  25. 1 1
      src/Avalonia.Base/Input/KeyboardDevice.cs
  26. 3 6
      src/Avalonia.Base/Input/MouseDevice.cs
  27. 1 1
      src/Avalonia.Base/Input/PenDevice.cs
  28. 2 2
      src/Avalonia.Base/Input/Pointer.cs
  29. 1 1
      src/Avalonia.Base/Input/TouchDevice.cs
  30. 1 1
      src/Avalonia.Base/Layout/AttachedLayout.cs
  31. 2 2
      src/Avalonia.Base/Layout/StackLayout.cs
  32. 1 1
      src/Avalonia.Base/Layout/UniformGridLayout.cs
  33. 3 2
      src/Avalonia.Base/Media/ArcSegment.cs
  34. 4 2
      src/Avalonia.Base/Media/BezierSegment .cs
  35. 4 4
      src/Avalonia.Base/Media/BoxShadow.cs
  36. 1 1
      src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs
  37. 1 1
      src/Avalonia.Base/Media/Immutable/ImmutableTransform.cs
  38. 1 1
      src/Avalonia.Base/Media/Immutable/ImmutableVisualBrush.cs
  39. 4 2
      src/Avalonia.Base/Media/LineSegment.cs
  40. 1 1
      src/Avalonia.Base/Media/MatrixTransform.cs
  41. 1 1
      src/Avalonia.Base/Media/PathFigure.cs
  42. 1 1
      src/Avalonia.Base/Media/PathGeometry.cs
  43. 6 6
      src/Avalonia.Base/Media/PathMarkupParser.cs
  44. 4 2
      src/Avalonia.Base/Media/QuadraticBezierSegment .cs
  45. 1 1
      src/Avalonia.Base/Media/RotateTransform.cs
  46. 1 1
      src/Avalonia.Base/Media/ScaleTransform.cs
  47. 1 1
      src/Avalonia.Base/Media/SkewTransform.cs
  48. 1 1
      src/Avalonia.Base/Media/Transform.cs
  49. 1 1
      src/Avalonia.Base/Media/TranslateTransform.cs
  50. 2 2
      src/Avalonia.Base/Platform/AssetLoader.cs
  51. 1 1
      src/Avalonia.Base/RelativePoint.cs
  52. 6 6
      src/Avalonia.Base/Rendering/Composition/Animations/KeyFrameAnimationInstance.cs
  53. 1 1
      src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
  54. 2 2
      src/Avalonia.Base/Rendering/Composition/CompositionTarget.cs
  55. 1 1
      src/Avalonia.Base/Rendering/Composition/Drawing/CompositionDrawingContext.cs
  56. 1 1
      src/Avalonia.Base/Rendering/Composition/Server/FpsCounter.cs
  57. 1 1
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs
  58. 2 2
      src/Avalonia.Base/Rendering/DeferredRenderer.cs
  59. 1 1
      src/Avalonia.Base/Rendering/RendererBase.cs
  60. 1 1
      src/Avalonia.Base/Rendering/SceneGraph/SceneBuilder.cs
  61. 1 1
      src/Avalonia.Base/Rendering/SceneGraph/VisualNode.cs
  62. 1 1
      src/Avalonia.Base/Styling/Activators/IStyleActivator.cs
  63. 1 1
      src/Avalonia.Base/Thickness.cs
  64. 1 1
      src/Avalonia.Base/VisualTree/TransformedBounds.cs
  65. 1 1
      src/Avalonia.Build.Tasks/Extensions.cs
  66. 1 1
      src/Avalonia.Build.Tasks/GenerateAvaloniaResourcesTask.cs
  67. 1 1
      src/Avalonia.Controls.ColorPicker/ColorSlider/ColorSlider.cs
  68. 1 1
      src/Avalonia.Controls.ColorPicker/ColorSpectrum/ColorSpectrum.cs
  69. 1 1
      src/Avalonia.Controls.DataGrid/DataGridTemplateColumn.cs
  70. 1 1
      src/Avalonia.Controls/Automation/Peers/ComboBoxAutomationPeer.cs
  71. 1 1
      src/Avalonia.Controls/Calendar/CalendarBlackoutDatesCollection.cs
  72. 1 2
      src/Avalonia.Controls/Calendar/SelectedDatesCollection.cs
  73. 1 1
      src/Avalonia.Controls/DateTimePickers/DateTimePickerPanel.cs
  74. 4 4
      src/Avalonia.Controls/Grid.cs
  75. 1 1
      src/Avalonia.Controls/GridSplitter.cs
  76. 6 5
      src/Avalonia.Controls/MenuItemAccessKeyHandler.cs
  77. 2 2
      src/Avalonia.Controls/Platform/InProcessDragSource.cs
  78. 2 4
      src/Avalonia.Controls/Primitives/Popup.cs
  79. 1 1
      src/Avalonia.Controls/Repeater/RecyclingElementFactory.cs
  80. 1 1
      src/Avalonia.Controls/Selection/IndexRange.cs
  81. 2 2
      src/Avalonia.Controls/Selection/SelectionNodeBase.cs
  82. 13 7
      src/Avalonia.Controls/Slider.cs
  83. 2 5
      src/Avalonia.Controls/SplitView.cs
  84. 1 1
      src/Avalonia.Controls/TextBox.cs
  85. 1 1
      src/Avalonia.Controls/TopLevel.cs
  86. 0 1
      src/Avalonia.Controls/UserControl.cs
  87. 1 1
      src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs
  88. 1 1
      src/Avalonia.DesignerSupport/Remote/HtmlTransport/SimpleWebSocketHttpServer.cs
  89. 1 1
      src/Avalonia.Diagnostics/Diagnostics/Screenshots/FilePickerHandler.cs
  90. 7 7
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs
  91. 4 4
      src/Avalonia.Dialogs/ManagedStorageProvider.cs
  92. 1 1
      src/Avalonia.FreeDesktop/DBusTrayIconImpl.cs
  93. 4 4
      src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs
  94. 1 1
      src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
  95. 1 2
      src/Avalonia.Native/IAvnMenu.cs
  96. 2 2
      src/Avalonia.OpenGL/Controls/OpenGlControlBase.cs
  97. 1 1
      src/Avalonia.Remote.Protocol/MetsysBson.cs
  98. 8 8
      src/Avalonia.Themes.Fluent/Controls/CalendarButton.xaml
  99. 19 20
      src/Avalonia.Themes.Fluent/Controls/Slider.xaml
  100. 9 9
      src/Avalonia.Themes.Simple/Controls/CalendarButton.xaml

+ 13 - 0
.editorconfig

@@ -137,14 +137,27 @@ space_within_single_line_array_initializer_braces = true
 #Net Analyzer
 dotnet_analyzer_diagnostic.category-Performance.severity = none #error - Uncomment when all violations are fixed.
 
+# CA1304: Specify CultureInfo
+dotnet_diagnostic.CA1304.severity = warning
 # CA1802: Use literals where appropriate
 dotnet_diagnostic.CA1802.severity = warning
 # CA1820: Test for empty strings using string length
 dotnet_diagnostic.CA1820.severity = warning
 # CA1821: Remove empty finalizers
 dotnet_diagnostic.CA1821.severity = warning
+# CA1822: Mark members as static
+dotnet_diagnostic.CA1822.severity = suggestion
+dotnet_code_quality.CA1822.api_surface = private, internal
 # CA1825: Avoid zero-length array allocations
 dotnet_diagnostic.CA1825.severity = warning
+# CA1826: Use property instead of Linq Enumerable method
+dotnet_diagnostic.CA1826.severity = suggestion
+# CA1827: Do not use Count/LongCount when Any can be used
+dotnet_diagnostic.CA1827.severity = warning
+# CA1828: Do not use CountAsync/LongCountAsync when AnyAsync can be used
+dotnet_diagnostic.CA1828.severity = warning
+# CA1829: Use Length/Count property instead of Enumerable.Count method
+dotnet_diagnostic.CA1829.severity = warning
 #CA1847: Use string.Contains(char) instead of string.Contains(string) with single characters
 dotnet_diagnostic.CA1847.severity = warning
 

+ 12 - 3
packages/Avalonia/AvaloniaBuildTasks.targets

@@ -30,7 +30,9 @@
              />
 
 
-  <Target Name="AddAvaloniaResources" BeforeTargets="ResolveReferences">
+  <Target Name="AddAvaloniaResources" 
+          BeforeTargets="ResolveReferences"
+          Condition="('@(AvaloniaResource->Count())' &gt; 0) or ('@(AvaloniaXaml->Count())' &gt; 0)">
     <PropertyGroup>
       <AvaloniaResourcesTemporaryFilePath Condition="'$(AvaloniaResourcesTemporaryFilePath)' == ''">$(IntermediateOutputPath)/Avalonia/resources</AvaloniaResourcesTemporaryFilePath>
     </PropertyGroup>
@@ -62,7 +64,9 @@
           BeforeTargets="CoreCompile;CoreResGen"
           Inputs="@(AvaloniaResource);@(AvaloniaXaml);@(CustomAdditionalGenerateAvaloniaResourcesInputs);$(MSBuildAllProjects)"
           Outputs="$(AvaloniaResourcesTemporaryFilePath)"
-	  DependsOnTargets="$(BuildAvaloniaResourcesDependsOn)">
+          DependsOnTargets="$(BuildAvaloniaResourcesDependsOn)"
+          Condition="('@(AvaloniaResource->Count())' &gt; 0) or ('@(AvaloniaXaml->Count())' &gt; 0)"
+          >
     <ItemGroup>
         <AvaloniaResource Include="@(AvaloniaXaml)"/>
     </ItemGroup>
@@ -81,7 +85,12 @@
   <Target
     Name="CompileAvaloniaXaml"
     AfterTargets="AfterCompile"
-    Condition="Exists('@(IntermediateAssembly)') And $(DesignTimeBuild) != true And $(EnableAvaloniaXamlCompilation) != false"
+    Condition="
+      (('@(AvaloniaResource->Count())' &gt; 0) 
+          or ('@(AvaloniaXaml->Count())' &gt; 0))
+      and Exists('@(IntermediateAssembly)') 
+      And $(DesignTimeBuild) != true 
+      And $(EnableAvaloniaXamlCompilation) != false"
     >
     <PropertyGroup>
       <AvaloniaXamlReferencesTemporaryFilePath Condition="'$(AvaloniaXamlReferencesTemporaryFilePath)' == ''">$(IntermediateOutputPath)/Avalonia/references</AvaloniaXamlReferencesTemporaryFilePath>

+ 22 - 3
samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml.cs

@@ -14,7 +14,26 @@ namespace ControlCatalog.Pages
 {
     public class AutoCompleteBoxPage : UserControl
     {
-        private StateData[] BuildAllStates()
+        public class StateData
+        {
+            public string Name { get; private set; }
+            public string Abbreviation { get; private set; }
+            public string Capital { get; private set; }
+
+            public StateData(string name, string abbreviatoin, string capital)
+            {
+                Name = name;
+                Abbreviation = abbreviatoin;
+                Capital = capital;
+            }
+
+            public override string ToString()
+            {
+                return Name;
+            }
+        }
+
+        private static StateData[] BuildAllStates()
         {
             return new StateData[]
             {
@@ -72,7 +91,7 @@ namespace ControlCatalog.Pages
         }
         public StateData[] States { get; private set; }
         
-        private LinkedList<string>[] BuildAllSentences()
+        private static LinkedList<string>[] BuildAllSentences()
         {
             return new string[]
             {
@@ -124,7 +143,7 @@ namespace ControlCatalog.Pages
                     .OfType<AutoCompleteBox>();
         }
 
-        private bool StringContains(string str, string? query)
+        private static bool StringContains(string str, string? query)
         {
             if (query == null) return false;
             return str.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0;

+ 1 - 1
samples/ControlCatalog/Pages/CompositionPage.axaml.cs

@@ -25,7 +25,7 @@ public partial class CompositionPage : UserControl
         this.Get<ItemsControl>("Items").Items = CreateColorItems();
     }
 
-    private List<CompositionPageColorItem> CreateColorItems()
+    private static List<CompositionPageColorItem> CreateColorItems()
     {
         var list = new List<CompositionPageColorItem>();
 

+ 1 - 1
samples/ControlCatalog/Pages/ImagePage.xaml.cs

@@ -58,7 +58,7 @@ namespace ControlCatalog.Pages
             }
         }
 
-        private PixelRect GetCropRect(int index)
+        private static PixelRect GetCropRect(int index)
         {
             var bitmapWidth = 640;
             var bitmapHeight = 426;

+ 1 - 1
samples/ControlCatalog/Pages/OpenGlPage.xaml.cs

@@ -247,7 +247,7 @@ namespace ControlCatalog.Pages
 
         }
 
-        private void CheckError(GlInterface gl)
+        private static void CheckError(GlInterface gl)
         {
             int err;
             while ((err = gl.GetError()) != GL_NO_ERROR)

+ 2 - 1
samples/ControlCatalog/Pages/ScreenPage.cs

@@ -66,6 +66,7 @@ namespace ControlCatalog.Pages
                     context.DrawText(formattedText, boundsRect.Position.WithY(boundsRect.Size.Height + 40));
 
                     formattedText = CreateFormattedText($"IsPrimary: {screen.IsPrimary}");
+
                     context.DrawText(formattedText, boundsRect.Position.WithY(boundsRect.Size.Height + 60));
 
                     formattedText =
@@ -77,7 +78,7 @@ namespace ControlCatalog.Pages
             context.DrawRectangle(p, new Rect(w.Position.X / 10f + Math.Abs(_leftMost), w.Position.Y / 10f, w.Bounds.Width / 10, w.Bounds.Height / 10));
         }
 
-        private FormattedText CreateFormattedText(string textToFormat)
+        private static FormattedText CreateFormattedText(string textToFormat)
         {
             return new FormattedText(textToFormat, CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
                 Typeface.Default, 12, Brushes.Green);

+ 1 - 1
samples/ControlCatalog/Pages/TabControlPage.xaml.cs

@@ -49,7 +49,7 @@ namespace ControlCatalog.Pages
             AvaloniaXamlLoader.Load(this);
         }
 
-        private IBitmap LoadBitmap(string uri)
+        private static IBitmap LoadBitmap(string uri)
         {
             var assets = AvaloniaLocator.Current!.GetService<IAssetLoader>()!;
             return new Bitmap(assets.Open(new Uri(uri)));

+ 3 - 0
samples/Directory.Build.props

@@ -4,4 +4,7 @@
       <AvaloniaPreviewerNetCoreToolPath>$(MSBuildThisFileDirectory)..\src\tools\Avalonia.Designer.HostApp\bin\Debug\netcoreapp2.0\Avalonia.Designer.HostApp.dll</AvaloniaPreviewerNetCoreToolPath>
   </PropertyGroup>
   <Import Project="..\build\SharedVersion.props" />
+  <PropertyGroup>
+    <EnableNETAnalyzers>false</EnableNETAnalyzers>
+  </PropertyGroup>  
 </Project>

+ 1 - 1
src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs

@@ -30,7 +30,7 @@ namespace Avalonia.Android.Platform.Specific.Helpers
             return DispatchKeyEventInternal(e, out callBase);
         }
 
-        string UnicodeTextInput(KeyEvent keyEvent)
+        static string UnicodeTextInput(KeyEvent keyEvent)
         {
             return keyEvent.Action == KeyEventActions.Multiple
                 && keyEvent.RepeatCount == 0

+ 1 - 1
src/Android/Avalonia.Android/Platform/Storage/AndroidStorageItem.cs

@@ -178,7 +178,7 @@ internal sealed class AndroidStorageFile : AndroidStorageItem, IStorageBookmarkF
         return false;
     }
 
-    private Stream? GetVirtualFileStream(Context context, AndroidUri uri, bool isOutput)
+    private static Stream? GetVirtualFileStream(Context context, AndroidUri uri, bool isOutput)
     {
         var mimeTypes = context.ContentResolver?.GetStreamTypes(uri, FilePickerFileTypes.All.MimeTypes![0]);
         if (mimeTypes?.Length >= 1)

+ 1 - 1
src/Avalonia.Base/Animation/Animators/GradientBrushAnimator.cs

@@ -72,7 +72,7 @@ namespace Avalonia.Animation.Animators
             return control.Bind((AvaloniaProperty<IBrush?>)Property, instance, BindingPriority.Animation);
         }
 
-        private IReadOnlyList<ImmutableGradientStop> InterpolateStops(double progress, IReadOnlyList<IGradientStop> oldValue, IReadOnlyList<IGradientStop> newValue)
+        private static IReadOnlyList<ImmutableGradientStop> InterpolateStops(double progress, IReadOnlyList<IGradientStop> oldValue, IReadOnlyList<IGradientStop> newValue)
         {
             var resultCount = Math.Max(oldValue.Count, newValue.Count);
             var stops = new ImmutableGradientStop[resultCount];

+ 1 - 1
src/Avalonia.Base/Animation/CrossFade.cs

@@ -10,7 +10,7 @@ using Avalonia.VisualTree;
 namespace Avalonia.Animation
 {
     /// <summary>
-    /// Defines a cross-fade animation between two <see cref="IVisual"/>s.
+    /// Defines a cross-fade animation between two <see cref="Visual"/>s.
     /// </summary>
     public class CrossFade : IPageTransition
     {

+ 1 - 1
src/Avalonia.Base/Animation/KeySpline.cs

@@ -196,7 +196,7 @@ namespace Avalonia.Animation
         /// </summary>
         /// <param name="value"></param>
         /// <returns></returns>
-        private bool IsValidXValue(double value)
+        private static bool IsValidXValue(double value)
         {
             return value >= 0.0 && value <= 1.0;
         }

+ 2 - 2
src/Avalonia.Base/Controls/Classes.cs

@@ -37,7 +37,7 @@ namespace Avalonia.Controls
         /// <param name="items">The initial items.</param>
         public Classes(params string[] items)
             : base(items)
-        {            
+        {
         }
 
         /// <summary>
@@ -320,7 +320,7 @@ namespace Avalonia.Controls
                 listener.Changed();
         }
 
-        private void ThrowIfPseudoclass(string name, string operation)
+        private static void ThrowIfPseudoclass(string name, string operation)
         {
             if (name.StartsWith(":"))
             {

+ 1 - 1
src/Avalonia.Base/CornerRadius.cs

@@ -103,7 +103,7 @@ namespace Avalonia
 
         public override string ToString()
         {
-            return $"{TopLeft},{TopRight},{BottomRight},{BottomLeft}";
+            return FormattableString.Invariant($"{TopLeft},{TopRight},{BottomRight},{BottomLeft}");
         }
 
         public static CornerRadius Parse(string s)

+ 1 - 1
src/Avalonia.Base/Data/Core/ExpressionNode.cs

@@ -159,7 +159,7 @@ namespace Avalonia.Data.Core
             _listening = false;
         }
 
-        private BindingNotification TargetNullNotification()
+        private static BindingNotification TargetNullNotification()
         {
             return new BindingNotification(
                 new MarkupBindingChainException("Null value"),

+ 2 - 2
src/Avalonia.Base/Data/Core/Parsers/ExpressionVisitorNodeBuilder.cs

@@ -81,7 +81,7 @@ namespace Avalonia.Data.Core.Parsers
             return node;
         }
 
-        private T GetArgumentExpressionValue<T>(Expression expr)
+        private static T GetArgumentExpressionValue<T>(Expression expr)
         {
             try
             {
@@ -193,7 +193,7 @@ namespace Avalonia.Data.Core.Parsers
             throw new ExpressionParseException(0, $"Invalid method call in binding expression: '{node.Method.DeclaringType!.AssemblyQualifiedName}.{node.Method.Name}'.");
         }
 
-        private PropertyInfo? TryGetPropertyFromMethod(MethodInfo method)
+        private static PropertyInfo? TryGetPropertyFromMethod(MethodInfo method)
         {
             var type = method.DeclaringType;
             return type?.GetRuntimeProperties().FirstOrDefault(prop => prop.GetMethod == method);

+ 1 - 1
src/Avalonia.Base/Data/Core/Plugins/DataAnnotationsValidationPlugin.cs

@@ -63,7 +63,7 @@ namespace Avalonia.Data.Core.Plugins
                 }
             }
 
-            private Exception CreateException(IList<ValidationResult> errors)
+            private static Exception CreateException(IList<ValidationResult> errors)
             {
                 if (errors.Count == 1)
                 {

+ 1 - 1
src/Avalonia.Base/Data/Core/Plugins/IndeiValidationPlugin.cs

@@ -108,7 +108,7 @@ namespace Avalonia.Data.Core.Plugins
                 return target;
             }
 
-            private Exception GenerateException(IList<object> errors)
+            private static Exception GenerateException(IList<object> errors)
             {
                 if (errors.Count == 1)
                 {

+ 1 - 1
src/Avalonia.Base/Data/Core/Plugins/TaskStreamPlugin.cs

@@ -59,7 +59,7 @@ namespace Avalonia.Data.Core.Plugins
             return Observable.Empty<object?>();
         }
 
-        private IObservable<object?> HandleCompleted(Task task)
+        private static IObservable<object?> HandleCompleted(Task task)
         {
             var resultProperty = task.GetType().GetRuntimeProperty("Result");
             

+ 10 - 8
src/Avalonia.Base/Input/AccessKeyHandler.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Globalization;
 using System.Linq;
 using Avalonia.Interactivity;
 using Avalonia.VisualTree;
@@ -23,7 +24,7 @@ namespace Avalonia.Input
         /// <summary>
         /// The registered access keys.
         /// </summary>
-        private readonly List<Tuple<string, IInputElement>> _registered = new List<Tuple<string, IInputElement>>();
+        private readonly List<(string AccessKey, IInputElement Element)> _registered = new();
 
         /// <summary>
         /// The window to which the handler belongs.
@@ -108,12 +109,12 @@ namespace Avalonia.Input
         {
             var existing = _registered.FirstOrDefault(x => x.Item2 == element);
 
-            if (existing != null)
+            if (existing != default)
             {
                 _registered.Remove(existing);
             }
 
-            _registered.Add(Tuple.Create(accessKey.ToString().ToUpper(), element));
+            _registered.Add((accessKey.ToString().ToUpperInvariant(), element));
         }
 
         /// <summary>
@@ -143,7 +144,7 @@ namespace Avalonia.Input
                 {
                     // TODO: Use FocusScopes to store the current element and restore it when context menu is closed.
                     // Save currently focused input element.
-                    _restoreFocusElement = FocusManager.Instance?.Current;                    
+                    _restoreFocusElement = FocusManager.Instance?.Current;
 
                     // When Alt is pressed without a main menu, or with a closed main menu, show
                     // access key markers in the window (i.e. "_File").
@@ -180,10 +181,11 @@ namespace Avalonia.Input
             {
                 // If any other key is pressed with the Alt key held down, or the main menu is open,
                 // find all controls who have registered that access key.
-                var text = e.Key.ToString().ToUpper();
+                var text = e.Key.ToString();
                 var matches = _registered
-                    .Where(x => x.Item1 == text && ((Visual)x.Item2).IsEffectivelyVisible)
-                    .Select(x => x.Item2);
+                    .Where(x => string.Equals(x.AccessKey, text, StringComparison.OrdinalIgnoreCase)
+                        && x.Element.IsEffectivelyVisible)
+                    .Select(x => x.Element);
 
                 // If the menu is open, only match controls in the menu's visual tree.
                 if (menuIsOpen)
@@ -194,7 +196,7 @@ namespace Avalonia.Input
                 var match = matches.FirstOrDefault();
 
                 // If there was a match, raise the AccessKeyPressed event on it.
-                if (match != null)
+                if (match is not null)
                 {
                     match.RaiseEvent(new RoutedEventArgs(AccessKeyPressedEvent));
                     e.Handled = true;

+ 2 - 2
src/Avalonia.Base/Input/DragDropDevice.cs

@@ -11,7 +11,7 @@ namespace Avalonia.Input
         
         private Interactive? _lastTarget = null;
         
-        private Interactive? GetTarget(IInputRoot root, Point local)
+        private static Interactive? GetTarget(IInputRoot root, Point local)
         {
             var hit = root.InputHitTest(local) as Visual;
             var target = hit?.GetSelfAndVisualAncestors()?.OfType<Interactive>()?.FirstOrDefault();
@@ -20,7 +20,7 @@ namespace Avalonia.Input
             return null;
         }
         
-        private DragDropEffects RaiseDragEvent(Interactive? target, IInputRoot inputRoot, Point point, RoutedEvent<DragEventArgs> routedEvent, DragDropEffects operation, IDataObject data, KeyModifiers modifiers)
+        private static DragDropEffects RaiseDragEvent(Interactive? target, IInputRoot inputRoot, Point point, RoutedEvent<DragEventArgs> routedEvent, DragDropEffects operation, IDataObject data, KeyModifiers modifiers)
         {
             if (target == null)
                 return DragDropEffects.None;

+ 3 - 2
src/Avalonia.Base/Input/KeyGesture.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Globalization;
 using System.Text;
 using Avalonia.Utilities;
 
@@ -143,7 +144,7 @@ namespace Avalonia.Input
         // TODO: Move that to external key parser
         private static Key ParseKey(string key)
         {
-            if (s_keySynonyms.TryGetValue(key.ToLower(), out Key rv))
+            if (s_keySynonyms.TryGetValue(key.ToLower(CultureInfo.InvariantCulture), out Key rv))
                 return rv;
 
             return EnumHelper.Parse<Key>(key, true);
@@ -166,7 +167,7 @@ namespace Avalonia.Input
             return EnumHelper.Parse<KeyModifiers>(modifier.ToString(), true);
         }
 
-        private Key ResolveNumPadOperationKey(Key key)
+        private static Key ResolveNumPadOperationKey(Key key)
         {
             switch (key)
             {

+ 1 - 1
src/Avalonia.Base/Input/KeyboardDevice.cs

@@ -25,7 +25,7 @@ namespace Avalonia.Input
 
         public IInputElement? FocusedElement => _focusedElement;
 
-        private void ClearFocusWithinAncestors(IInputElement? element)
+        private static void ClearFocusWithinAncestors(IInputElement? element)
         {
             var el = element;
             

+ 3 - 6
src/Avalonia.Base/Input/MouseDevice.cs

@@ -1,12 +1,8 @@
 using System;
 using System.Collections.Generic;
-using System.Linq;
-using System.Reactive.Linq;
 using Avalonia.Input.Raw;
-using Avalonia.Interactivity;
 using Avalonia.Platform;
 using Avalonia.Utilities;
-using Avalonia.VisualTree;
 
 namespace Avalonia.Input
 {
@@ -34,7 +30,7 @@ namespace Avalonia.Input
                 ProcessRawEvent(margs);
         }
 
-        int ButtonCount(PointerPointProperties props)
+        static int ButtonCount(PointerPointProperties props)
         {
             var rv = 0;
             if (props.IsLeftButtonPressed)
@@ -106,9 +102,10 @@ namespace Avalonia.Input
 
         private void LeaveWindow()
         {
+
         }
 
-        PointerPointProperties CreateProperties(RawPointerEventArgs args)
+        static PointerPointProperties CreateProperties(RawPointerEventArgs args)
         {
             return new PointerPointProperties(args.InputModifiers, args.Type.ToUpdateKind());
         }

+ 1 - 1
src/Avalonia.Base/Input/PenDevice.cs

@@ -99,7 +99,7 @@ namespace Avalonia.Input
             return false;
         }
 
-        private bool PenMove(Pointer pointer, ulong timestamp,
+        private static bool PenMove(Pointer pointer, ulong timestamp,
             IInputRoot root, Point p, PointerPointProperties properties,
             KeyModifiers inputModifiers, IInputElement? hitTest,
             Lazy<IReadOnlyList<RawPointerPoint>?>? intermediatePoints)

+ 2 - 2
src/Avalonia.Base/Input/Pointer.cs

@@ -19,7 +19,7 @@ namespace Avalonia.Input
 
         public int Id { get; }
 
-        IInputElement? FindCommonParent(IInputElement? control1, IInputElement? control2)
+        static IInputElement? FindCommonParent(IInputElement? control1, IInputElement? control2)
         {
             if (control1 is not Visual c1 || control2 is not Visual c2)
                 return null;
@@ -54,7 +54,7 @@ namespace Avalonia.Input
                 v3.DetachedFromVisualTree += OnCaptureDetached;
         }
 
-        IInputElement? GetNextCapture(Visual parent)
+        static IInputElement? GetNextCapture(Visual parent)
         {
             return parent as IInputElement ?? parent.FindAncestorOfType<IInputElement>();
         }

+ 1 - 1
src/Avalonia.Base/Input/TouchDevice.cs

@@ -21,7 +21,7 @@ namespace Avalonia.Input
         private Rect _lastClickRect;
         private ulong _lastClickTime;
 
-        RawInputModifiers GetModifiers(RawInputModifiers modifiers, bool isLeftButtonDown)
+        static RawInputModifiers GetModifiers(RawInputModifiers modifiers, bool isLeftButtonDown)
         {
             var rv = modifiers &= RawInputModifiers.KeyboardMask;
             if (isLeftButtonDown)

+ 1 - 1
src/Avalonia.Base/Layout/AttachedLayout.cs

@@ -184,7 +184,7 @@ namespace Avalonia.Layout
         /// </summary>
         protected void InvalidateArrange() => ArrangeInvalidated?.Invoke(this, EventArgs.Empty);
 
-        private VirtualizingLayoutContext GetVirtualizingLayoutContext(LayoutContext context)
+        private static VirtualizingLayoutContext GetVirtualizingLayoutContext(LayoutContext context)
         {
             if (context is VirtualizingLayoutContext virtualizingContext)
             {

+ 2 - 2
src/Avalonia.Base/Layout/StackLayout.cs

@@ -335,7 +335,7 @@ namespace Avalonia.Layout
             InvalidateLayout();
         }
 
-        private double GetAverageElementSize(
+        private static double GetAverageElementSize(
             Size availableSize,
             VirtualizingLayoutContext context,
             StackLayoutState stackLayoutState)
@@ -359,6 +359,6 @@ namespace Avalonia.Layout
 
         private void InvalidateLayout() => InvalidateMeasure();
 
-        private FlowLayoutAlgorithm GetFlowAlgorithm(VirtualizingLayoutContext context) => ((StackLayoutState)context.LayoutState!).FlowAlgorithm;
+        private static FlowLayoutAlgorithm GetFlowAlgorithm(VirtualizingLayoutContext context) => ((StackLayoutState)context.LayoutState!).FlowAlgorithm;
     }
 }

+ 1 - 1
src/Avalonia.Base/Layout/UniformGridLayout.cs

@@ -557,6 +557,6 @@ namespace Avalonia.Layout
 
         private void InvalidateLayout() => InvalidateMeasure();
 
-        private FlowLayoutAlgorithm GetFlowAlgorithm(VirtualizingLayoutContext context) => ((UniformGridLayoutState)context.LayoutState!).FlowAlgorithm;
+        private static FlowLayoutAlgorithm GetFlowAlgorithm(VirtualizingLayoutContext context) => ((UniformGridLayoutState)context.LayoutState!).FlowAlgorithm;
     }
 }

+ 3 - 2
src/Avalonia.Base/Media/ArcSegment.cs

@@ -1,3 +1,4 @@
+using System;
 using System.Globalization;
 
 namespace Avalonia.Media
@@ -100,6 +101,6 @@ namespace Avalonia.Media
         }
 
         public override string ToString()
-            => $"A {Size} {RotationAngle.ToString(CultureInfo.InvariantCulture)} {(IsLargeArc ? 1 : 0)} {(int)SweepDirection} {Point}";
+            => FormattableString.Invariant($"A {Size} {RotationAngle} {(IsLargeArc ? 1 : 0)} {(int)SweepDirection} {Point}");
     }
-}
+}

+ 4 - 2
src/Avalonia.Base/Media/BezierSegment .cs

@@ -1,3 +1,5 @@
+using System;
+
 namespace Avalonia.Media
 {
     public sealed class BezierSegment : PathSegment
@@ -60,6 +62,6 @@ namespace Avalonia.Media
         }
 
         public override string ToString()
-            => $"C {Point1} {Point2} {Point3}";
+            => FormattableString.Invariant($"C {Point1} {Point2} {Point3}");
     }
-}
+}

+ 4 - 4
src/Avalonia.Base/Media/BoxShadow.cs

@@ -101,22 +101,22 @@ namespace Avalonia.Media
 
             if (OffsetX != 0.0)
             {
-                sb.AppendFormat(" {0}", OffsetX.ToString());
+                sb.AppendFormat(" {0}", OffsetX.ToString(CultureInfo.InvariantCulture));
             }
 
             if (OffsetY != 0.0)
             {
-                sb.AppendFormat(" {0}", OffsetY.ToString());
+                sb.AppendFormat(" {0}", OffsetY.ToString(CultureInfo.InvariantCulture));
             }
             
             if (Blur != 0.0)
             {
-                sb.AppendFormat(" {0}", Blur.ToString());
+                sb.AppendFormat(" {0}", Blur.ToString(CultureInfo.InvariantCulture));
             }
 
             if (Spread != 0.0)
             {
-                sb.AppendFormat(" {0}", Spread.ToString());
+                sb.AppendFormat(" {0}", Spread.ToString(CultureInfo.InvariantCulture));
             }
 
             sb.AppendFormat(" {0}", Color.ToString());

+ 1 - 1
src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs

@@ -7,7 +7,7 @@ using Avalonia.VisualTree;
 namespace Avalonia.Media.Imaging
 {
     /// <summary>
-    /// A bitmap that holds the rendering of a <see cref="IVisual"/>.
+    /// A bitmap that holds the rendering of a <see cref="Visual"/>.
     /// </summary>
     public class RenderTargetBitmap : Bitmap, IDisposable, IRenderTarget
     {

+ 1 - 1
src/Avalonia.Base/Media/Immutable/ImmutableTransform.cs

@@ -3,7 +3,7 @@
 namespace Avalonia.Media.Immutable
 {
     /// <summary>
-    /// Represents a transform on an <see cref="IVisual"/>.
+    /// Represents a transform on an <see cref="Visual"/>.
     /// </summary>
     public class ImmutableTransform : ITransform
     {

+ 1 - 1
src/Avalonia.Base/Media/Immutable/ImmutableVisualBrush.cs

@@ -4,7 +4,7 @@ using Avalonia.VisualTree;
 namespace Avalonia.Media.Immutable
 {
     /// <summary>
-    /// Paints an area with an <see cref="IVisual"/>.
+    /// Paints an area with an <see cref="Visual"/>.
     /// </summary>
     internal class ImmutableVisualBrush : ImmutableTileBrush, IVisualBrush
     {

+ 4 - 2
src/Avalonia.Base/Media/LineSegment.cs

@@ -1,3 +1,5 @@
+using System;
+
 namespace Avalonia.Media
 {
     public sealed class LineSegment : PathSegment
@@ -26,6 +28,6 @@ namespace Avalonia.Media
         }
 
         public override string ToString()
-            => $"L {Point}";
+            => FormattableString.Invariant($"L {Point}");
     }
-}
+}

+ 1 - 1
src/Avalonia.Base/Media/MatrixTransform.cs

@@ -4,7 +4,7 @@ using Avalonia.VisualTree;
 namespace Avalonia.Media
 {
     /// <summary>
-    /// Transforms an <see cref="IVisual"/> according to a <see cref="Matrix"/>.
+    /// Transforms an <see cref="Visual"/> according to a <see cref="Matrix"/>.
     /// </summary>
     public class MatrixTransform : Transform
     {

+ 1 - 1
src/Avalonia.Base/Media/PathFigure.cs

@@ -126,7 +126,7 @@ namespace Avalonia.Media
         }
         
         public override string ToString()
-            => $"M {StartPoint} {string.Join(" ", _segments ?? Enumerable.Empty<PathSegment>())}{(IsClosed ? "Z" : "")}";
+            => FormattableString.Invariant($"M {StartPoint} {string.Join(" ", _segments ?? Enumerable.Empty<PathSegment>())}{(IsClosed ? "Z" : "")}");
 
         internal void ApplyTo(StreamGeometryContext ctx)
         {

+ 1 - 1
src/Avalonia.Base/Media/PathGeometry.cs

@@ -133,7 +133,7 @@ namespace Avalonia.Media
         public override string ToString()
         {
             var figuresString = _figures is not null ? string.Join(" ", _figures) : string.Empty;
-            return $"{(FillRule != FillRule.EvenOdd ? "F1 " : "")}{figuresString}";
+            return FormattableString.Invariant($"{(FillRule != FillRule.EvenOdd ? "F1 " : "")}{figuresString}");
         }
     }
 }

+ 6 - 6
src/Avalonia.Base/Media/PathMarkupParser.cs

@@ -527,7 +527,7 @@ namespace Avalonia.Media
             return span.Slice(i);
         }
 
-        private bool ReadBool(ref ReadOnlySpan<char> span)
+        private static bool ReadBool(ref ReadOnlySpan<char> span)
         {
             span = SkipWhitespace(span);
             
@@ -551,7 +551,7 @@ namespace Avalonia.Media
             }
         }
 
-        private double ReadDouble(ref ReadOnlySpan<char> span)
+        private static double ReadDouble(ref ReadOnlySpan<char> span)
         {
             if (!ReadArgument(ref span, out var doubleValue))
             {
@@ -561,7 +561,7 @@ namespace Avalonia.Media
             return double.Parse(doubleValue.ToString(), CultureInfo.InvariantCulture);
         }
 
-        private Size ReadSize(ref ReadOnlySpan<char> span)
+        private static Size ReadSize(ref ReadOnlySpan<char> span)
         {
             var width = ReadDouble(ref span);
             span = ReadSeparator(span);
@@ -569,7 +569,7 @@ namespace Avalonia.Media
             return new Size(width, height);
         }
 
-        private Point ReadPoint(ref ReadOnlySpan<char> span)
+        private static Point ReadPoint(ref ReadOnlySpan<char> span)
         {
             var x = ReadDouble(ref span);
             span = ReadSeparator(span);
@@ -577,7 +577,7 @@ namespace Avalonia.Media
             return new Point(x, y);
         }
 
-        private Point ReadRelativePoint(ref ReadOnlySpan<char> span, Point origin)
+        private static Point ReadRelativePoint(ref ReadOnlySpan<char> span, Point origin)
         {
             var x = ReadDouble(ref span);
             span = ReadSeparator(span);
@@ -585,7 +585,7 @@ namespace Avalonia.Media
             return new Point(origin.X + x, origin.Y + y);
         }
 
-        private bool ReadCommand(ref ReadOnlySpan<char> span, out Command command, out bool relative)
+        private static bool ReadCommand(ref ReadOnlySpan<char> span, out Command command, out bool relative)
         {
             span = SkipWhitespace(span);
             if (span.IsEmpty)

+ 4 - 2
src/Avalonia.Base/Media/QuadraticBezierSegment .cs

@@ -1,3 +1,5 @@
+using System;
+
 namespace Avalonia.Media
 {
     public sealed class QuadraticBezierSegment : PathSegment
@@ -44,6 +46,6 @@ namespace Avalonia.Media
         }
 
         public override string ToString()
-            => $"Q {Point1} {Point2}";
+            => FormattableString.Invariant($"Q {Point1} {Point2}");
     }
-}
+}

+ 1 - 1
src/Avalonia.Base/Media/RotateTransform.cs

@@ -4,7 +4,7 @@ using Avalonia.VisualTree;
 namespace Avalonia.Media
 {
     /// <summary>
-    /// Rotates an <see cref="IVisual"/>.
+    /// Rotates an <see cref="Visual"/>.
     /// </summary>
     public class RotateTransform : Transform
     {

+ 1 - 1
src/Avalonia.Base/Media/ScaleTransform.cs

@@ -4,7 +4,7 @@ using Avalonia.VisualTree;
 namespace Avalonia.Media
 {
     /// <summary>
-    /// Scale an <see cref="IVisual"/>.
+    /// Scale an <see cref="Visual"/>.
     /// </summary>
     public class ScaleTransform : Transform
     {

+ 1 - 1
src/Avalonia.Base/Media/SkewTransform.cs

@@ -4,7 +4,7 @@ using Avalonia.VisualTree;
 namespace Avalonia.Media
 {
     /// <summary>
-    /// Skews an <see cref="IVisual"/>.
+    /// Skews an <see cref="Visual"/>.
     /// </summary>
     public class SkewTransform : Transform
     {

+ 1 - 1
src/Avalonia.Base/Media/Transform.cs

@@ -7,7 +7,7 @@ using Avalonia.VisualTree;
 namespace Avalonia.Media
 {
     /// <summary>
-    /// Represents a transform on an <see cref="IVisual"/>.
+    /// Represents a transform on an <see cref="Visual"/>.
     /// </summary>
     public abstract class Transform : Animatable, IMutableTransform
     {

+ 1 - 1
src/Avalonia.Base/Media/TranslateTransform.cs

@@ -4,7 +4,7 @@ using Avalonia.VisualTree;
 namespace Avalonia.Media
 {
     /// <summary>
-    /// Translates (moves) an <see cref="IVisual"/>.
+    /// Translates (moves) an <see cref="Visual"/>.
     /// </summary>
     public class TranslateTransform : Transform
     {

+ 2 - 2
src/Avalonia.Base/Platform/AssetLoader.cs

@@ -187,13 +187,13 @@ namespace Avalonia.Platform
             throw new ArgumentException($"Unsupported url type: " + uri.Scheme, nameof(uri));
         }
 
-        private (IAssemblyDescriptor asm, string path) GetResAsmAndPath(Uri uri)
+        private static (IAssemblyDescriptor asm, string path) GetResAsmAndPath(Uri uri)
         {
             var asm = s_assemblyDescriptorResolver.GetAssembly(uri.Authority);
             return (asm, uri.GetUnescapeAbsolutePath());
         }
         
-        private IAssemblyDescriptor? GetAssembly(Uri? uri)
+        private static IAssemblyDescriptor? GetAssembly(Uri? uri)
         {
             if (uri != null)
             {

+ 1 - 1
src/Avalonia.Base/RelativePoint.cs

@@ -199,7 +199,7 @@ namespace Avalonia
         {
             return _unit == RelativeUnit.Absolute ?
                 _point.ToString() :
-                 string.Format(CultureInfo.InvariantCulture, "{0}%, {1}%", _point.X * 100, _point.Y * 100);
+                string.Format(CultureInfo.InvariantCulture, "{0}%, {1}%", _point.X * 100, _point.Y * 100);
         }
     }
 }

+ 6 - 6
src/Avalonia.Base/Rendering/Composition/Animations/KeyFrameAnimationInstance.cs

@@ -87,7 +87,7 @@ namespace Avalonia.Rendering.Composition.Animations
             if (elapsed < _delayTime)
             {
                 if (_delayBehavior == AnimationDelayBehavior.SetInitialValueBeforeDelay)
-                    return ExpressionVariant.Create(GetKeyFrame(ref ctx, _keyFrames[0]));
+                    return ExpressionVariant.Create(KeyFrameAnimationInstance<T>.GetKeyFrame(ref ctx, _keyFrames[0]));
                 return currentValue;
             }
 
@@ -95,7 +95,7 @@ namespace Avalonia.Rendering.Composition.Animations
             var iterationNumber = elapsed.Ticks / _duration.Ticks;
             if (_iterationBehavior == AnimationIterationBehavior.Count
                 && iterationNumber >= _iterationCount)
-                return ExpressionVariant.Create(GetKeyFrame(ref ctx, _keyFrames[_keyFrames.Length - 1]));
+                return ExpressionVariant.Create(KeyFrameAnimationInstance<T>.GetKeyFrame(ref ctx, _keyFrames[_keyFrames.Length - 1]));
             
             
             var evenIterationNumber = iterationNumber % 2 == 0;
@@ -124,7 +124,7 @@ namespace Avalonia.Rendering.Composition.Animations
                 {
                     // this is the last frame
                     if (c == _keyFrames.Length - 1)
-                        return ExpressionVariant.Create(GetKeyFrame(ref ctx, kf));
+                        return ExpressionVariant.Create(KeyFrameAnimationInstance<T>.GetKeyFrame(ref ctx, kf));
 
                     left = kf;
                     right = _keyFrames[c + 1];
@@ -147,13 +147,13 @@ namespace Avalonia.Rendering.Composition.Animations
                 return currentValue;
             
             return ExpressionVariant.Create(_interpolator.Interpolate(
-                GetKeyFrame(ref ctx, left),
-                GetKeyFrame(ref ctx, right),
+                KeyFrameAnimationInstance<T>.GetKeyFrame(ref ctx, left),
+                KeyFrameAnimationInstance<T>.GetKeyFrame(ref ctx, right),
                 easedKeyProgress
             ));
         }
 
-        T GetKeyFrame(ref ExpressionEvaluationContext ctx, ServerKeyFrame<T> f)
+        static T GetKeyFrame(ref ExpressionEvaluationContext ctx, ServerKeyFrame<T> f)
         {
             if (f.Expression != null)
                 return f.Expression.Evaluate(ref ctx).CastOrDefault<T>();

+ 1 - 1
src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs

@@ -124,7 +124,7 @@ public class CompositingRenderer : IRendererWithCompositor
         QueueUpdate();
     }
 
-    private void SyncChildren(Visual v)
+    private static void SyncChildren(Visual v)
     {
         //TODO: Optimize by moving that logic to Visual itself
         if(v.CompositionVisual == null)

+ 2 - 2
src/Avalonia.Base/Rendering/Composition/CompositionTarget.cs

@@ -62,7 +62,7 @@ namespace Avalonia.Rendering.Composition
             return point * m;
         }
 
-        bool TryGetInvertedTransform(CompositionVisual visual, out Matrix matrix)
+        static bool TryGetInvertedTransform(CompositionVisual visual, out Matrix matrix)
         {
             var m = visual.TryGetServerGlobalTransform();
             if (m == null)
@@ -75,7 +75,7 @@ namespace Avalonia.Rendering.Composition
             return m33.TryInvert(out matrix);
         }
 
-        bool TryTransformTo(CompositionVisual visual, Point globalPoint, out Point v)
+        static bool TryTransformTo(CompositionVisual visual, Point globalPoint, out Point v)
         {
             v = default;
             if (TryGetInvertedTransform(visual, out var m))

+ 1 - 1
src/Avalonia.Base/Rendering/Composition/Drawing/CompositionDrawingContext.cs

@@ -368,7 +368,7 @@ internal class CompositionDrawingContext : IDrawingContextImpl, IDrawingContextW
             : null;
     }
     
-    private IDisposable? CreateChildScene(IBrush? brush)
+    private static IDisposable? CreateChildScene(IBrush? brush)
     {
         if (brush is VisualBrush visualBrush)
         {

+ 1 - 1
src/Avalonia.Base/Rendering/Composition/Server/FpsCounter.cs

@@ -52,7 +52,7 @@ internal class FpsCounter
             _lastFpsUpdate = now;
         }
 
-        var fpsLine = $"Frame #{_totalFrames:00000000} FPS: {_fps:000} " + aux;
+        var fpsLine = FormattableString.Invariant($"Frame #{_totalFrames:00000000} FPS: {_fps:000} ") + aux;
         double width = 0;
         double height = 0;
         foreach (var ch in fpsLine)

+ 1 - 1
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs

@@ -156,7 +156,7 @@ namespace Avalonia.Rendering.Composition.Server
                         (Compositor.BatchObjectPool.CurrentUsage + Compositor.BatchObjectPool.CurrentPool) *
                                                                      Compositor.BatchObjectPool.ArraySize *
                                                                      IntPtr.Size), false);
-                    _fpsCounter.RenderFps(targetContext, $"M:{managedMem} / N:{nativeMem} R:{RenderedVisuals:0000}");
+                    _fpsCounter.RenderFps(targetContext, FormattableString.Invariant($"M:{managedMem} / N:{nativeMem} R:{RenderedVisuals:0000}"));
                 }
                 RenderedVisuals = 0;
 

+ 2 - 2
src/Avalonia.Base/Rendering/DeferredRenderer.cs

@@ -272,7 +272,7 @@ namespace Avalonia.Rendering
             }
         }
 
-        Scene? TryGetChildScene(IRef<IDrawOperation>? op) => (op?.Item as BrushDrawOperation)?.Aux as Scene;
+        static Scene? TryGetChildScene(IRef<IDrawOperation>? op) => (op?.Item as BrushDrawOperation)?.Aux as Scene;
         
         /// <inheritdoc/>
         Size IVisualBrushRenderer.GetRenderTargetSize(IVisualBrush brush)
@@ -725,7 +725,7 @@ namespace Avalonia.Rendering
 
             foreach (var layer in Layers)
             {
-                var fileName = Path.Combine(DebugFramesPath ?? string.Empty, $"frame-{id}-layer-{index++}.png");
+                var fileName = Path.Combine(DebugFramesPath ?? string.Empty, FormattableString.Invariant($"frame-{id}-layer-{index++}.png"));
                 layer.Bitmap.Item.Save(fileName);
             }
         }

+ 1 - 1
src/Avalonia.Base/Rendering/RendererBase.cs

@@ -36,7 +36,7 @@ namespace Avalonia.Rendering
                 _lastFpsUpdate = now;
             }
 
-            var text = layerCount.HasValue ? $"Layers: {layerCount} FPS: {_fps:000}" : $"FPS: {_fps:000}";
+            var text = layerCount.HasValue ? FormattableString.Invariant($"Layers: {layerCount} FPS: {_fps:000}") : FormattableString.Invariant($"FPS: {_fps:000}");
 
             var formattedText = new FormattedText(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, Typeface.Default, s_fontSize, Brushes.White);
 

+ 1 - 1
src/Avalonia.Base/Rendering/SceneGraph/SceneBuilder.cs

@@ -318,7 +318,7 @@ namespace Avalonia.Rendering.SceneGraph
             }
         }
 
-        private void UpdateSize(Scene scene)
+        private static void UpdateSize(Scene scene)
         {
             var renderRoot = scene.Root.Visual as IRenderRoot;
             var newSize = renderRoot?.ClientSize ?? scene.Root.Visual.Bounds.Size;

+ 1 - 1
src/Avalonia.Base/Rendering/SceneGraph/VisualNode.cs

@@ -10,7 +10,7 @@ using Avalonia.VisualTree;
 namespace Avalonia.Rendering.SceneGraph
 {
     /// <summary>
-    /// A node in the low-level scene graph representing an <see cref="IVisual"/>.
+    /// A node in the low-level scene graph representing an <see cref="Visual"/>.
     /// </summary>
     internal class VisualNode : IVisualNode
     {

+ 1 - 1
src/Avalonia.Base/Styling/Activators/IStyleActivator.cs

@@ -39,7 +39,7 @@ namespace Avalonia.Styling.Activators
         /// </summary>
         /// <param name="sink">The listener.</param>
         /// <remarks>
-        /// This method should not call <see cref="IStyleActivatorSink.OnNext(bool, int)"/>.
+        /// This method should not call <see cref="IStyleActivatorSink.OnNext(bool)"/>.
         /// </remarks>
         void Subscribe(IStyleActivatorSink sink);
 

+ 1 - 1
src/Avalonia.Base/Thickness.cs

@@ -276,7 +276,7 @@ namespace Avalonia
         /// <returns>The string representation of the thickness.</returns>
         public override string ToString()
         {
-            return $"{_left},{_top},{_right},{_bottom}";
+            return FormattableString.Invariant($"{_left},{_top},{_right},{_bottom}");
         }
 
         /// <summary>

+ 1 - 1
src/Avalonia.Base/VisualTree/TransformedBounds.cs

@@ -77,6 +77,6 @@ namespace Avalonia.VisualTree
             return !left.Equals(right);
         }
 
-        public override string ToString() => $"Bounds: {Bounds} Clip: {Clip} Transform {Transform}";
+        public override string ToString() => FormattableString.Invariant($"Bounds: {Bounds} Clip: {Clip} Transform {Transform}");
     }
 }

+ 1 - 1
src/Avalonia.Build.Tasks/Extensions.cs

@@ -5,7 +5,7 @@ namespace Avalonia.Build.Tasks
 {
     static class Extensions
     {
-        static string FormatErrorCode(BuildEngineErrorCode code) => $"AVLN:{(int)code:0000}";
+        static string FormatErrorCode(BuildEngineErrorCode code) => FormattableString.Invariant($"AVLN:{(int)code:0000}");
 
         public static void LogError(this IBuildEngine engine, BuildEngineErrorCode code, string file, Exception ex,
             int lineNumber = 0, int linePosition = 0)

+ 1 - 1
src/Avalonia.Build.Tasks/GenerateAvaloniaResourcesTask.cs

@@ -67,7 +67,7 @@ namespace Avalonia.Build.Tasks
            {
               
                var src = new Source(r.ItemSpec, Root);
-               BuildEngine.LogMessage($"avares -> name:{src.Path}, path: {src.SystemPath}, size:{src.Size}, ItemSpec:{r.ItemSpec}", _reportImportance);
+               BuildEngine.LogMessage(FormattableString.Invariant($"avares -> name:{src.Path}, path: {src.SystemPath}, size:{src.Size}, ItemSpec:{r.ItemSpec}"), _reportImportance);
                return src;
            }).ToList();
 

+ 1 - 1
src/Avalonia.Controls.ColorPicker/ColorSlider/ColorSlider.cs

@@ -154,7 +154,7 @@ namespace Avalonia.Controls.Primitives
         /// </summary>
         /// <param name="hsvColor">The <see cref="HsvColor"/> to round component values for.</param>
         /// <returns>A new <see cref="HsvColor"/> with rounded component values.</returns>
-        private HsvColor RoundComponentValues(HsvColor hsvColor)
+        private static HsvColor RoundComponentValues(HsvColor hsvColor)
         {
             return new HsvColor(
                 Math.Round(hsvColor.A, 2, MidpointRounding.AwayFromZero),

+ 1 - 1
src/Avalonia.Controls.ColorPicker/ColorSpectrum/ColorSpectrum.cs

@@ -1146,7 +1146,7 @@ namespace Avalonia.Controls.Primitives
             });
         }
 
-        private void FillPixelForBox(
+        private static void FillPixelForBox(
             double x,
             double y,
             Hsv baseHsv,

+ 1 - 1
src/Avalonia.Controls.DataGrid/DataGridTemplateColumn.cs

@@ -56,7 +56,7 @@ namespace Avalonia.Controls
             set => SetAndRaise(CellEditingTemplateProperty, ref _cellEditingCellTemplate, value);
         }
         
-        private void OnCellTemplateChanged(AvaloniaPropertyChangedEventArgs e)
+        private static void OnCellTemplateChanged(AvaloniaPropertyChangedEventArgs e)
         {
             var oldValue = (IDataTemplate)e.OldValue;
             var value = (IDataTemplate)e.NewValue;

+ 1 - 1
src/Avalonia.Controls/Automation/Peers/ComboBoxAutomationPeer.cs

@@ -71,7 +71,7 @@ namespace Avalonia.Automation.Peers
             }
         }
 
-        private ExpandCollapseState ToState(bool value)
+        private static ExpandCollapseState ToState(bool value)
         {
             return value ? ExpandCollapseState.Expanded : ExpandCollapseState.Collapsed;
         }

+ 1 - 1
src/Avalonia.Controls/Calendar/CalendarBlackoutDatesCollection.cs

@@ -206,7 +206,7 @@ namespace Avalonia.Controls.Primitives
             return true;
         }
         
-        private void EnsureValidThread()
+        private static void EnsureValidThread()
         {
             Dispatcher.UIThread.VerifyAccess();
         }

+ 1 - 2
src/Avalonia.Controls/Calendar/SelectedDatesCollection.cs

@@ -6,7 +6,6 @@
 using Avalonia.Threading;
 using System;
 using System.Collections.ObjectModel;
-using System.Threading;
 
 namespace Avalonia.Controls.Primitives
 {
@@ -353,7 +352,7 @@ namespace Avalonia.Controls.Primitives
             return true;
         }
         
-        private void EnsureValidThread()
+        private static void EnsureValidThread()
         {
             Dispatcher.UIThread.VerifyAccess();
         }

+ 1 - 1
src/Avalonia.Controls/DateTimePickers/DateTimePickerPanel.cs

@@ -259,7 +259,7 @@ namespace Avalonia.Controls.Primitives
                 SelectedValue = (int)newSel * Increment + MinimumValue;
                 _suppressUpdateOffset = false;
 
-                System.Diagnostics.Debug.WriteLine($"Offset: {_offset} ItemHeight: {ItemHeight}");
+                System.Diagnostics.Debug.WriteLine(FormattableString.Invariant($"Offset: {_offset} ItemHeight: {ItemHeight}"));
             }
         }
 

+ 4 - 4
src/Avalonia.Controls/Grid.cs

@@ -1165,7 +1165,7 @@ namespace Avalonia.Controls
         /// <remarks>
         /// For "Auto" definitions MinWidth is used in place of PreferredSize.
         /// </remarks>
-        private double GetMeasureSizeForRange(
+        private static double GetMeasureSizeForRange(
             IReadOnlyList<DefinitionBase> definitions,
             int start,
             int count)
@@ -1192,7 +1192,7 @@ namespace Avalonia.Controls
         /// <param name="start">Starting index of the range.</param>
         /// <param name="count">Number of definitions included in the range.</param>
         /// <returns>Length type for given range.</returns>
-        private LayoutTimeSizeType GetLengthTypeForRange(
+        private static LayoutTimeSizeType GetLengthTypeForRange(
             IReadOnlyList<DefinitionBase> definitions,
             int start,
             int count)
@@ -1721,7 +1721,7 @@ namespace Avalonia.Controls
         /// </summary>
         /// <param name="definitions">Array of definitions to use for calculations.</param>
         /// <returns>Desired size.</returns>
-        private double CalculateDesiredSize(
+        private static double CalculateDesiredSize(
             IReadOnlyList<DefinitionBase> definitions)
         {
             double desiredSize = 0;
@@ -2281,7 +2281,7 @@ namespace Avalonia.Controls
         /// <param name="start">Start of the range.</param>
         /// <param name="count">Number of items in the range.</param>
         /// <returns>Final size.</returns>
-        private double GetFinalSizeForRange(
+        private static double GetFinalSizeForRange(
             IReadOnlyList<DefinitionBase> definitions,
             int start,
             int count)

+ 1 - 1
src/Avalonia.Controls/GridSplitter.cs

@@ -516,7 +516,7 @@ namespace Avalonia.Controls
         /// <summary>
         /// Retrieves the ActualWidth or ActualHeight of the definition depending on its type Column or Row.
         /// </summary>
-        private double GetActualLength(DefinitionBase definition)
+        private static double GetActualLength(DefinitionBase definition)
         {
             var column = definition as ColumnDefinition;
 

+ 6 - 5
src/Avalonia.Controls/MenuItemAccessKeyHandler.cs

@@ -14,7 +14,7 @@ namespace Avalonia.Controls
         /// <summary>
         /// The registered access keys.
         /// </summary>
-        private readonly List<Tuple<string, IInputElement>> _registered = new List<Tuple<string, IInputElement>>();
+        private readonly List<(string AccessKey, IInputElement Element)> _registered = new();
 
         /// <summary>
         /// The window to which the handler belongs.
@@ -59,12 +59,12 @@ namespace Avalonia.Controls
         {
             var existing = _registered.FirstOrDefault(x => x.Item2 == element);
 
-            if (existing != null)
+            if (existing != default)
             {
                 _registered.Remove(existing);
             }
 
-            _registered.Add(Tuple.Create(accessKey.ToString().ToUpper(), element));
+            _registered.Add((accessKey.ToString().ToUpperInvariant(), element));
         }
 
         /// <summary>
@@ -88,9 +88,10 @@ namespace Avalonia.Controls
         {
             if (!string.IsNullOrWhiteSpace(e.Text))
             {
-                var text = e.Text.ToUpper();
+                var text = e.Text;
                 var focus = _registered
-                    .FirstOrDefault(x => x.Item1 == text && x.Item2.IsEffectivelyVisible)?.Item2;
+                    .FirstOrDefault(x => string.Equals(x.AccessKey, text, StringComparison.OrdinalIgnoreCase)
+                        && x.Element.IsEffectivelyVisible).Element;
 
                 focus?.RaiseEvent(new RoutedEventArgs(AccessKeyHandler.AccessKeyPressedEvent));
 

+ 2 - 2
src/Avalonia.Controls/Platform/InProcessDragSource.cs

@@ -69,7 +69,7 @@ namespace Avalonia.Platform
             return effect;
         }
 
-        private DragDropEffects GetPreferredEffect(DragDropEffects effect, RawInputModifiers modifiers)
+        private static DragDropEffects GetPreferredEffect(DragDropEffects effect, RawInputModifiers modifiers)
         {
             if (effect == DragDropEffects.Copy || effect == DragDropEffects.Move || effect == DragDropEffects.Link || effect == DragDropEffects.None)
                 return effect; // No need to check for the modifiers.
@@ -80,7 +80,7 @@ namespace Avalonia.Platform
             return DragDropEffects.Move;
         }
 
-        private StandardCursorType GetCursorForDropEffect(DragDropEffects effects)
+        private static StandardCursorType GetCursorForDropEffect(DragDropEffects effects)
         {
             if (effects.HasAllFlags(DragDropEffects.Copy))
                 return StandardCursorType.DragCopy;

+ 2 - 4
src/Avalonia.Controls/Primitives/Popup.cs

@@ -1,6 +1,5 @@
 using System;
 using System.ComponentModel;
-using System.Linq;
 using System.Reactive.Disposables;
 using Avalonia.Automation.Peers;
 using Avalonia.Controls.Mixins;
@@ -15,7 +14,6 @@ using Avalonia.Metadata;
 using Avalonia.Platform;
 using Avalonia.VisualTree;
 using Avalonia.Media;
-using Avalonia.Utilities;
 
 namespace Avalonia.Controls.Primitives
 {
@@ -639,7 +637,7 @@ namespace Avalonia.Controls.Primitives
             return Disposable.Create((unsubscribe, target, handler), state => state.unsubscribe(state.target, state.handler));
         }
 
-        private void WindowManagerAddShadowHintChanged(IPopupHost host, bool hint)
+        private static void WindowManagerAddShadowHintChanged(IPopupHost host, bool hint)
         {
             if(host is PopupRoot pr && pr.PlatformImpl is not null)
             {
@@ -769,7 +767,7 @@ namespace Avalonia.Controls.Primitives
             }
         }
 
-        private void PassThroughEvent(PointerPressedEventArgs e)
+        private static void PassThroughEvent(PointerPressedEventArgs e)
         {
             if (e.Source is LightDismissOverlayLayer layer &&
                 layer.GetVisualRoot() is InputElement root)

+ 1 - 1
src/Avalonia.Controls/Repeater/RecyclingElementFactory.cs

@@ -87,7 +87,7 @@ namespace Avalonia.Controls
 
         protected virtual string OnSelectTemplateKeyCore(object? dataContext, Control? owner)
         {
-            if (SelectTemplateKey is object)
+            if (SelectTemplateKey is not null)
             {
                 _args ??= new SelectTemplateEventArgs();
                 _args.TemplateKey = null;

+ 1 - 1
src/Avalonia.Controls/Selection/IndexRange.cs

@@ -86,7 +86,7 @@ namespace Avalonia.Controls.Selection
             return hashCode;
         }
 
-        public override string ToString() => $"[{Begin}..{End}]";
+        public override string ToString() => FormattableString.Invariant($"[{Begin}..{End}]");
 
         public static bool operator ==(IndexRange left, IndexRange right) => left.Equals(right);
         public static bool operator !=(IndexRange left, IndexRange right) => !(left == right);

+ 2 - 2
src/Avalonia.Controls/Selection/SelectionNodeBase.cs

@@ -290,12 +290,12 @@ namespace Avalonia.Controls.Selection
             // so bail.
             //
             // See unit test Handles_Selection_Made_In_CollectionChanged for more details.
-            if (ItemsView is object &&
+            if (ItemsView is not null &&
                 RangesEnabled &&
                 Ranges.Count > 0 &&
                 e.Action == NotifyCollectionChangedAction.Add)
             {
-                var lastIndex = Ranges.Last().End;
+                var lastIndex = Ranges[Ranges.Count - 1].End;
 
                 if (e.NewStartingIndex <= lastIndex)
                 {

+ 13 - 7
src/Avalonia.Controls/Slider.cs

@@ -190,7 +190,7 @@ namespace Avalonia.Controls
             _increaseButtonSubscription?.Dispose();
             _increaseButtonReleaseDispose?.Dispose();
             _pointerMovedDispose?.Dispose();
-            
+
             _decreaseButton = e.NameScope.Find<Button>("PART_DecreaseButton");
             _track = e.NameScope.Find<Track>("PART_Track");
             _increaseButton = e.NameScope.Find<Button>("PART_IncreaseButton");
@@ -258,7 +258,7 @@ namespace Avalonia.Controls
 
             e.Handled = handled;
         }
-            
+
         private void MoveToNextTick(double direction)
         {
             if (direction == 0.0) return;
@@ -317,6 +317,12 @@ namespace Avalonia.Controls
 
         private void TrackMoved(object? sender, PointerEventArgs e)
         {
+            if (!IsEnabled)
+            {
+                _isDragging = false;
+                return;
+            }
+
             if (_isDragging)
             {
                 MoveToPoint(e.GetCurrentPoint(_track));
@@ -343,15 +349,15 @@ namespace Avalonia.Controls
                 return;
 
             var orient = Orientation == Orientation.Horizontal;
-            var thumbLength = (orient 
-                ? _track.Thumb.Bounds.Width 
+            var thumbLength = (orient
+                ? _track.Thumb.Bounds.Width
                 : _track.Thumb.Bounds.Height) + double.Epsilon;
-            var trackLength = (orient 
-                ? _track.Bounds.Width 
+            var trackLength = (orient
+                ? _track.Bounds.Width
                 : _track.Bounds.Height) - thumbLength;
             var trackPos = orient ? posOnTrack.Position.X : posOnTrack.Position.Y;
             var logicalPos = MathUtilities.Clamp((trackPos - thumbLength * 0.5) / trackLength, 0.0d, 1.0d);
-            var invert = orient ? 
+            var invert = orient ?
                 IsDirectionReversed ? 1 : 0 :
                 IsDirectionReversed ? 0 : 1;
             var calcVal = Math.Abs(invert - logicalPos);

+ 2 - 5
src/Avalonia.Controls/SplitView.cs

@@ -1,14 +1,11 @@
 using Avalonia.Controls.Metadata;
 using Avalonia.Controls.Primitives;
 using Avalonia.Input;
-using Avalonia.Input.Raw;
 using Avalonia.Interactivity;
 using Avalonia.Media;
 using Avalonia.Metadata;
-using Avalonia.Platform;
 using Avalonia.VisualTree;
 using System;
-using System.Reactive.Disposables;
 using Avalonia.Controls.Presenters;
 using Avalonia.Controls.Templates;
 using Avalonia.LogicalTree;
@@ -431,7 +428,7 @@ namespace Avalonia.Controls
             }
         }
 
-        private string GetPseudoClass(SplitViewDisplayMode mode)
+        private static string GetPseudoClass(SplitViewDisplayMode mode)
         {
             return mode switch
             {
@@ -443,7 +440,7 @@ namespace Avalonia.Controls
             };
         }
         
-        private string GetPseudoClass(SplitViewPanePlacement placement)
+        private static string GetPseudoClass(SplitViewPanePlacement placement)
         {
             return placement switch
             {

+ 1 - 1
src/Avalonia.Controls/TextBox.cs

@@ -1588,7 +1588,7 @@ namespace Avalonia.Controls
 
         private int CoerceCaretIndex(int value) => CoerceCaretIndex(value, Text);
 
-        private int CoerceCaretIndex(int value, string? text)
+        private static int CoerceCaretIndex(int value, string? text)
         {
             if (text == null)
             {

+ 1 - 1
src/Avalonia.Controls/TopLevel.cs

@@ -427,7 +427,7 @@ namespace Avalonia.Controls
             LayoutHelper.InvalidateSelfAndChildrenMeasure(this);
         }
 
-        private bool TransparencyLevelsMatch (WindowTransparencyLevel requested, WindowTransparencyLevel received)
+        private static bool TransparencyLevelsMatch (WindowTransparencyLevel requested, WindowTransparencyLevel received)
         {
             if(requested == received)
             {

+ 0 - 1
src/Avalonia.Controls/UserControl.cs

@@ -1,4 +1,3 @@
-using System;
 using Avalonia.Styling;
 
 namespace Avalonia.Controls

+ 1 - 1
src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs

@@ -162,7 +162,7 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport
                     if (sendNow != null && socket != null)
                     {
                         await socket.SendMessage(
-                            $"frame:{sendNow.SequenceId}:{sendNow.Width}:{sendNow.Height}:{sendNow.Stride}:{sendNow.DpiX}:{sendNow.DpiY}");
+                            FormattableString.Invariant($"frame:{sendNow.SequenceId}:{sendNow.Width}:{sendNow.Height}:{sendNow.Stride}:{sendNow.DpiX}:{sendNow.DpiY}"));
                         await socket.SendMessage(false, sendNow.Data);
                     }
 

+ 1 - 1
src/Avalonia.DesignerSupport/Remote/HtmlTransport/SimpleWebSocketHttpServer.cs

@@ -146,7 +146,7 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport
 
         public async Task RespondAsync(int code, byte[] data, string contentType)
         {
-            var headers = Encoding.UTF8.GetBytes($"HTTP/1.1 {code} {(HttpStatusCode)code}\r\nConnection: close\r\nContent-Type: {contentType}\r\nContent-Length: {data.Length}\r\n\r\n");
+            var headers = Encoding.UTF8.GetBytes(FormattableString.Invariant($"HTTP/1.1 {code} {(HttpStatusCode)code}\r\nConnection: close\r\nContent-Type: {contentType}\r\nContent-Length: {data.Length}\r\n\r\n"));
             await _stream.WriteAsync(headers, 0, headers.Length);
             await _stream.WriteAsync(data, 0, data.Length);
             _stream.Dispose();

+ 1 - 1
src/Avalonia.Diagnostics/Diagnostics/Screenshots/FilePickerHandler.cs

@@ -47,7 +47,7 @@ namespace Avalonia.Diagnostics.Screenshots
         /// </summary>
         public string Title { get; } = "Save Screenshot to ...";
 
-        Window GetWindow(Control control)
+        static Window GetWindow(Control control)
         {
             var window = control.VisualRoot as Window;
             var app = Application.Current;

+ 7 - 7
src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs

@@ -82,7 +82,7 @@ namespace Avalonia.Diagnostics.ViewModels
                             {
                                 var setterValue = regularSetter.Value;
 
-                                var resourceInfo = GetResourceInfo(setterValue);
+                                var resourceInfo =  GetResourceInfo(setterValue);
 
                                 SetterViewModel setterVm;
 
@@ -121,7 +121,7 @@ namespace Avalonia.Diagnostics.ViewModels
 
         public bool CanNavigateToParentProperty => _selectedEntitiesStack.Count >= 1;
 
-        private (object resourceKey, bool isDynamic)? GetResourceInfo(object? value)
+        private static (object resourceKey, bool isDynamic)? GetResourceInfo(object? value)
         {
             if (value is StaticResourceExtension staticResource)
             {
@@ -136,7 +136,7 @@ namespace Avalonia.Diagnostics.ViewModels
             return null;
         }
 
-        private bool IsBinding(object? value)
+        private static bool IsBinding(object? value)
         {
             switch (value)
             {
@@ -253,7 +253,7 @@ namespace Avalonia.Diagnostics.ViewModels
             }
         }
 
-        private IEnumerable<PropertyViewModel> GetAvaloniaProperties(object o)
+        private static IEnumerable<PropertyViewModel> GetAvaloniaProperties(object o)
         {
             if (o is AvaloniaObject ao)
             {
@@ -267,7 +267,7 @@ namespace Avalonia.Diagnostics.ViewModels
             }
         }
 
-        private IEnumerable<PropertyViewModel> GetClrProperties(object o, bool showImplementedInterfaces)
+        private static IEnumerable<PropertyViewModel> GetClrProperties(object o, bool showImplementedInterfaces)
         {
             foreach (var p in GetClrProperties(o, o.GetType()))
             {
@@ -286,7 +286,7 @@ namespace Avalonia.Diagnostics.ViewModels
             }
         }
 
-        private IEnumerable<PropertyViewModel> GetClrProperties(object o, Type t)
+        private static IEnumerable<PropertyViewModel> GetClrProperties(object o, Type t)
         {
             return t.GetProperties()
                 .Where(x => x.GetIndexParameters().Length == 0)
@@ -411,7 +411,7 @@ namespace Avalonia.Diagnostics.ViewModels
                 }
             }
 
-            private int GroupIndex(string? group)
+            private static int GroupIndex(string? group)
             {
                 switch (group)
                 {

+ 4 - 4
src/Avalonia.Dialogs/ManagedStorageProvider.cs

@@ -29,7 +29,7 @@ public class ManagedStorageProvider<T> : BclStorageProvider where T : Window, ne
     public override async Task<IReadOnlyList<IStorageFile>> OpenFilePickerAsync(FilePickerOpenOptions options)
     {
         var model = new ManagedFileChooserViewModel(options, _managedOptions);
-        var results = await Show(model, _parent);
+        var results = await ManagedStorageProvider<T>.Show(model, _parent);
 
         return results.Select(f => new BclStorageFile(new FileInfo(f))).ToArray();
     }
@@ -37,7 +37,7 @@ public class ManagedStorageProvider<T> : BclStorageProvider where T : Window, ne
     public override async Task<IStorageFile?> SaveFilePickerAsync(FilePickerSaveOptions options)
     {
         var model = new ManagedFileChooserViewModel(options, _managedOptions);
-        var results = await Show(model, _parent);
+        var results = await ManagedStorageProvider<T>.Show(model, _parent);
 
         return results.FirstOrDefault() is { } result
             ? new BclStorageFile(new FileInfo(result))
@@ -47,12 +47,12 @@ public class ManagedStorageProvider<T> : BclStorageProvider where T : Window, ne
     public override async Task<IReadOnlyList<IStorageFolder>> OpenFolderPickerAsync(FolderPickerOpenOptions options)
     {
         var model = new ManagedFileChooserViewModel(options, _managedOptions);
-        var results = await Show(model, _parent);
+        var results = await ManagedStorageProvider<T>.Show(model, _parent);
 
         return results.Select(f => new BclStorageFolder(new DirectoryInfo(f))).ToArray();
     }
             
-    private async Task<string[]> Show(ManagedFileChooserViewModel model, Window parent)
+    private static async Task<string[]> Show(ManagedFileChooserViewModel model, Window parent)
     {
         var dialog = new T
         {

+ 1 - 1
src/Avalonia.FreeDesktop/DBusTrayIconImpl.cs

@@ -127,7 +127,7 @@ namespace Avalonia.FreeDesktop
             var pid = Process.GetCurrentProcess().Id;
             var tid = s_trayIconInstanceId++;
 
-            _sysTrayServiceName = $"org.kde.StatusNotifierItem-{pid}-{tid}";
+            _sysTrayServiceName = FormattableString.Invariant($"org.kde.StatusNotifierItem-{pid}-{tid}");
             _statusNotifierItemDbusObj = new StatusNotifierItemDbusObj(_dbusMenuPath);
 
             try

+ 4 - 4
src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs

@@ -34,14 +34,14 @@ namespace Avalonia.FreeDesktop
             Poll(0);
         }
 
-        private string GetSymlinkTarget(string x) => Path.GetFullPath(Path.Combine(DevByLabelDir, NativeMethods.ReadLink(x)));
+        private static string GetSymlinkTarget(string x) => Path.GetFullPath(Path.Combine(DevByLabelDir, NativeMethods.ReadLink(x)));
 
-        private string UnescapeString(string input, string regexText, int escapeBase) =>
+        private static string UnescapeString(string input, string regexText, int escapeBase) =>
             new Regex(regexText).Replace(input, m => Convert.ToChar(Convert.ToByte(m.Groups[1].Value, escapeBase)).ToString());
 
-        private string UnescapePathFromProcMounts(string input) => UnescapeString(input, @"\\(\d{3})", 8);
+        private static string UnescapePathFromProcMounts(string input) => UnescapeString(input, @"\\(\d{3})", 8);
 
-        private string UnescapeDeviceLabel(string input) => UnescapeString(input, @"\\x([0-9a-f]{2})", 16);
+        private static string UnescapeDeviceLabel(string input) => UnescapeString(input, @"\\x([0-9a-f]{2})", 16);
 
         private void Poll(long _)
         {

+ 1 - 1
src/Avalonia.Native/AvaloniaNativeMenuExporter.cs

@@ -65,7 +65,7 @@ namespace Avalonia.Native
             }
         }
 
-        private NativeMenu CreateDefaultAppMenu()
+        private static NativeMenu CreateDefaultAppMenu()
         {
             var result = new NativeMenu();
 

+ 1 - 2
src/Avalonia.Native/IAvnMenu.cs

@@ -3,7 +3,6 @@ using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.Reactive.Disposables;
 using Avalonia.Controls;
-using Avalonia.Platform.Interop;
 
 namespace Avalonia.Native.Interop
 {
@@ -112,7 +111,7 @@ namespace Avalonia.Native.Interop.Impl
             return result;
         }
 
-        private __MicroComIAvnMenuItemProxy CreateNew(IAvaloniaNativeFactory factory, NativeMenuItemBase item)
+        private static __MicroComIAvnMenuItemProxy CreateNew(IAvaloniaNativeFactory factory, NativeMenuItemBase item)
         {
             var nativeItem = (__MicroComIAvnMenuItemProxy)(item is NativeMenuItemSeparator ?
                 factory.CreateMenuItemSeparator() :

+ 2 - 2
src/Avalonia.OpenGL/Controls/OpenGlControlBase.cs

@@ -38,7 +38,7 @@ namespace Avalonia.OpenGL.Controls
             base.Render(context);
         }
         
-        private void CheckError(GlInterface gl)
+        private static void CheckError(GlInterface gl)
         {
             int err;
             while ((err = gl.GetError()) != GL_NO_ERROR)
@@ -197,7 +197,7 @@ namespace Avalonia.OpenGL.Controls
             }
         }
 
-        private bool CheckFramebufferStatus(GlInterface gl)
+        private static bool CheckFramebufferStatus(GlInterface gl)
         {
             var status = gl.CheckFramebufferStatus(GL_FRAMEBUFFER);
             if (status != GL_FRAMEBUFFER_COMPLETE)

+ 1 - 1
src/Avalonia.Remote.Protocol/MetsysBson.cs

@@ -562,7 +562,7 @@ namespace Metsys.Bson
         {
             if (_string == null && Value != null)
             {
-                _string = BitConverter.ToString(Value).Replace("-", string.Empty).ToLower();
+                _string = BitConverter.ToString(Value).Replace("-", string.Empty).ToLowerInvariant();
             }
 
             return _string;

+ 8 - 8
src/Avalonia.Themes.Fluent/Controls/CalendarButton.xaml

@@ -35,13 +35,13 @@
           <!-- To mimic WinUI SystemFocusVisual, Focus visual is drawn outside the bounds of the item -->
           <Border Name="Root" Background="{TemplateBinding Background}"
                   BorderThickness="0" ClipToBounds="True">
-            <ContentControl Name="Content"
-                            ContentTemplate="{TemplateBinding ContentTemplate}"
-                            Content="{TemplateBinding Content}"
-                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
-                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
-                            FontSize="{TemplateBinding FontSize}"
-                            Margin="{TemplateBinding Padding}" />
+            <ContentPresenter Name="Content"
+                              ContentTemplate="{TemplateBinding ContentTemplate}"
+                              Content="{TemplateBinding Content}"
+                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
+                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
+                              FontSize="{TemplateBinding FontSize}"
+                              Margin="{TemplateBinding Padding}" />
           </Border>
 
           <!-- Drawn Border should render on top of background to preserve the 1px margin between items -->
@@ -70,7 +70,7 @@
         <Setter Property="BorderBrush" Value="{DynamicResource CalendarViewSelectedBorderBrush}" />
       </Style>
 
-      <Style Selector="^ /template/ ContentControl#Content">
+      <Style Selector="^ /template/ ContentPresenter#Content">
         <Setter Property="Foreground" Value="{DynamicResource CalendarViewTodayForeground}" />
         <Setter Property="FontWeight" Value="SemiBold" />
       </Style>

+ 19 - 20
src/Avalonia.Themes.Fluent/Controls/Slider.xaml

@@ -302,26 +302,6 @@
       <Setter Property="IsVisible" Value="True" />
     </Style>
 
-    <!--  Disabled State  -->
-
-    <Style Selector="^:disabled">
-      <Style Selector="^ /template/ RepeatButton#PART_DecreaseButton">
-        <Setter Property="Background" Value="{DynamicResource SliderTrackValueFillDisabled}" />
-      </Style>
-
-      <Style Selector="^ /template/ RepeatButton#PART_IncreaseButton">
-        <Setter Property="Background" Value="{DynamicResource SliderTrackFillDisabled}" />
-      </Style>
-
-      <Style Selector="^ /template/ Thumb">
-        <Setter Property="Background" Value="{DynamicResource SliderThumbBackgroundDisabled}" />
-      </Style>
-
-      <Style Selector="^ /template/ TickBar">
-        <Setter Property="Fill" Value="{DynamicResource SliderTickBarFillDisabled}" />
-      </Style>
-    </Style>
-
     <!--  PointerOver State  -->
     <Style Selector="^:pointerover">
       <Style Selector="^ /template/ Grid#SliderContainer">
@@ -362,6 +342,25 @@
       </Style>
     </Style>
 
+    <!--  Disabled State  -->
+    <Style Selector="^:disabled">
+      <Style Selector="^ /template/ RepeatButton#PART_DecreaseButton">
+        <Setter Property="Background" Value="{DynamicResource SliderTrackValueFillDisabled}" />
+      </Style>
+
+      <Style Selector="^ /template/ RepeatButton#PART_IncreaseButton">
+        <Setter Property="Background" Value="{DynamicResource SliderTrackFillDisabled}" />
+      </Style>
+
+      <Style Selector="^ /template/ Thumb">
+        <Setter Property="Background" Value="{DynamicResource SliderThumbBackgroundDisabled}" />
+      </Style>
+
+      <Style Selector="^ /template/ TickBar">
+        <Setter Property="Fill" Value="{DynamicResource SliderTickBarFillDisabled}" />
+      </Style>
+    </Style>
+
     <Style Selector="^:error">
       <Setter Property="Foreground" Value="{DynamicResource SystemControlErrorTextForegroundBrush}" />
       <Style Selector="^ /template/ Thumb">

+ 9 - 9
src/Avalonia.Themes.Simple/Controls/CalendarButton.xaml

@@ -32,14 +32,14 @@
                      Opacity="0.5" />
 
           <!--  Focusable="False"  -->
-          <ContentControl Name="Content"
-                          Margin="1,0,1,1"
-                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
-                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
-                          Content="{TemplateBinding Content}"
-                          ContentTemplate="{TemplateBinding ContentTemplate}"
-                          FontSize="{TemplateBinding FontSize}"
-                          Foreground="{TemplateBinding Foreground}" />
+          <ContentPresenter Name="Content"
+                            Margin="1,0,1,1"
+                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
+                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
+                            Content="{TemplateBinding Content}"
+                            ContentTemplate="{TemplateBinding ContentTemplate}"
+                            FontSize="{TemplateBinding FontSize}"
+                            Foreground="{TemplateBinding Foreground}" />
 
           <Rectangle Name="FocusVisual"
                      IsHitTestVisible="False"
@@ -62,7 +62,7 @@
       <Setter Property="IsVisible" Value="True" />
     </Style>
 
-    <Style Selector="^:inactive /template/ ContentControl#Content">
+    <Style Selector="^:inactive /template/ ContentPresenter#Content">
       <Setter Property="Foreground" Value="{DynamicResource ThemeForegroundLowBrush}" />
     </Style>
 

Some files were not shown because too many files changed in this diff