diff --git a/src/Avalonia.Base/Styling/ITemplate.cs b/src/Avalonia.Base/Styling/ITemplate.cs
index 8a130cb3b4..d183d3ff74 100644
--- a/src/Avalonia.Base/Styling/ITemplate.cs
+++ b/src/Avalonia.Base/Styling/ITemplate.cs
@@ -2,6 +2,6 @@
{
public interface ITemplate
{
- object Build();
+ object? Build();
}
}
diff --git a/src/Avalonia.Controls/Carousel.cs b/src/Avalonia.Controls/Carousel.cs
index 84601e8690..1e0405dab4 100644
--- a/src/Avalonia.Controls/Carousel.cs
+++ b/src/Avalonia.Controls/Carousel.cs
@@ -1,7 +1,6 @@
using Avalonia.Animation;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
-using Avalonia.Controls.Utils;
namespace Avalonia.Controls
{
@@ -20,8 +19,8 @@ namespace Avalonia.Controls
/// The default value of for
/// .
///
- private static readonly ITemplate PanelTemplate =
- new FuncTemplate(() => new VirtualizingCarouselPanel());
+ private static readonly FuncTemplate DefaultPanel =
+ new(() => new VirtualizingCarouselPanel());
private IScrollable? _scroller;
@@ -31,7 +30,7 @@ namespace Avalonia.Controls
static Carousel()
{
SelectionModeProperty.OverrideDefaultValue(SelectionMode.AlwaysSelected);
- ItemsPanelProperty.OverrideDefaultValue(PanelTemplate);
+ ItemsPanelProperty.OverrideDefaultValue(DefaultPanel);
}
///
diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs
index f6e4b32d6b..1234b66383 100644
--- a/src/Avalonia.Controls/ComboBox.cs
+++ b/src/Avalonia.Controls/ComboBox.cs
@@ -1,13 +1,10 @@
using System;
-using System.Diagnostics;
using System.Linq;
using Avalonia.Automation.Peers;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
-using Avalonia.Controls.Selection;
using Avalonia.Controls.Shapes;
using Avalonia.Controls.Templates;
-using Avalonia.Controls.Utils;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Layout;
@@ -29,8 +26,8 @@ namespace Avalonia.Controls
///
/// The default value for the property.
///
- private static readonly FuncTemplate DefaultPanel =
- new FuncTemplate(() => new VirtualizingStackPanel());
+ private static readonly FuncTemplate DefaultPanel =
+ new(() => new VirtualizingStackPanel());
///
/// Defines the property.
diff --git a/src/Avalonia.Controls/ContextMenu.cs b/src/Avalonia.Controls/ContextMenu.cs
index f46594ff96..fc4b11bd4a 100644
--- a/src/Avalonia.Controls/ContextMenu.cs
+++ b/src/Avalonia.Controls/ContextMenu.cs
@@ -4,7 +4,6 @@ using System.ComponentModel;
using Avalonia.Automation.Peers;
using System.Linq;
using Avalonia.Controls.Diagnostics;
-using Avalonia.Controls.Generators;
using Avalonia.Controls.Platform;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Primitives.PopupPositioning;
@@ -84,8 +83,8 @@ namespace Avalonia.Controls
public static readonly StyledProperty PlacementTargetProperty =
Popup.PlacementTargetProperty.AddOwner();
- private static readonly ITemplate DefaultPanel =
- new FuncTemplate(() => new StackPanel { Orientation = Orientation.Vertical });
+ private static readonly FuncTemplate DefaultPanel =
+ new(() => new StackPanel { Orientation = Orientation.Vertical });
private Popup? _popup;
private List? _attachedControls;
private IInputElement? _previousFocus;
diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs
index 4460ff0486..1123f42afa 100644
--- a/src/Avalonia.Controls/ItemsControl.cs
+++ b/src/Avalonia.Controls/ItemsControl.cs
@@ -2,9 +2,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
-using System.Diagnostics.CodeAnalysis;
using Avalonia.Automation.Peers;
-using Avalonia.Collections;
using Avalonia.Controls.Generators;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Presenters;
@@ -29,8 +27,8 @@ namespace Avalonia.Controls
///
/// The default value for the property.
///
- private static readonly FuncTemplate DefaultPanel =
- new FuncTemplate(() => new StackPanel());
+ private static readonly FuncTemplate DefaultPanel =
+ new(() => new StackPanel());
///
/// Defines the property.
@@ -58,8 +56,8 @@ namespace Avalonia.Controls
///
/// Defines the property.
///
- public static readonly StyledProperty> ItemsPanelProperty =
- AvaloniaProperty.Register>(nameof(ItemsPanel), DefaultPanel);
+ public static readonly StyledProperty> ItemsPanelProperty =
+ AvaloniaProperty.Register>(nameof(ItemsPanel), DefaultPanel);
///
/// Defines the property.
@@ -202,7 +200,7 @@ namespace Avalonia.Controls
///
/// Gets or sets the panel used to display the items.
///
- public ITemplate ItemsPanel
+ public ITemplate ItemsPanel
{
get => GetValue(ItemsPanelProperty);
set => SetValue(ItemsPanelProperty, value);
diff --git a/src/Avalonia.Controls/ListBox.cs b/src/Avalonia.Controls/ListBox.cs
index 80d1677c2f..e665c2db90 100644
--- a/src/Avalonia.Controls/ListBox.cs
+++ b/src/Avalonia.Controls/ListBox.cs
@@ -1,13 +1,10 @@
using System.Collections;
-using Avalonia.Controls.Generators;
using Avalonia.Controls.Metadata;
-using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Selection;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Input.Platform;
-using Avalonia.VisualTree;
namespace Avalonia.Controls
{
@@ -20,8 +17,8 @@ namespace Avalonia.Controls
///
/// The default value for the property.
///
- private static readonly FuncTemplate DefaultPanel =
- new FuncTemplate(() => new VirtualizingStackPanel());
+ private static readonly FuncTemplate DefaultPanel =
+ new(() => new VirtualizingStackPanel());
///
/// Defines the property.
diff --git a/src/Avalonia.Controls/Menu.cs b/src/Avalonia.Controls/Menu.cs
index dbdcad8217..ac0262c9b2 100644
--- a/src/Avalonia.Controls/Menu.cs
+++ b/src/Avalonia.Controls/Menu.cs
@@ -1,7 +1,6 @@
using Avalonia.Automation;
using Avalonia.Automation.Peers;
using Avalonia.Controls.Platform;
-using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Interactivity;
@@ -14,9 +13,8 @@ namespace Avalonia.Controls
///
public class Menu : MenuBase, IMainMenu
{
- private static readonly ITemplate DefaultPanel =
- new FuncTemplate(() => new StackPanel { Orientation = Orientation.Horizontal });
-
+ private static readonly FuncTemplate DefaultPanel =
+ new (() => new StackPanel { Orientation = Orientation.Horizontal });
///
/// Initializes a new instance of the class.
diff --git a/src/Avalonia.Controls/MenuItem.cs b/src/Avalonia.Controls/MenuItem.cs
index 03e3444d71..06d84e715d 100644
--- a/src/Avalonia.Controls/MenuItem.cs
+++ b/src/Avalonia.Controls/MenuItem.cs
@@ -4,7 +4,6 @@ using System.Linq;
using Avalonia.Reactive;
using System.Windows.Input;
using Avalonia.Automation.Peers;
-using Avalonia.Controls.Generators;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Mixins;
using Avalonia.Controls.Primitives;
@@ -107,8 +106,8 @@ namespace Avalonia.Controls
///
/// The default value for the property.
///
- private static readonly ITemplate DefaultPanel =
- new FuncTemplate(() => new StackPanel());
+ private static readonly FuncTemplate DefaultPanel =
+ new(() => new StackPanel());
private bool _commandCanExecute = true;
private bool _commandBindingError;
diff --git a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs
index a0020a0b6e..88d1e10ba4 100644
--- a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs
+++ b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs
@@ -16,7 +16,7 @@ namespace Avalonia.Controls.Presenters
///
/// Defines the property.
///
- public static readonly StyledProperty> ItemsPanelProperty =
+ public static readonly StyledProperty> ItemsPanelProperty =
ItemsControl.ItemsPanelProperty.AddOwner();
private PanelContainerGenerator? _generator;
@@ -68,7 +68,7 @@ namespace Avalonia.Controls.Presenters
///
/// Gets or sets a template which creates the used to display the items.
///
- public ITemplate ItemsPanel
+ public ITemplate ItemsPanel
{
get => GetValue(ItemsPanelProperty);
set => SetValue(ItemsPanelProperty, value);
@@ -166,6 +166,12 @@ namespace Avalonia.Controls.Presenters
}
Panel = ItemsPanel.Build();
+
+ if (Panel is null)
+ {
+ return;
+ }
+
Panel.TemplatedParent = TemplatedParent;
Panel.IsItemsHost = true;
_scrollSnapPointsInfo = Panel as IScrollSnapPointsInfo;
@@ -183,7 +189,7 @@ namespace Avalonia.Controls.Presenters
else
CreateSimplePanelGenerator();
- if(Panel is IScrollSnapPointsInfo scrollSnapPointsInfo)
+ if (Panel is IScrollSnapPointsInfo scrollSnapPointsInfo)
{
scrollSnapPointsInfo.VerticalSnapPointsChanged += (s, e) =>
{
diff --git a/src/Avalonia.Controls/Primitives/TabStrip.cs b/src/Avalonia.Controls/Primitives/TabStrip.cs
index b8790d2a44..25cd1cd65b 100644
--- a/src/Avalonia.Controls/Primitives/TabStrip.cs
+++ b/src/Avalonia.Controls/Primitives/TabStrip.cs
@@ -1,15 +1,13 @@
-using Avalonia.Controls.Generators;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Layout;
-using Avalonia.VisualTree;
namespace Avalonia.Controls.Primitives
{
public class TabStrip : SelectingItemsControl
{
- private static readonly FuncTemplate DefaultPanel =
- new FuncTemplate(() => new WrapPanel { Orientation = Orientation.Horizontal });
+ private static readonly FuncTemplate DefaultPanel =
+ new(() => new WrapPanel { Orientation = Orientation.Horizontal });
static TabStrip()
{
diff --git a/src/Avalonia.Controls/Primitives/TemplatedControl.cs b/src/Avalonia.Controls/Primitives/TemplatedControl.cs
index e1cf25d89f..44d68fcf30 100644
--- a/src/Avalonia.Controls/Primitives/TemplatedControl.cs
+++ b/src/Avalonia.Controls/Primitives/TemplatedControl.cs
@@ -286,14 +286,17 @@ namespace Avalonia.Controls.Primitives
{
Logger.TryGet(LogEventLevel.Verbose, LogArea.Control)?.Log(this, "Creating control template");
- var (child, nameScope) = template.Build(this);
- ApplyTemplatedParent(child, this);
- ((ISetLogicalParent)child).SetParent(this);
- VisualChildren.Add(child);
-
- var e = new TemplateAppliedEventArgs(nameScope);
- OnApplyTemplate(e);
- RaiseEvent(e);
+ if (template.Build(this) is { } templateResult)
+ {
+ var (child, nameScope) = templateResult;
+ ApplyTemplatedParent(child, this);
+ ((ISetLogicalParent)child).SetParent(this);
+ VisualChildren.Add(child);
+
+ var e = new TemplateAppliedEventArgs(nameScope);
+ OnApplyTemplate(e);
+ RaiseEvent(e);
+ }
}
_appliedTemplate = template;
diff --git a/src/Avalonia.Controls/TabControl.cs b/src/Avalonia.Controls/TabControl.cs
index f12a66a4e6..74cf54beb8 100644
--- a/src/Avalonia.Controls/TabControl.cs
+++ b/src/Avalonia.Controls/TabControl.cs
@@ -1,8 +1,6 @@
-using System.ComponentModel;
using System.Linq;
using Avalonia.Collections;
using Avalonia.Automation.Peers;
-using Avalonia.Controls.Generators;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
@@ -12,7 +10,6 @@ using Avalonia.LogicalTree;
using Avalonia.VisualTree;
using Avalonia.Automation;
using Avalonia.Controls.Metadata;
-using Avalonia.Data;
namespace Avalonia.Controls
{
@@ -61,8 +58,8 @@ namespace Avalonia.Controls
///
/// The default value for the property.
///
- private static readonly FuncTemplate DefaultPanel =
- new FuncTemplate(() => new WrapPanel());
+ private static readonly FuncTemplate DefaultPanel =
+ new(() => new WrapPanel());
///
/// Initializes static members of the class.
diff --git a/src/Avalonia.Controls/Templates/FuncTemplate`1.cs b/src/Avalonia.Controls/Templates/FuncTemplate`1.cs
index 61da607a38..aa8fa43be9 100644
--- a/src/Avalonia.Controls/Templates/FuncTemplate`1.cs
+++ b/src/Avalonia.Controls/Templates/FuncTemplate`1.cs
@@ -7,7 +7,7 @@ namespace Avalonia.Controls.Templates
/// Creates a control from a .
///
/// The type of control.
- public class FuncTemplate : ITemplate where TControl : Control
+ public class FuncTemplate : ITemplate where TControl : Control?
{
private readonly Func _func;
@@ -31,6 +31,6 @@ namespace Avalonia.Controls.Templates
return _func();
}
- object ITemplate.Build() => Build();
+ object? ITemplate.Build() => Build();
}
}
diff --git a/src/Avalonia.Controls/Templates/IControlTemplate.cs b/src/Avalonia.Controls/Templates/IControlTemplate.cs
index 67e861f6ab..38ad6561ab 100644
--- a/src/Avalonia.Controls/Templates/IControlTemplate.cs
+++ b/src/Avalonia.Controls/Templates/IControlTemplate.cs
@@ -1,13 +1,11 @@
-using System;
using Avalonia.Controls.Primitives;
-using Avalonia.Styling;
namespace Avalonia.Controls.Templates
{
///
/// Interface representing a template used to build a .
///
- public interface IControlTemplate : ITemplate
+ public interface IControlTemplate : ITemplate
{
}
diff --git a/src/Avalonia.Controls/TreeViewItem.cs b/src/Avalonia.Controls/TreeViewItem.cs
index 3ac157f727..cf83ba8253 100644
--- a/src/Avalonia.Controls/TreeViewItem.cs
+++ b/src/Avalonia.Controls/TreeViewItem.cs
@@ -40,8 +40,8 @@ namespace Avalonia.Controls
AvaloniaProperty.RegisterDirect(
nameof(Level), o => o.Level);
- private static readonly ITemplate DefaultPanel =
- new FuncTemplate(() => new StackPanel());
+ private static readonly FuncTemplate DefaultPanel =
+ new(() => new StackPanel());
private TreeView? _treeView;
private Control? _header;
diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
index da739c754c..05e937fc05 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
+++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
@@ -58,7 +58,6 @@
-
@@ -69,6 +68,7 @@
+
diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
index 0b6a2c522f..834fa84b53 100644
--- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
@@ -1,8 +1,7 @@
using System;
using System.Diagnostics.CodeAnalysis;
-using System.IO;
using Avalonia.Platform;
-#nullable enable
+
namespace Avalonia.Markup.Xaml
{
///
@@ -79,7 +78,7 @@ namespace Avalonia.Markup.Xaml
var compiledLoader = assetLocator.GetAssembly(uri, baseUri)
?.GetType("CompiledAvaloniaXaml.!XamlLoader")
- ?.GetMethod("TryLoad", new[] { typeof(System.IServiceProvider), typeof(string) });
+ ?.GetMethod("TryLoad", new[] { typeof(IServiceProvider), typeof(string) });
if (compiledLoader != null)
{
var compiledResult = compiledLoader.Invoke(null, new object?[] { sp, absoluteUri.ToString()});
diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs
index 5b660af887..0a5ecebe5d 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs
@@ -14,18 +14,20 @@ namespace Avalonia.Markup.Xaml.Converters
[RequiresUnreferencedCode(TrimmingMessages.XamlTypeResolvedRequiresUnreferenceCodeMessage)]
public class AvaloniaPropertyTypeConverter : TypeConverter
{
- public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
+ ///
+ public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{
return sourceType == typeof(string);
}
- public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ ///
+ public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
var registry = AvaloniaPropertyRegistry.Instance;
var (ns, owner, propertyName) = PropertyParser.Parse(new CharacterReader(((string)value).AsSpan()));
var ownerType = TryResolveOwnerByName(context, ns, owner);
- var targetType = context.GetFirstParent()?.TargetType ??
- context.GetFirstParent