diff --git a/src/Avalonia.Controls/RelativePanel.AttachedProperties.cs b/src/Avalonia.Controls/RelativePanel.AttachedProperties.cs index 91a4f15039..f93de5ca15 100644 --- a/src/Avalonia.Controls/RelativePanel.AttachedProperties.cs +++ b/src/Avalonia.Controls/RelativePanel.AttachedProperties.cs @@ -1,14 +1,17 @@ using Avalonia.Layout; +#nullable enable + namespace Avalonia.Controls { public partial class RelativePanel { private static void OnAlignPropertiesChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e) { - var elm = d as Layoutable; - if (elm.Parent is Layoutable) - ((Layoutable)elm.Parent).InvalidateArrange(); + if (d is Layoutable layoutable && layoutable.Parent is Layoutable layoutableParent) + { + layoutableParent.InvalidateArrange(); + } } static RelativePanel() diff --git a/src/Avalonia.Controls/RelativePanel.cs b/src/Avalonia.Controls/RelativePanel.cs index d44d39ed90..d7bc658dd1 100644 --- a/src/Avalonia.Controls/RelativePanel.cs +++ b/src/Avalonia.Controls/RelativePanel.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using System.Linq; using Avalonia.Layout; +#nullable enable + namespace Avalonia.Controls { public partial class RelativePanel : Panel @@ -80,7 +82,7 @@ namespace Avalonia.Controls return size; } - private Layoutable GetDependencyElement(AvaloniaProperty property, AvaloniaObject child) + private Layoutable? GetDependencyElement(AvaloniaProperty property, AvaloniaObject child) { var dependency = child.GetValue(property); @@ -89,7 +91,7 @@ namespace Avalonia.Controls if (Children.Contains((ILayoutable)layoutable)) return layoutable; - throw new ArgumentException(string.Format("RelativePanel error: Element does not exist in the current context", property.Name)); + throw new ArgumentException($"RelativePanel error: Element does not exist in the current context: {property.Name}"); } return null; @@ -105,25 +107,25 @@ namespace Avalonia.Controls public HashSet OutgoingNodes { get; } - public GraphNode AlignLeftWithNode { get; set; } + public GraphNode? AlignLeftWithNode { get; set; } - public GraphNode AlignTopWithNode { get; set; } + public GraphNode? AlignTopWithNode { get; set; } - public GraphNode AlignRightWithNode { get; set; } + public GraphNode? AlignRightWithNode { get; set; } - public GraphNode AlignBottomWithNode { get; set; } + public GraphNode? AlignBottomWithNode { get; set; } - public GraphNode LeftOfNode { get; set; } + public GraphNode? LeftOfNode { get; set; } - public GraphNode AboveNode { get; set; } + public GraphNode? AboveNode { get; set; } - public GraphNode RightOfNode { get; set; } + public GraphNode? RightOfNode { get; set; } - public GraphNode BelowNode { get; set; } + public GraphNode? BelowNode { get; set; } - public GraphNode AlignHorizontalCenterWith { get; set; } + public GraphNode? AlignHorizontalCenterWith { get; set; } - public GraphNode AlignVerticalCenterWith { get; set; } + public GraphNode? AlignVerticalCenterWith { get; set; } public GraphNode(Layoutable element) { @@ -143,7 +145,7 @@ namespace Avalonia.Controls _nodeDic = new Dictionary(); } - public GraphNode AddLink(GraphNode from, Layoutable to) + public GraphNode? AddLink(GraphNode from, Layoutable? to) { if (to == null) return null; @@ -183,12 +185,9 @@ namespace Avalonia.Controls public bool CheckCyclic() => CheckCyclic(_nodeDic.Values, null); - private bool CheckCyclic(IEnumerable nodes, HashSet set) + private bool CheckCyclic(IEnumerable nodes, HashSet? set) { - if (set == null) - { - set = new HashSet(); - } + set ??= new HashSet(); foreach (var node in nodes) { @@ -341,7 +340,7 @@ namespace Avalonia.Controls } else { - childPos = childPos.WithY((_arrangeSize.Height + node.AlignLeftWithNode.Position.Y - childSize.Height) / 2); + childPos = childPos.WithY((_arrangeSize.Height + node.AlignTopWithNode.Position.Y - childSize.Height) / 2); } } diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs index 2b5d1ced3a..8561aa898b 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs @@ -2,6 +2,8 @@ using Avalonia.Controls; using Avalonia.Data.Core; +#nullable enable + namespace Avalonia.Markup.Xaml.MarkupExtensions { public class ResolveByNameExtension @@ -13,20 +15,19 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions public string Name { get; } - public object ProvideValue(IServiceProvider serviceProvider) + public object? ProvideValue(IServiceProvider serviceProvider) { - var namescope = serviceProvider.GetService(); + var nameScope = serviceProvider.GetService(); - var value = namescope.FindAsync(Name); + var value = nameScope.FindAsync(Name); if(value.IsCompleted) return value.GetResult(); var provideValueTarget = serviceProvider.GetService(); var target = provideValueTarget.TargetObject; - var property = provideValueTarget.TargetProperty as IPropertyInfo; - if (property != null) + if (provideValueTarget.TargetProperty is IPropertyInfo property) value.OnCompleted(() => property.Set(target, value.GetResult())); return null; diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs index f550f82972..1c5e4fd4ce 100644 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs @@ -5,47 +5,40 @@ using XamlX.Ast; using XamlX.Transform; using XamlX.TypeSystem; +#nullable enable namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers { class AvaloniaXamlIlResolveByNameMarkupExtensionReplacer : IXamlAstTransformer { public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { - if (node is XamlAstXamlPropertyValueNode propertyValueNode) + if (!(node is XamlAstXamlPropertyValueNode propertyValueNode)) return node; + + IEnumerable attributes = propertyValueNode.Property.GetClrProperty().CustomAttributes; + + if (propertyValueNode.Property is XamlAstClrProperty referenceNode && + referenceNode.Getter != null) { + attributes = attributes.Concat(referenceNode.Getter.CustomAttributes); + } - IEnumerable attributes = propertyValueNode.Property.GetClrProperty().CustomAttributes; + if (attributes.All(attribute => attribute.Type.FullName != "Avalonia.Controls.ResolveByNameAttribute")) + return node; - if (propertyValueNode.Property is XamlAstClrProperty referenceNode && - referenceNode.Getter != null) - { - attributes = attributes.Concat(referenceNode.Getter.CustomAttributes); - } + if (propertyValueNode.Values.Count != 1 || !(propertyValueNode.Values.First() is XamlAstTextNode)) + return node; - foreach (var attribute in attributes) - { - if (attribute.Type.FullName == "Avalonia.Controls.ResolveByNameAttribute") - { - if (propertyValueNode.Values.Count == 1 && - propertyValueNode.Values.First() is XamlAstTextNode) - { - if (XamlTransformHelpers.TryConvertMarkupExtension(context, new XamlAstObjectNode( - propertyValueNode.Values[0], - new XamlAstClrTypeReference(propertyValueNode.Values[0], - context.GetAvaloniaTypes().ResolveByNameExtension, true)) - { - Arguments = new System.Collections.Generic.List - { - propertyValueNode.Values[0] - } - }, out var extensionNode)) - { - propertyValueNode.Values[0] = extensionNode; - } - } - break; - } - } + var newNode = new XamlAstObjectNode( + propertyValueNode.Values[0], + new XamlAstClrTypeReference(propertyValueNode.Values[0], + context.GetAvaloniaTypes().ResolveByNameExtension, true)) + { + Arguments = new List { propertyValueNode.Values[0] } + }; + + if (XamlTransformHelpers.TryConvertMarkupExtension(context, newNode, out var extensionNode)) + { + propertyValueNode.Values[0] = extensionNode; } return node;