Browse Source

add nullable and refactor.

pull/3987/head
Dan Walmsley 6 years ago
parent
commit
ecdc9d0186
  1. 9
      src/Avalonia.Controls/RelativePanel.AttachedProperties.cs
  2. 37
      src/Avalonia.Controls/RelativePanel.cs
  3. 11
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs
  4. 55
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs

9
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()

37
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<GraphNode> 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<AvaloniaObject, GraphNode>();
}
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<GraphNode> nodes, HashSet<Layoutable> set)
private bool CheckCyclic(IEnumerable<GraphNode> nodes, HashSet<Layoutable>? set)
{
if (set == null)
{
set = new HashSet<Layoutable>();
}
set ??= new HashSet<Layoutable>();
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);
}
}

11
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<INameScope>();
var nameScope = serviceProvider.GetService<INameScope>();
var value = namescope.FindAsync(Name);
var value = nameScope.FindAsync(Name);
if(value.IsCompleted)
return value.GetResult();
var provideValueTarget = serviceProvider.GetService<IProvideValueTarget>();
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;

55
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<IXamlCustomAttribute> attributes = propertyValueNode.Property.GetClrProperty().CustomAttributes;
if (propertyValueNode.Property is XamlAstClrProperty referenceNode &&
referenceNode.Getter != null)
{
attributes = attributes.Concat(referenceNode.Getter.CustomAttributes);
}
IEnumerable<IXamlCustomAttribute> 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<IXamlAstValueNode>
{
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<IXamlAstValueNode> { propertyValueNode.Values[0] }
};
if (XamlTransformHelpers.TryConvertMarkupExtension(context, newNode, out var extensionNode))
{
propertyValueNode.Values[0] = extensionNode;
}
return node;

Loading…
Cancel
Save