diff --git a/Avalonia.sln b/Avalonia.sln
index 4999719676..35b6b2108a 100644
--- a/Avalonia.sln
+++ b/Avalonia.sln
@@ -13,7 +13,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Direct2D1", "src\W
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls", "src\Avalonia.Controls\Avalonia.Controls.csproj", "{D2221C82-4A25-4583-9B43-D791E3F6820C}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Themes.Default", "src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj", "{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Themes.Simple", "src\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj", "{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Diagnostics", "src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj", "{7062AE20-5DCC-4442-9645-8195BDECE63E}"
EndProject
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index edf3c3d819..52fc8db53c 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -59,7 +59,7 @@ jobs:
variables:
SolutionDir: '$(Build.SourcesDirectory)'
pool:
- vmImage: 'macOS-10.15'
+ vmImage: 'macos-12'
steps:
- task: UseDotNet@2
displayName: 'Use .NET Core SDK 3.1.418'
@@ -91,10 +91,10 @@ jobs:
inputs:
actions: 'build'
scheme: ''
- sdk: 'macosx11.1'
+ sdk: 'macosx12.3'
configuration: 'Release'
xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
- xcodeVersion: '12' # Options: 8, 9, default, specifyPath
+ xcodeVersion: '13' # Options: 8, 9, default, specifyPath
args: '-derivedDataPath ./'
- task: CmdLine@2
diff --git a/samples/BindingDemo/App.xaml b/samples/BindingDemo/App.xaml
index 3e312c8685..175e838616 100644
--- a/samples/BindingDemo/App.xaml
+++ b/samples/BindingDemo/App.xaml
@@ -4,6 +4,6 @@
x:Class="BindingDemo.App">
-
+
diff --git a/samples/ControlCatalog/App.xaml.cs b/samples/ControlCatalog/App.xaml.cs
index 7ebb87094a..750c1082a6 100644
--- a/samples/ControlCatalog/App.xaml.cs
+++ b/samples/ControlCatalog/App.xaml.cs
@@ -5,7 +5,7 @@ using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Markup.Xaml.Styling;
using Avalonia.Styling;
-using Avalonia.Themes.Default;
+using Avalonia.Themes.Simple;
using Avalonia.Themes.Fluent;
using ControlCatalog.ViewModels;
@@ -23,9 +23,9 @@ namespace ControlCatalog
Source = new Uri("avares://Avalonia.Controls.ColorPicker/Themes/Fluent/Fluent.xaml")
};
- public static readonly StyleInclude ColorPickerDefault = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
+ public static readonly StyleInclude ColorPickerSimple = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
{
- Source = new Uri("avares://Avalonia.Controls.ColorPicker/Themes/Default/Default.xaml")
+ Source = new Uri("avares://Avalonia.Controls.ColorPicker/Themes/Simple/Simple.xaml")
};
public static readonly StyleInclude DataGridFluent = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
@@ -33,16 +33,16 @@ namespace ControlCatalog
Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml")
};
- public static readonly StyleInclude DataGridDefault = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
+ public static readonly StyleInclude DataGridSimple = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
{
- Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Default.xaml")
+ Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Simple.xaml")
};
public static FluentTheme Fluent = new FluentTheme(new Uri("avares://ControlCatalog/Styles"));
- public static SimpleTheme Default = new SimpleTheme(new Uri("avares://ControlCatalog/Styles"));
+ public static SimpleTheme Simple = new SimpleTheme(new Uri("avares://ControlCatalog/Styles"));
- public static Styles DefaultLight = new Styles
+ public static Styles SimpleLight = new Styles
{
new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
{
@@ -56,10 +56,10 @@ namespace ControlCatalog
{
Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseLight.xaml")
},
- Default
+ Simple
};
- public static Styles DefaultDark = new Styles
+ public static Styles SimpleDark = new Styles
{
new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
{
@@ -73,7 +73,7 @@ namespace ControlCatalog
{
Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseDark.xaml")
},
- Default
+ Simple
};
public override void Initialize()
diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj
index 8358fb3cd4..2654574a3e 100644
--- a/samples/ControlCatalog/ControlCatalog.csproj
+++ b/samples/ControlCatalog/ControlCatalog.csproj
@@ -29,7 +29,7 @@
-
+
diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml
index 7461e78c33..7f5a191519 100644
--- a/samples/ControlCatalog/MainView.xaml
+++ b/samples/ControlCatalog/MainView.xaml
@@ -187,8 +187,8 @@
FluentLight
FluentDark
- DefaultLight
- DefaultDark
+ SimpleLight
+ SimpleDark
? items)
{
items ??= Array.Empty();
- var mappedResults = items.Select(FullPathOrName).ToList();
- bookmarkContainer.Text = items.FirstOrDefault(f => f.CanBookmark) is { } f ? await f.SaveBookmark() : "Can't bookmark";
+ bookmarkContainer.Text = items.FirstOrDefault(f => f.CanBookmark) is { } f ? await f.SaveBookmarkAsync() : "Can't bookmark";
+ var mappedResults = new List();
if (items.FirstOrDefault() is IStorageItem item)
{
@@ -267,9 +267,9 @@ Content:
if (file.CanOpenRead)
{
#if NET6_0_OR_GREATER
- await using var stream = await file.OpenRead();
+ await using var stream = await file.OpenReadAsync();
#else
- using var stream = await file.OpenRead();
+ using var stream = await file.OpenReadAsync();
#endif
using var reader = new System.IO.StreamReader(stream);
@@ -293,7 +293,19 @@ Content:
lastSelectedDirectory = await item.GetParentAsync();
if (lastSelectedDirectory is not null)
{
- mappedResults.Insert(0, "Parent: " + FullPathOrName(lastSelectedDirectory));
+ mappedResults.Add(FullPathOrName(lastSelectedDirectory));
+ }
+
+ foreach (var selectedItem in items)
+ {
+ mappedResults.Add("+> " + FullPathOrName(selectedItem));
+ if (selectedItem is IStorageFolder folder)
+ {
+ foreach (var innerItems in await folder.GetItemsAsync())
+ {
+ mappedResults.Add("++> " + FullPathOrName(innerItems));
+ }
+ }
}
}
diff --git a/samples/PlatformSanityChecks/App.xaml b/samples/PlatformSanityChecks/App.xaml
index 25bab6ae35..1b9d64fca6 100644
--- a/samples/PlatformSanityChecks/App.xaml
+++ b/samples/PlatformSanityChecks/App.xaml
@@ -1,6 +1,5 @@
-
-
+
diff --git a/samples/PlatformSanityChecks/PlatformSanityChecks.csproj b/samples/PlatformSanityChecks/PlatformSanityChecks.csproj
index 4f7f06b529..5c743aabdb 100644
--- a/samples/PlatformSanityChecks/PlatformSanityChecks.csproj
+++ b/samples/PlatformSanityChecks/PlatformSanityChecks.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/samples/Previewer/App.xaml b/samples/Previewer/App.xaml
index 6bae1955af..1b9d64fca6 100644
--- a/samples/Previewer/App.xaml
+++ b/samples/Previewer/App.xaml
@@ -1,6 +1,5 @@
-
-
+
-
\ No newline at end of file
+
diff --git a/samples/Previewer/Previewer.csproj b/samples/Previewer/Previewer.csproj
index 98560e9ab0..2cc84168dc 100644
--- a/samples/Previewer/Previewer.csproj
+++ b/samples/Previewer/Previewer.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/samples/RenderDemo/Pages/CustomSkiaPage.cs b/samples/RenderDemo/Pages/CustomSkiaPage.cs
index 9c524a7932..bf27747154 100644
--- a/samples/RenderDemo/Pages/CustomSkiaPage.cs
+++ b/samples/RenderDemo/Pages/CustomSkiaPage.cs
@@ -40,14 +40,16 @@ namespace RenderDemo.Pages
static Stopwatch St = Stopwatch.StartNew();
public void Render(IDrawingContextImpl context)
{
- var canvas = (context as ISkiaDrawingContextImpl)?.SkCanvas;
- if (canvas == null)
+ var leaseFeature = context.GetFeature();
+ if (leaseFeature == null)
using (var c = new DrawingContext(context, false))
{
c.DrawText(_noSkia, new Point());
}
else
{
+ using var lease = leaseFeature.Lease();
+ var canvas = lease.SkCanvas;
canvas.Save();
// create the first shader
var colors = new SKColor[] {
diff --git a/samples/VirtualizationDemo/App.xaml b/samples/VirtualizationDemo/App.xaml
index 3ad1dce794..eb5f0e4dca 100644
--- a/samples/VirtualizationDemo/App.xaml
+++ b/samples/VirtualizationDemo/App.xaml
@@ -1,9 +1,7 @@
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
diff --git a/samples/VirtualizationDemo/VirtualizationDemo.csproj b/samples/VirtualizationDemo/VirtualizationDemo.csproj
index bd6054327f..b27cfe77e8 100644
--- a/samples/VirtualizationDemo/VirtualizationDemo.csproj
+++ b/samples/VirtualizationDemo/VirtualizationDemo.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/samples/interop/Direct3DInteropSample/App.paml b/samples/interop/Direct3DInteropSample/App.paml
index d9630eef58..e6d77dfaf4 100644
--- a/samples/interop/Direct3DInteropSample/App.paml
+++ b/samples/interop/Direct3DInteropSample/App.paml
@@ -1,6 +1,5 @@
-
-
+
-
\ No newline at end of file
+
diff --git a/samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj b/samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
index 81b94b4d09..f9ef4693d5 100644
--- a/samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
+++ b/samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
@@ -22,7 +22,7 @@
-
+
diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs
index 0c72c389dc..ed5b46d398 100644
--- a/src/Android/Avalonia.Android/AndroidPlatform.cs
+++ b/src/Android/Avalonia.Android/AndroidPlatform.cs
@@ -8,7 +8,8 @@ using Avalonia.Input.Platform;
using Avalonia.OpenGL.Egl;
using Avalonia.Platform;
using Avalonia.Rendering;
-using Avalonia.Skia;
+using Avalonia.Rendering.Composition;
+using Avalonia.OpenGL;
namespace Avalonia
{
@@ -16,10 +17,8 @@ namespace Avalonia
{
public static T UseAndroid(this T builder) where T : AppBuilderBase, new()
{
- var options = AvaloniaLocator.Current.GetService() ?? new AndroidPlatformOptions();
-
return builder
- .UseWindowingSubsystem(() => AndroidPlatform.Initialize(options), "Android")
+ .UseWindowingSubsystem(() => AndroidPlatform.Initialize(), "Android")
.UseSkia();
}
}
@@ -42,9 +41,11 @@ namespace Avalonia.Android
public TimeSpan DoubleClickTime => TimeSpan.FromMilliseconds(500);
- public static void Initialize(AndroidPlatformOptions options)
+ internal static Compositor Compositor { get; private set; }
+
+ public static void Initialize()
{
- Options = options;
+ Options = AvaloniaLocator.Current.GetService() ?? new AndroidPlatformOptions();
AvaloniaLocator.CurrentMutable
.Bind().ToTransient()
@@ -58,16 +59,24 @@ namespace Avalonia.Android
.Bind().ToConstant(new RenderLoop())
.Bind().ToSingleton();
- if (options.UseGpu)
+ if (Options.UseGpu)
{
EglPlatformOpenGlInterface.TryInitialize();
}
+
+ if (Options.UseCompositor)
+ {
+ Compositor = new Compositor(
+ AvaloniaLocator.Current.GetRequiredService(),
+ AvaloniaLocator.Current.GetService());
+ }
}
}
public sealed class AndroidPlatformOptions
{
- public bool UseDeferredRendering { get; set; } = true;
+ public bool UseDeferredRendering { get; set; } = false;
public bool UseGpu { get; set; } = true;
+ public bool UseCompositor { get; set; } = true;
}
}
diff --git a/src/Android/Avalonia.Android/AndroidThreadingInterface.cs b/src/Android/Avalonia.Android/AndroidThreadingInterface.cs
index e72f0aed90..42f75a27e1 100644
--- a/src/Android/Avalonia.Android/AndroidThreadingInterface.cs
+++ b/src/Android/Avalonia.Android/AndroidThreadingInterface.cs
@@ -14,6 +14,7 @@ namespace Avalonia.Android
internal sealed class AndroidThreadingInterface : IPlatformThreadingInterface
{
private Handler _handler;
+ private static Thread s_uiThread;
public AndroidThreadingInterface()
{
@@ -76,7 +77,25 @@ namespace Avalonia.Android
EnsureInvokeOnMainThread(() => Signaled?.Invoke(null));
}
- public bool CurrentThreadIsLoopThread => Looper.MainLooper.Thread.Equals(Java.Lang.Thread.CurrentThread());
+ public bool CurrentThreadIsLoopThread
+ {
+ get
+ {
+ if (s_uiThread != null)
+ return s_uiThread == Thread.CurrentThread;
+
+ var isOnMainThread = OperatingSystem.IsAndroidVersionAtLeast(23)
+ ? Looper.MainLooper.IsCurrentThread
+ : Looper.MainLooper.Thread.Equals(Java.Lang.Thread.CurrentThread());
+ if (isOnMainThread)
+ {
+ s_uiThread = Thread.CurrentThread;
+ return true;
+ }
+
+ return false;
+ }
+ }
public event Action Signaled;
}
}
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
index fd97e293f9..dc74214170 100644
--- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
+++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
@@ -19,6 +19,7 @@ using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform;
using Avalonia.Platform.Storage;
using Avalonia.Rendering;
+using Avalonia.Rendering.Composition;
namespace Avalonia.Android.Platform.SkiaPlatform
{
@@ -84,9 +85,11 @@ namespace Avalonia.Android.Platform.SkiaPlatform
public IEnumerable
diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml
index c32638f6ca..1270dbaa62 100644
--- a/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml
+++ b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml
@@ -2,19 +2,16 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:Avalonia.Diagnostics.Views"
xmlns:diag="clr-namespace:Avalonia.Diagnostics"
- xmlns:default="using:Avalonia.Themes.Default"
Title="Avalonia DevTools"
- x:Class="Avalonia.Diagnostics.Views.MainWindow">
+ x:Class="Avalonia.Diagnostics.Views.MainWindow"
+ Theme="{StaticResource {x:Type Window}}">
-
-
-
+
+
diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs
index 96dc929434..c81997f2cb 100644
--- a/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs
+++ b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs
@@ -11,7 +11,7 @@ using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Markup.Xaml;
using Avalonia.Styling;
-using Avalonia.Themes.Default;
+using Avalonia.Themes.Simple;
using Avalonia.VisualTree;
namespace Avalonia.Diagnostics.Views
diff --git a/src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs b/src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
index 5576368240..cb23c6c336 100644
--- a/src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
+++ b/src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
@@ -416,6 +416,11 @@ namespace Avalonia.Headless
}
+ public object GetFeature(Type t)
+ {
+ return null;
+ }
+
public void DrawLine(IPen pen, Point p1, Point p2)
{
}
diff --git a/src/Avalonia.OpenGL/Controls/OpenGlControlBase.cs b/src/Avalonia.OpenGL/Controls/OpenGlControlBase.cs
index 68442c1fd3..7b65cfb595 100644
--- a/src/Avalonia.OpenGL/Controls/OpenGlControlBase.cs
+++ b/src/Avalonia.OpenGL/Controls/OpenGlControlBase.cs
@@ -146,6 +146,13 @@ namespace Avalonia.OpenGL.Controls
return false;
}
+ if (_context == null)
+ {
+ Logger.TryGet(LogEventLevel.Error, "OpenGL")?.Log("OpenGlControlBase",
+ "Unable to initialize OpenGL: unable to create additional OpenGL context.");
+ return false;
+ }
+
GlVersion = _context.Version;
try
{
diff --git a/src/Avalonia.ReactiveUI/RoutedViewHost.cs b/src/Avalonia.ReactiveUI/RoutedViewHost.cs
index 9269dc70f8..775014d419 100644
--- a/src/Avalonia.ReactiveUI/RoutedViewHost.cs
+++ b/src/Avalonia.ReactiveUI/RoutedViewHost.cs
@@ -64,6 +64,12 @@ namespace Avalonia.ReactiveUI
public static readonly StyledProperty ViewContractProperty =
AvaloniaProperty.Register(nameof(ViewContract));
+ ///
+ /// for the property.
+ ///
+ public static readonly StyledProperty DefaultContentProperty =
+ ViewModelViewHost.DefaultContentProperty.AddOwner();
+
///
/// Initializes a new instance of the class.
///
@@ -106,6 +112,15 @@ namespace Avalonia.ReactiveUI
set => SetValue(ViewContractProperty, value);
}
+ ///
+ /// Gets or sets the content displayed whenever there is no page currently routed.
+ ///
+ public object? DefaultContent
+ {
+ get => GetValue(DefaultContentProperty);
+ set => SetValue(DefaultContentProperty, value);
+ }
+
///
/// Gets or sets the ReactiveUI view locator used by this router.
///
diff --git a/src/Avalonia.ReactiveUI/TransitioningContentControl.cs b/src/Avalonia.ReactiveUI/TransitioningContentControl.cs
deleted file mode 100644
index d26e90b2da..0000000000
--- a/src/Avalonia.ReactiveUI/TransitioningContentControl.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using System;
-using System.Threading;
-
-using Avalonia.Animation;
-using Avalonia.Controls;
-using Avalonia.Styling;
-
-namespace Avalonia.ReactiveUI
-{
- ///
- /// A ContentControl that animates the transition when its content is changed.
- ///
- [Obsolete("Use TransitioningContentControl in Avalonia.Controls namespace")]
- public class TransitioningContentControl : ContentControl, IStyleable
- {
- ///
- /// for the property.
- ///
- public static readonly StyledProperty PageTransitionProperty =
- AvaloniaProperty.Register(nameof(PageTransition),
- new CrossFade(TimeSpan.FromSeconds(0.5)));
-
- ///
- /// for the property.
- ///
- public static readonly StyledProperty DefaultContentProperty =
- AvaloniaProperty.Register(nameof(DefaultContent));
-
- private CancellationTokenSource? _lastTransitionCts;
-
- ///
- /// Gets or sets the animation played when content appears and disappears.
- ///
- public IPageTransition? PageTransition
- {
- get => GetValue(PageTransitionProperty);
- set => SetValue(PageTransitionProperty, value);
- }
-
- ///
- /// Gets or sets the content displayed whenever there is no page currently routed.
- ///
- public object? DefaultContent
- {
- get => GetValue(DefaultContentProperty);
- set => SetValue(DefaultContentProperty, value);
- }
-
- ///
- /// Gets or sets the content with animation.
- ///
- public new object? Content
- {
- get => base.Content;
- set => UpdateContentWithTransition(value);
- }
-
- ///
- /// TransitioningContentControl uses the default ContentControl
- /// template from Avalonia default theme.
- ///
- Type IStyleable.StyleKey => typeof(ContentControl);
-
- ///
- /// Updates the content with transitions.
- ///
- /// New content to set.
- private async void UpdateContentWithTransition(object? content)
- {
- _lastTransitionCts?.Cancel();
- _lastTransitionCts = new CancellationTokenSource();
-
- if (PageTransition != null)
- await PageTransition.Start(this, null, true, _lastTransitionCts.Token);
- base.Content = content;
- if (PageTransition != null)
- await PageTransition.Start(null, this, true, _lastTransitionCts.Token);
- }
- }
-}
diff --git a/src/Avalonia.ReactiveUI/ViewModelViewHost.cs b/src/Avalonia.ReactiveUI/ViewModelViewHost.cs
index 16dee00ebc..869238b377 100644
--- a/src/Avalonia.ReactiveUI/ViewModelViewHost.cs
+++ b/src/Avalonia.ReactiveUI/ViewModelViewHost.cs
@@ -1,5 +1,8 @@
using System;
using System.Reactive.Disposables;
+
+using Avalonia.Controls;
+
using ReactiveUI;
using Splat;
@@ -24,6 +27,12 @@ namespace Avalonia.ReactiveUI
public static readonly StyledProperty ViewContractProperty =
AvaloniaProperty.Register(nameof(ViewContract));
+ ///
+ /// for the property.
+ ///
+ public static readonly StyledProperty DefaultContentProperty =
+ AvaloniaProperty.Register(nameof(DefaultContent));
+
///
/// Initializes a new instance of the class.
///
@@ -55,6 +64,15 @@ namespace Avalonia.ReactiveUI
set => SetValue(ViewContractProperty, value);
}
+ ///
+ /// Gets or sets the content displayed whenever there is no page currently routed.
+ ///
+ public object? DefaultContent
+ {
+ get => GetValue(DefaultContentProperty);
+ set => SetValue(DefaultContentProperty, value);
+ }
+
///
/// Gets or sets the view locator.
///
diff --git a/src/Avalonia.Themes.Default/Controls/ButtonSpinner.xaml b/src/Avalonia.Themes.Default/Controls/ButtonSpinner.xaml
deleted file mode 100644
index 561ca8bedd..0000000000
--- a/src/Avalonia.Themes.Default/Controls/ButtonSpinner.xaml
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/CalendarButton.xaml b/src/Avalonia.Themes.Default/Controls/CalendarButton.xaml
deleted file mode 100644
index 3314534b3b..0000000000
--- a/src/Avalonia.Themes.Default/Controls/CalendarButton.xaml
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/CalendarDayButton.xaml b/src/Avalonia.Themes.Default/Controls/CalendarDayButton.xaml
deleted file mode 100644
index 2d79e62a75..0000000000
--- a/src/Avalonia.Themes.Default/Controls/CalendarDayButton.xaml
+++ /dev/null
@@ -1,116 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/CaptionButtons.xaml b/src/Avalonia.Themes.Default/Controls/CaptionButtons.xaml
deleted file mode 100644
index be6642467f..0000000000
--- a/src/Avalonia.Themes.Default/Controls/CaptionButtons.xaml
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/Carousel.xaml b/src/Avalonia.Themes.Default/Controls/Carousel.xaml
deleted file mode 100644
index baba0649aa..0000000000
--- a/src/Avalonia.Themes.Default/Controls/Carousel.xaml
+++ /dev/null
@@ -1,17 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/ComboBoxItem.xaml b/src/Avalonia.Themes.Default/Controls/ComboBoxItem.xaml
deleted file mode 100644
index a694143bec..0000000000
--- a/src/Avalonia.Themes.Default/Controls/ComboBoxItem.xaml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/ContentControl.xaml b/src/Avalonia.Themes.Default/Controls/ContentControl.xaml
deleted file mode 100644
index d32bc399b6..0000000000
--- a/src/Avalonia.Themes.Default/Controls/ContentControl.xaml
+++ /dev/null
@@ -1,16 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/ContextMenu.xaml b/src/Avalonia.Themes.Default/Controls/ContextMenu.xaml
deleted file mode 100644
index 987b72aaa2..0000000000
--- a/src/Avalonia.Themes.Default/Controls/ContextMenu.xaml
+++ /dev/null
@@ -1,25 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/DataValidationErrors.xaml b/src/Avalonia.Themes.Default/Controls/DataValidationErrors.xaml
deleted file mode 100644
index d7bf4bbbf1..0000000000
--- a/src/Avalonia.Themes.Default/Controls/DataValidationErrors.xaml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/DatePicker.xaml b/src/Avalonia.Themes.Default/Controls/DatePicker.xaml
deleted file mode 100644
index c1ee941416..0000000000
--- a/src/Avalonia.Themes.Default/Controls/DatePicker.xaml
+++ /dev/null
@@ -1,337 +0,0 @@
-
-
-
-
- 0,0,0,4
- 40
- 40
- 41
- 296
- 456
- 0,3,0,6
- 9,3,0,6
- 0,3,0,6
- 9,3,0,6
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/EmbeddableControlRoot.xaml b/src/Avalonia.Themes.Default/Controls/EmbeddableControlRoot.xaml
deleted file mode 100644
index 9ffe51fae8..0000000000
--- a/src/Avalonia.Themes.Default/Controls/EmbeddableControlRoot.xaml
+++ /dev/null
@@ -1,19 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/Expander.xaml b/src/Avalonia.Themes.Default/Controls/Expander.xaml
deleted file mode 100644
index 2f18faf84a..0000000000
--- a/src/Avalonia.Themes.Default/Controls/Expander.xaml
+++ /dev/null
@@ -1,196 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- Expanded content
-
-
-
-
- Expanded content
-
-
-
-
- Expanded content
-
-
-
-
- Expanded content
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/FocusAdorner.xaml b/src/Avalonia.Themes.Default/Controls/FocusAdorner.xaml
deleted file mode 100644
index 2d5e369573..0000000000
--- a/src/Avalonia.Themes.Default/Controls/FocusAdorner.xaml
+++ /dev/null
@@ -1,10 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/GridSplitter.xaml b/src/Avalonia.Themes.Default/Controls/GridSplitter.xaml
deleted file mode 100644
index 490ae01318..0000000000
--- a/src/Avalonia.Themes.Default/Controls/GridSplitter.xaml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/ItemsControl.xaml b/src/Avalonia.Themes.Default/Controls/ItemsControl.xaml
deleted file mode 100644
index 19d13b6399..0000000000
--- a/src/Avalonia.Themes.Default/Controls/ItemsControl.xaml
+++ /dev/null
@@ -1,16 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/Label.xaml b/src/Avalonia.Themes.Default/Controls/Label.xaml
deleted file mode 100644
index 1e04d05497..0000000000
--- a/src/Avalonia.Themes.Default/Controls/Label.xaml
+++ /dev/null
@@ -1,18 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/ListBox.xaml b/src/Avalonia.Themes.Default/Controls/ListBox.xaml
deleted file mode 100644
index b1fcb830b3..0000000000
--- a/src/Avalonia.Themes.Default/Controls/ListBox.xaml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/ListBoxItem.xaml b/src/Avalonia.Themes.Default/Controls/ListBoxItem.xaml
deleted file mode 100644
index c1360c5d98..0000000000
--- a/src/Avalonia.Themes.Default/Controls/ListBoxItem.xaml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/ManagedFileChooser.xaml b/src/Avalonia.Themes.Default/Controls/ManagedFileChooser.xaml
deleted file mode 100644
index f9f77bf455..0000000000
--- a/src/Avalonia.Themes.Default/Controls/ManagedFileChooser.xaml
+++ /dev/null
@@ -1,153 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Avalonia.Themes.Default/Controls/Menu.xaml b/src/Avalonia.Themes.Default/Controls/Menu.xaml
deleted file mode 100644
index 583add1017..0000000000
--- a/src/Avalonia.Themes.Default/Controls/Menu.xaml
+++ /dev/null
@@ -1,17 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/MenuItem.xaml b/src/Avalonia.Themes.Default/Controls/MenuItem.xaml
deleted file mode 100644
index 05c286c1f5..0000000000
--- a/src/Avalonia.Themes.Default/Controls/MenuItem.xaml
+++ /dev/null
@@ -1,150 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/NativeMenuBar.xaml b/src/Avalonia.Themes.Default/Controls/NativeMenuBar.xaml
deleted file mode 100644
index 3b0019eea1..0000000000
--- a/src/Avalonia.Themes.Default/Controls/NativeMenuBar.xaml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/NotificationCard.xaml b/src/Avalonia.Themes.Default/Controls/NotificationCard.xaml
deleted file mode 100644
index c411fede11..0000000000
--- a/src/Avalonia.Themes.Default/Controls/NotificationCard.xaml
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/OverlayPopupHost.xaml b/src/Avalonia.Themes.Default/Controls/OverlayPopupHost.xaml
deleted file mode 100644
index 07d905ea1d..0000000000
--- a/src/Avalonia.Themes.Default/Controls/OverlayPopupHost.xaml
+++ /dev/null
@@ -1,23 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/PathIcon.xaml b/src/Avalonia.Themes.Default/Controls/PathIcon.xaml
deleted file mode 100644
index 039f0ef10c..0000000000
--- a/src/Avalonia.Themes.Default/Controls/PathIcon.xaml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/PopupRoot.xaml b/src/Avalonia.Themes.Default/Controls/PopupRoot.xaml
deleted file mode 100644
index 5e8f3337ee..0000000000
--- a/src/Avalonia.Themes.Default/Controls/PopupRoot.xaml
+++ /dev/null
@@ -1,27 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/ProgressBar.xaml b/src/Avalonia.Themes.Default/Controls/ProgressBar.xaml
deleted file mode 100644
index 3f684f3936..0000000000
--- a/src/Avalonia.Themes.Default/Controls/ProgressBar.xaml
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/RadioButton.xaml b/src/Avalonia.Themes.Default/Controls/RadioButton.xaml
deleted file mode 100644
index ae33946009..0000000000
--- a/src/Avalonia.Themes.Default/Controls/RadioButton.xaml
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/RepeatButton.xaml b/src/Avalonia.Themes.Default/Controls/RepeatButton.xaml
deleted file mode 100644
index 47398966f7..0000000000
--- a/src/Avalonia.Themes.Default/Controls/RepeatButton.xaml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/RichTextBlock.xaml b/src/Avalonia.Themes.Default/Controls/RichTextBlock.xaml
deleted file mode 100644
index d7bf6e5cf9..0000000000
--- a/src/Avalonia.Themes.Default/Controls/RichTextBlock.xaml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/ScrollBar.xaml b/src/Avalonia.Themes.Default/Controls/ScrollBar.xaml
deleted file mode 100644
index 0f8fa4986d..0000000000
--- a/src/Avalonia.Themes.Default/Controls/ScrollBar.xaml
+++ /dev/null
@@ -1,142 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/Separator.xaml b/src/Avalonia.Themes.Default/Controls/Separator.xaml
deleted file mode 100644
index 6a318d2e85..0000000000
--- a/src/Avalonia.Themes.Default/Controls/Separator.xaml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/Slider.xaml b/src/Avalonia.Themes.Default/Controls/Slider.xaml
deleted file mode 100644
index bcb330f188..0000000000
--- a/src/Avalonia.Themes.Default/Controls/Slider.xaml
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/SplitButton.xaml b/src/Avalonia.Themes.Default/Controls/SplitButton.xaml
deleted file mode 100644
index 0c46ce3724..0000000000
--- a/src/Avalonia.Themes.Default/Controls/SplitButton.xaml
+++ /dev/null
@@ -1,275 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- 24
- 24
- 1
- 24
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/SplitView.xaml b/src/Avalonia.Themes.Default/Controls/SplitView.xaml
deleted file mode 100644
index 10eda2d9cd..0000000000
--- a/src/Avalonia.Themes.Default/Controls/SplitView.xaml
+++ /dev/null
@@ -1,234 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 320
- 48
-
- 00:00:00.2
- 00:00:00.1
- 0.1,0.9,0.2,1.0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/TabControl.xaml b/src/Avalonia.Themes.Default/Controls/TabControl.xaml
deleted file mode 100644
index afb5010baa..0000000000
--- a/src/Avalonia.Themes.Default/Controls/TabControl.xaml
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/TabItem.xaml b/src/Avalonia.Themes.Default/Controls/TabItem.xaml
deleted file mode 100644
index c7748299a0..0000000000
--- a/src/Avalonia.Themes.Default/Controls/TabItem.xaml
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/TextBox.xaml b/src/Avalonia.Themes.Default/Controls/TextBox.xaml
deleted file mode 100644
index 1885d3b65b..0000000000
--- a/src/Avalonia.Themes.Default/Controls/TextBox.xaml
+++ /dev/null
@@ -1,203 +0,0 @@
-
-
- M 11.416016,10 20,1.4160156 18.583984,0 10,8.5839846 1.4160156,0 0,1.4160156 8.5839844,10 0,18.583985 1.4160156,20 10,11.416015 18.583984,20 20,18.583985 Z
- m10.051 7.0032c2.215 0 4.0105 1.7901 4.0105 3.9984s-1.7956 3.9984-4.0105 3.9984c-2.215 0-4.0105-1.7901-4.0105-3.9984s1.7956-3.9984 4.0105-3.9984zm0 1.4994c-1.3844 0-2.5066 1.1188-2.5066 2.499s1.1222 2.499 2.5066 2.499 2.5066-1.1188 2.5066-2.499-1.1222-2.499-2.5066-2.499zm0-5.0026c4.6257 0 8.6188 3.1487 9.7267 7.5613 0.10085 0.40165-0.14399 0.80877-0.54686 0.90931-0.40288 0.10054-0.81122-0.14355-0.91208-0.54521-0.94136-3.7492-4.3361-6.4261-8.2678-6.4261-3.9334 0-7.3292 2.6792-8.2689 6.4306-0.10063 0.40171-0.50884 0.64603-0.91177 0.54571s-0.648-0.5073-0.54737-0.90901c1.106-4.4152 5.1003-7.5667 9.728-7.5667z
- m0.21967 0.21965c-0.26627 0.26627-0.29047 0.68293-0.07262 0.97654l0.07262 0.08412 4.0346 4.0346c-1.922 1.3495-3.3585 3.365-3.9554 5.7495-0.10058 0.4018 0.14362 0.8091 0.54543 0.9097 0.40182 0.1005 0.80909-0.1436 0.90968-0.5455 0.52947-2.1151 1.8371-3.8891 3.5802-5.0341l1.8096 1.8098c-0.70751 0.7215-1.1438 1.71-1.1438 2.8003 0 2.2092 1.7909 4 4 4 1.0904 0 2.0788-0.4363 2.8004-1.1438l5.9193 5.9195c0.2929 0.2929 0.7677 0.2929 1.0606 0 0.2663-0.2662 0.2905-0.6829 0.0726-0.9765l-0.0726-0.0841-6.1135-6.1142 0.0012-0.0015-1.2001-1.1979-2.8699-2.8693 2e-3 -8e-4 -2.8812-2.8782 0.0012-0.0018-1.1333-1.1305-4.3064-4.3058c-0.29289-0.29289-0.76777-0.29289-1.0607 0zm7.9844 9.0458 3.5351 3.5351c-0.45 0.4358-1.0633 0.704-1.7392 0.704-1.3807 0-2.5-1.1193-2.5-2.5 0-0.6759 0.26824-1.2892 0.7041-1.7391zm1.7959-5.7655c-1.0003 0-1.9709 0.14807-2.8889 0.425l1.237 1.2362c0.5358-0.10587 1.0883-0.16119 1.6519-0.16119 3.9231 0 7.3099 2.6803 8.2471 6.4332 0.1004 0.4018 0.5075 0.6462 0.9094 0.5459 0.4019-0.1004 0.6463-0.5075 0.5459-0.9094-1.103-4.417-5.0869-7.5697-9.7024-7.5697zm0.1947 3.5093 3.8013 3.8007c-0.1018-2.0569-1.7488-3.7024-3.8013-3.8007z
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/TimePicker.xaml b/src/Avalonia.Themes.Default/Controls/TimePicker.xaml
deleted file mode 100644
index 0a5147e335..0000000000
--- a/src/Avalonia.Themes.Default/Controls/TimePicker.xaml
+++ /dev/null
@@ -1,286 +0,0 @@
-
-
-
-
- 40
- 1
- 1
- 0,0,0,4
- 40
- 41
- 242
- 456
- 0,3,0,6
- 0,3,0,6
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/TitleBar.xaml b/src/Avalonia.Themes.Default/Controls/TitleBar.xaml
deleted file mode 100644
index 7f8ed24076..0000000000
--- a/src/Avalonia.Themes.Default/Controls/TitleBar.xaml
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/ToggleSwitch.xaml b/src/Avalonia.Themes.Default/Controls/ToggleSwitch.xaml
deleted file mode 100644
index 2c831cf360..0000000000
--- a/src/Avalonia.Themes.Default/Controls/ToggleSwitch.xaml
+++ /dev/null
@@ -1,322 +0,0 @@
-
-
- 0,0,0,6
- 6
- 6
- 0
- 0
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/ToolTip.xaml b/src/Avalonia.Themes.Default/Controls/ToolTip.xaml
deleted file mode 100644
index 35c1dceb8d..0000000000
--- a/src/Avalonia.Themes.Default/Controls/ToolTip.xaml
+++ /dev/null
@@ -1,18 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/TreeView.xaml b/src/Avalonia.Themes.Default/Controls/TreeView.xaml
deleted file mode 100644
index 67a683dad9..0000000000
--- a/src/Avalonia.Themes.Default/Controls/TreeView.xaml
+++ /dev/null
@@ -1,27 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/TreeViewItem.xaml b/src/Avalonia.Themes.Default/Controls/TreeViewItem.xaml
deleted file mode 100644
index 1996756001..0000000000
--- a/src/Avalonia.Themes.Default/Controls/TreeViewItem.xaml
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/Controls/UserControl.xaml b/src/Avalonia.Themes.Default/Controls/UserControl.xaml
deleted file mode 100644
index d6028daff8..0000000000
--- a/src/Avalonia.Themes.Default/Controls/UserControl.xaml
+++ /dev/null
@@ -1,16 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/Window.xaml b/src/Avalonia.Themes.Default/Controls/Window.xaml
deleted file mode 100644
index 9c515ebe30..0000000000
--- a/src/Avalonia.Themes.Default/Controls/Window.xaml
+++ /dev/null
@@ -1,26 +0,0 @@
-
diff --git a/src/Avalonia.Themes.Default/Controls/WindowNotificationManager.xaml b/src/Avalonia.Themes.Default/Controls/WindowNotificationManager.xaml
deleted file mode 100644
index 7c1efa2e82..0000000000
--- a/src/Avalonia.Themes.Default/Controls/WindowNotificationManager.xaml
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/DefaultTheme.xaml b/src/Avalonia.Themes.Default/DefaultTheme.xaml
deleted file mode 100644
index f266402aef..0000000000
--- a/src/Avalonia.Themes.Default/DefaultTheme.xaml
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Avalonia.Themes.Default/DefaultTheme.xaml.cs b/src/Avalonia.Themes.Default/DefaultTheme.xaml.cs
deleted file mode 100644
index 598b418977..0000000000
--- a/src/Avalonia.Themes.Default/DefaultTheme.xaml.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Avalonia.Styling;
-
-namespace Avalonia.Themes.Default
-{
- ///
- /// The default Avalonia theme.
- ///
- public class DefaultTheme : Styles
- {
- }
-}
diff --git a/src/Avalonia.Themes.Fluent/Controls/ButtonSpinner.xaml b/src/Avalonia.Themes.Fluent/Controls/ButtonSpinner.xaml
index 855dc5363e..aa55065f6d 100644
--- a/src/Avalonia.Themes.Fluent/Controls/ButtonSpinner.xaml
+++ b/src/Avalonia.Themes.Fluent/Controls/ButtonSpinner.xaml
@@ -41,13 +41,31 @@
M0,9 L10,0 20,9 19,10 10,2 1,10 z
M0,1 L10,10 20,1 19,0 10,8 1,0 z
-
-
+
-
+
+
+
+
+
+
+
+
+
@@ -83,7 +101,6 @@
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness, Converter={StaticResource ButtonSpinnerLeftThickness}}"
- CornerRadius="0"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center"
Foreground="{TemplateBinding Foreground}"
@@ -99,7 +116,6 @@
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness, Converter={StaticResource ButtonSpinnerLeftThickness}}"
- CornerRadius="0"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center"
Foreground="{TemplateBinding Foreground}"
diff --git a/src/Avalonia.Themes.Fluent/Controls/ContextMenu.xaml b/src/Avalonia.Themes.Fluent/Controls/ContextMenu.xaml
index 8365ee61d3..fdd79ed736 100644
--- a/src/Avalonia.Themes.Fluent/Controls/ContextMenu.xaml
+++ b/src/Avalonia.Themes.Fluent/Controls/ContextMenu.xaml
@@ -29,7 +29,7 @@
-
+
0,4,0,4
@@ -54,7 +54,7 @@
MinHeight="{TemplateBinding MinHeight}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
CornerRadius="{TemplateBinding CornerRadius}">
-
+
@@ -26,10 +25,33 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
diff --git a/src/Avalonia.Themes.Fluent/Controls/FluentControls.xaml b/src/Avalonia.Themes.Fluent/Controls/FluentControls.xaml
index 0499495239..577539b26b 100644
--- a/src/Avalonia.Themes.Fluent/Controls/FluentControls.xaml
+++ b/src/Avalonia.Themes.Fluent/Controls/FluentControls.xaml
@@ -75,5 +75,4 @@
-
diff --git a/src/Avalonia.Themes.Fluent/Controls/Menu.xaml b/src/Avalonia.Themes.Fluent/Controls/Menu.xaml
index 12d18ae644..f5fd69a67f 100644
--- a/src/Avalonia.Themes.Fluent/Controls/Menu.xaml
+++ b/src/Avalonia.Themes.Fluent/Controls/Menu.xaml
@@ -5,7 +5,7 @@
@@ -46,7 +46,7 @@
MinHeight="{DynamicResource MenuFlyoutThemeMinHeight}"
HorizontalAlignment="Stretch"
CornerRadius="{DynamicResource OverlayCornerRadius}">
-
+
-
+
-
-
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/ToggleButton.xaml b/src/Avalonia.Themes.Simple/Controls/Button.xaml
similarity index 53%
rename from src/Avalonia.Themes.Default/Controls/ToggleButton.xaml
rename to src/Avalonia.Themes.Simple/Controls/Button.xaml
index 17fb2af16c..9018677ab6 100644
--- a/src/Avalonia.Themes.Default/Controls/ToggleButton.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/Button.xaml
@@ -1,40 +1,38 @@
-
-
-
-
-
-
-
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/ButtonSpinner.xaml b/src/Avalonia.Themes.Simple/Controls/ButtonSpinner.xaml
new file mode 100644
index 0000000000..9798e5290b
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/ButtonSpinner.xaml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/Calendar.xaml b/src/Avalonia.Themes.Simple/Controls/Calendar.xaml
similarity index 65%
rename from src/Avalonia.Themes.Default/Controls/Calendar.xaml
rename to src/Avalonia.Themes.Simple/Controls/Calendar.xaml
index 4b67aa232b..6f7267581b 100644
--- a/src/Avalonia.Themes.Default/Controls/Calendar.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/Calendar.xaml
@@ -1,12 +1,14 @@
-
-
-
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/CalendarButton.xaml b/src/Avalonia.Themes.Simple/Controls/CalendarButton.xaml
new file mode 100644
index 0000000000..59fb24663f
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/CalendarButton.xaml
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/CalendarDatePicker.xaml b/src/Avalonia.Themes.Simple/Controls/CalendarDatePicker.xaml
similarity index 64%
rename from src/Avalonia.Themes.Default/Controls/CalendarDatePicker.xaml
rename to src/Avalonia.Themes.Simple/Controls/CalendarDatePicker.xaml
index 3e2e497d2c..43fc8c7a34 100644
--- a/src/Avalonia.Themes.Default/Controls/CalendarDatePicker.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/CalendarDatePicker.xaml
@@ -1,20 +1,21 @@
-
-
-
+
-
+
+ UseFloatingWatermark="{TemplateBinding UseFloatingWatermark}"
+ Watermark="{TemplateBinding Watermark}" />
+ Focusable="False"
+ Foreground="{TemplateBinding Foreground}" />
+ FirstDayOfWeek="{TemplateBinding FirstDayOfWeek}"
+ IsTodayHighlighted="{TemplateBinding IsTodayHighlighted}"
+ SelectedDate="{TemplateBinding SelectedDate,
+ Mode=TwoWay}" />
-
-
-
-
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/CalendarDayButton.xaml b/src/Avalonia.Themes.Simple/Controls/CalendarDayButton.xaml
new file mode 100644
index 0000000000..0973a3b752
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/CalendarDayButton.xaml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/CalendarItem.xaml b/src/Avalonia.Themes.Simple/Controls/CalendarItem.xaml
similarity index 68%
rename from src/Avalonia.Themes.Default/Controls/CalendarItem.xaml
rename to src/Avalonia.Themes.Simple/Controls/CalendarItem.xaml
index 5b7ae5061a..e06034fe09 100644
--- a/src/Avalonia.Themes.Default/Controls/CalendarItem.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/CalendarItem.xaml
@@ -1,26 +1,27 @@
-
-
-
+ Fill="{TemplateBinding HeaderBackground}"
+ Stretch="Fill" />
-
+
+ VerticalAlignment="Center"
+ Classes="CalendarHeader"
+ FontSize="10.5"
+ FontWeight="Bold" />
+ Margin="6,-1,6,6"
+ IsVisible="False">
@@ -132,8 +133,8 @@
+ Margin="6,-3,7,6"
+ IsVisible="False">
@@ -146,39 +147,33 @@
-
-
+ Stretch="Fill" />
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/CaptionButtons.xaml b/src/Avalonia.Themes.Simple/Controls/CaptionButtons.xaml
new file mode 100644
index 0000000000..379b92ea17
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/CaptionButtons.xaml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/Carousel.xaml b/src/Avalonia.Themes.Simple/Controls/Carousel.xaml
new file mode 100644
index 0000000000..e79e3942c9
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/Carousel.xaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/CheckBox.xaml b/src/Avalonia.Themes.Simple/Controls/CheckBox.xaml
similarity index 57%
rename from src/Avalonia.Themes.Default/Controls/CheckBox.xaml
rename to src/Avalonia.Themes.Simple/Controls/CheckBox.xaml
index 170ecdd5b8..10e0b883d5 100644
--- a/src/Avalonia.Themes.Default/Controls/CheckBox.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/CheckBox.xaml
@@ -1,72 +1,75 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/ComboBox.xaml b/src/Avalonia.Themes.Simple/Controls/ComboBox.xaml
similarity index 65%
rename from src/Avalonia.Themes.Default/Controls/ComboBox.xaml
rename to src/Avalonia.Themes.Simple/Controls/ComboBox.xaml
index 262f63e2d2..d7dabae516 100644
--- a/src/Avalonia.Themes.Default/Controls/ComboBox.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/ComboBox.xaml
@@ -1,23 +1,7 @@
-
-
-
-
-
- Item 1
- Item 2
-
-
- Item 1
- Item 2
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/ComboBoxItem.xaml b/src/Avalonia.Themes.Simple/Controls/ComboBoxItem.xaml
new file mode 100644
index 0000000000..c3d8b6f900
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/ComboBoxItem.xaml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/ContentControl.xaml b/src/Avalonia.Themes.Simple/Controls/ContentControl.xaml
new file mode 100644
index 0000000000..415b1dc721
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/ContentControl.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/ContextMenu.xaml b/src/Avalonia.Themes.Simple/Controls/ContextMenu.xaml
new file mode 100644
index 0000000000..e99f1c5ac0
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/ContextMenu.xaml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/DataValidationErrors.xaml b/src/Avalonia.Themes.Simple/Controls/DataValidationErrors.xaml
new file mode 100644
index 0000000000..da8ec03cd4
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/DataValidationErrors.xaml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/DatePicker.xaml b/src/Avalonia.Themes.Simple/Controls/DatePicker.xaml
new file mode 100644
index 0000000000..a6da2ad9f8
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/DatePicker.xaml
@@ -0,0 +1,313 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Error
+
+
+
+
+
+
+
+
+ 0,0,0,4
+ 40
+ 40
+ 41
+ 296
+ 456
+ 0,3,0,6
+ 9,3,0,6
+ 0,3,0,6
+ 9,3,0,6
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/DateTimePickerShared.xaml b/src/Avalonia.Themes.Simple/Controls/DateTimePickerShared.xaml
new file mode 100644
index 0000000000..5909a1abbf
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/DateTimePickerShared.xaml
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+ Standard Item
+ Month Item
+ Button
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/DropDownButton.xaml b/src/Avalonia.Themes.Simple/Controls/DropDownButton.xaml
similarity index 54%
rename from src/Avalonia.Themes.Default/Controls/DropDownButton.xaml
rename to src/Avalonia.Themes.Simple/Controls/DropDownButton.xaml
index 662c6379fb..6a50cd6e36 100644
--- a/src/Avalonia.Themes.Default/Controls/DropDownButton.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/DropDownButton.xaml
@@ -1,12 +1,14 @@
-
-
-
+
-
+
-
+
-
-
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/EmbeddableControlRoot.xaml b/src/Avalonia.Themes.Simple/Controls/EmbeddableControlRoot.xaml
new file mode 100644
index 0000000000..79d6c6d917
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/EmbeddableControlRoot.xaml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/Expander.xaml b/src/Avalonia.Themes.Simple/Controls/Expander.xaml
new file mode 100644
index 0000000000..9920c9445a
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/Expander.xaml
@@ -0,0 +1,256 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/FlyoutPresenter.xaml b/src/Avalonia.Themes.Simple/Controls/FlyoutPresenter.xaml
similarity index 78%
rename from src/Avalonia.Themes.Default/Controls/FlyoutPresenter.xaml
rename to src/Avalonia.Themes.Simple/Controls/FlyoutPresenter.xaml
index 3bc5e085ff..08959cfbbe 100644
--- a/src/Avalonia.Themes.Default/Controls/FlyoutPresenter.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/FlyoutPresenter.xaml
@@ -1,8 +1,10 @@
-
-
-
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/FocusAdorner.xaml b/src/Avalonia.Themes.Simple/Controls/FocusAdorner.xaml
new file mode 100644
index 0000000000..f1d5f5f2ac
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/FocusAdorner.xaml
@@ -0,0 +1,11 @@
+
diff --git a/src/Avalonia.Themes.Simple/Controls/GridSplitter.xaml b/src/Avalonia.Themes.Simple/Controls/GridSplitter.xaml
new file mode 100644
index 0000000000..f2a3f01397
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/GridSplitter.xaml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/ItemsControl.xaml b/src/Avalonia.Themes.Simple/Controls/ItemsControl.xaml
new file mode 100644
index 0000000000..d8cdf96abd
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/ItemsControl.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/TabStripItem.xaml b/src/Avalonia.Themes.Simple/Controls/Label.xaml
similarity index 59%
rename from src/Avalonia.Themes.Default/Controls/TabStripItem.xaml
rename to src/Avalonia.Themes.Simple/Controls/Label.xaml
index 61eecc0395..0faa4852f2 100644
--- a/src/Avalonia.Themes.Default/Controls/TabStripItem.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/Label.xaml
@@ -1,24 +1,22 @@
-
-
-
-
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/ListBox.xaml b/src/Avalonia.Themes.Simple/Controls/ListBox.xaml
new file mode 100644
index 0000000000..7308738681
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/ListBox.xaml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/ListBoxItem.xaml b/src/Avalonia.Themes.Simple/Controls/ListBoxItem.xaml
new file mode 100644
index 0000000000..4d918326c8
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/ListBoxItem.xaml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/ManagedFileChooser.xaml b/src/Avalonia.Themes.Simple/Controls/ManagedFileChooser.xaml
new file mode 100644
index 0000000000..52d9000396
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/ManagedFileChooser.xaml
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Show hidden files
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/Menu.xaml b/src/Avalonia.Themes.Simple/Controls/Menu.xaml
new file mode 100644
index 0000000000..95b259bfa6
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/Menu.xaml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/MenuFlyoutPresenter.xaml b/src/Avalonia.Themes.Simple/Controls/MenuFlyoutPresenter.xaml
similarity index 76%
rename from src/Avalonia.Themes.Default/Controls/MenuFlyoutPresenter.xaml
rename to src/Avalonia.Themes.Simple/Controls/MenuFlyoutPresenter.xaml
index d56b46b17c..d974c36d31 100644
--- a/src/Avalonia.Themes.Default/Controls/MenuFlyoutPresenter.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/MenuFlyoutPresenter.xaml
@@ -1,6 +1,8 @@
-
-
-
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/MenuItem.xaml b/src/Avalonia.Themes.Simple/Controls/MenuItem.xaml
new file mode 100644
index 0000000000..ec22ee413d
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/MenuItem.xaml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/NativeMenuBar.xaml b/src/Avalonia.Themes.Simple/Controls/NativeMenuBar.xaml
new file mode 100644
index 0000000000..8c51ec8609
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/NativeMenuBar.xaml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/NotificationCard.xaml b/src/Avalonia.Themes.Simple/Controls/NotificationCard.xaml
new file mode 100644
index 0000000000..524f964afc
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/NotificationCard.xaml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/NumericUpDown.xaml b/src/Avalonia.Themes.Simple/Controls/NumericUpDown.xaml
similarity index 71%
rename from src/Avalonia.Themes.Default/Controls/NumericUpDown.xaml
rename to src/Avalonia.Themes.Simple/Controls/NumericUpDown.xaml
index 6740be69bb..d3adfb31e0 100644
--- a/src/Avalonia.Themes.Default/Controls/NumericUpDown.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/NumericUpDown.xaml
@@ -1,40 +1,39 @@
-
-
-
-
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/OverlayPopupHost.xaml b/src/Avalonia.Themes.Simple/Controls/OverlayPopupHost.xaml
new file mode 100644
index 0000000000..d1f5585c02
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/OverlayPopupHost.xaml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/PathIcon.xaml b/src/Avalonia.Themes.Simple/Controls/PathIcon.xaml
new file mode 100644
index 0000000000..4116b5784e
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/PathIcon.xaml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/PopupRoot.xaml b/src/Avalonia.Themes.Simple/Controls/PopupRoot.xaml
new file mode 100644
index 0000000000..a5593e3a68
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/PopupRoot.xaml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/ProgressBar.xaml b/src/Avalonia.Themes.Simple/Controls/ProgressBar.xaml
new file mode 100644
index 0000000000..5adb5bde7e
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/ProgressBar.xaml
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/RadioButton.xaml b/src/Avalonia.Themes.Simple/Controls/RadioButton.xaml
new file mode 100644
index 0000000000..c837b44402
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/RadioButton.xaml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/Button.xaml b/src/Avalonia.Themes.Simple/Controls/RepeatButton.xaml
similarity index 58%
rename from src/Avalonia.Themes.Default/Controls/Button.xaml
rename to src/Avalonia.Themes.Simple/Controls/RepeatButton.xaml
index a2971c3ff6..73cfd4d810 100644
--- a/src/Avalonia.Themes.Default/Controls/Button.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/RepeatButton.xaml
@@ -1,36 +1,34 @@
-
-
-
-
-
-
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/RichTextBlock.xaml b/src/Avalonia.Themes.Simple/Controls/RichTextBlock.xaml
new file mode 100644
index 0000000000..c0570282cb
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/RichTextBlock.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/ScrollBar.xaml b/src/Avalonia.Themes.Simple/Controls/ScrollBar.xaml
new file mode 100644
index 0000000000..d28ba66f6d
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/ScrollBar.xaml
@@ -0,0 +1,151 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/ScrollViewer.xaml b/src/Avalonia.Themes.Simple/Controls/ScrollViewer.xaml
similarity index 52%
rename from src/Avalonia.Themes.Default/Controls/ScrollViewer.xaml
rename to src/Avalonia.Themes.Simple/Controls/ScrollViewer.xaml
index aab1b76259..e11fbb6f15 100644
--- a/src/Avalonia.Themes.Default/Controls/ScrollViewer.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/ScrollViewer.xaml
@@ -1,106 +1,125 @@
-
-
+
-
-
+
-
-
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/Separator.xaml b/src/Avalonia.Themes.Simple/Controls/Separator.xaml
new file mode 100644
index 0000000000..e142cf29ad
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/Separator.xaml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/SimpleControls.xaml b/src/Avalonia.Themes.Simple/Controls/SimpleControls.xaml
new file mode 100644
index 0000000000..644c6ed416
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/SimpleControls.xaml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/Slider.xaml b/src/Avalonia.Themes.Simple/Controls/Slider.xaml
new file mode 100644
index 0000000000..851ee1b78a
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/Slider.xaml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/SplitButton.xaml b/src/Avalonia.Themes.Simple/Controls/SplitButton.xaml
new file mode 100644
index 0000000000..f0d22aac97
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/SplitButton.xaml
@@ -0,0 +1,223 @@
+
+
+
+
+
+
+
+
+
+
+ 24
+ 24
+ 1
+ 24
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/SplitView.xaml b/src/Avalonia.Themes.Simple/Controls/SplitView.xaml
new file mode 100644
index 0000000000..b0e4d0b096
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/SplitView.xaml
@@ -0,0 +1,255 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 320
+ 48
+
+ 00:00:00.2
+ 00:00:00.1
+ 0.1,0.9,0.2,1.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/TabControl.xaml b/src/Avalonia.Themes.Simple/Controls/TabControl.xaml
new file mode 100644
index 0000000000..4d1fcc0336
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/TabControl.xaml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/TabItem.xaml b/src/Avalonia.Themes.Simple/Controls/TabItem.xaml
new file mode 100644
index 0000000000..7b6a1d1116
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/TabItem.xaml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/TabStrip.xaml b/src/Avalonia.Themes.Simple/Controls/TabStrip.xaml
similarity index 63%
rename from src/Avalonia.Themes.Default/Controls/TabStrip.xaml
rename to src/Avalonia.Themes.Simple/Controls/TabStrip.xaml
index 29ca1e7c94..3960c1d275 100644
--- a/src/Avalonia.Themes.Default/Controls/TabStrip.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/TabStrip.xaml
@@ -1,11 +1,13 @@
-
-
-
-
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/TabStripItem.xaml b/src/Avalonia.Themes.Simple/Controls/TabStripItem.xaml
new file mode 100644
index 0000000000..b4d7218ec3
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/TabStripItem.xaml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/TextBox.xaml b/src/Avalonia.Themes.Simple/Controls/TextBox.xaml
new file mode 100644
index 0000000000..5fa6412688
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/TextBox.xaml
@@ -0,0 +1,221 @@
+
+ M 11.416016,10 20,1.4160156 18.583984,0 10,8.5839846 1.4160156,0 0,1.4160156 8.5839844,10 0,18.583985 1.4160156,20 10,11.416015 18.583984,20 20,18.583985 Z
+ m10.051 7.0032c2.215 0 4.0105 1.7901 4.0105 3.9984s-1.7956 3.9984-4.0105 3.9984c-2.215 0-4.0105-1.7901-4.0105-3.9984s1.7956-3.9984 4.0105-3.9984zm0 1.4994c-1.3844 0-2.5066 1.1188-2.5066 2.499s1.1222 2.499 2.5066 2.499 2.5066-1.1188 2.5066-2.499-1.1222-2.499-2.5066-2.499zm0-5.0026c4.6257 0 8.6188 3.1487 9.7267 7.5613 0.10085 0.40165-0.14399 0.80877-0.54686 0.90931-0.40288 0.10054-0.81122-0.14355-0.91208-0.54521-0.94136-3.7492-4.3361-6.4261-8.2678-6.4261-3.9334 0-7.3292 2.6792-8.2689 6.4306-0.10063 0.40171-0.50884 0.64603-0.91177 0.54571s-0.648-0.5073-0.54737-0.90901c1.106-4.4152 5.1003-7.5667 9.728-7.5667z
+ m0.21967 0.21965c-0.26627 0.26627-0.29047 0.68293-0.07262 0.97654l0.07262 0.08412 4.0346 4.0346c-1.922 1.3495-3.3585 3.365-3.9554 5.7495-0.10058 0.4018 0.14362 0.8091 0.54543 0.9097 0.40182 0.1005 0.80909-0.1436 0.90968-0.5455 0.52947-2.1151 1.8371-3.8891 3.5802-5.0341l1.8096 1.8098c-0.70751 0.7215-1.1438 1.71-1.1438 2.8003 0 2.2092 1.7909 4 4 4 1.0904 0 2.0788-0.4363 2.8004-1.1438l5.9193 5.9195c0.2929 0.2929 0.7677 0.2929 1.0606 0 0.2663-0.2662 0.2905-0.6829 0.0726-0.9765l-0.0726-0.0841-6.1135-6.1142 0.0012-0.0015-1.2001-1.1979-2.8699-2.8693 2e-3 -8e-4 -2.8812-2.8782 0.0012-0.0018-1.1333-1.1305-4.3064-4.3058c-0.29289-0.29289-0.76777-0.29289-1.0607 0zm7.9844 9.0458 3.5351 3.5351c-0.45 0.4358-1.0633 0.704-1.7392 0.704-1.3807 0-2.5-1.1193-2.5-2.5 0-0.6759 0.26824-1.2892 0.7041-1.7391zm1.7959-5.7655c-1.0003 0-1.9709 0.14807-2.8889 0.425l1.237 1.2362c0.5358-0.10587 1.0883-0.16119 1.6519-0.16119 3.9231 0 7.3099 2.6803 8.2471 6.4332 0.1004 0.4018 0.5075 0.6462 0.9094 0.5459 0.4019-0.1004 0.6463-0.5075 0.5459-0.9094-1.103-4.417-5.0869-7.5697-9.7024-7.5697zm0.1947 3.5093 3.8013 3.8007c-0.1018-2.0569-1.7488-3.7024-3.8013-3.8007z
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/TimePicker.xaml b/src/Avalonia.Themes.Simple/Controls/TimePicker.xaml
new file mode 100644
index 0000000000..c49b3aec4e
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/TimePicker.xaml
@@ -0,0 +1,329 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Error
+
+
+
+
+
+
+
+
+ 40
+ 1
+ 1
+ 0,0,0,4
+ 40
+ 41
+ 242
+ 456
+ 0,3,0,6
+ 0,3,0,6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/TitleBar.xaml b/src/Avalonia.Themes.Simple/Controls/TitleBar.xaml
new file mode 100644
index 0000000000..a06dfbb834
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/TitleBar.xaml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/ToggleButton.xaml b/src/Avalonia.Themes.Simple/Controls/ToggleButton.xaml
new file mode 100644
index 0000000000..2cfbcf6b7a
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/ToggleButton.xaml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/ToggleSwitch.xaml b/src/Avalonia.Themes.Simple/Controls/ToggleSwitch.xaml
new file mode 100644
index 0000000000..d00358951a
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/ToggleSwitch.xaml
@@ -0,0 +1,301 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0,0,0,6
+ 6
+ 6
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/ToolTip.xaml b/src/Avalonia.Themes.Simple/Controls/ToolTip.xaml
new file mode 100644
index 0000000000..c4fddd8c4c
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/ToolTip.xaml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/Controls/TransitioningContentControl.xaml b/src/Avalonia.Themes.Simple/Controls/TransitioningContentControl.xaml
similarity index 68%
rename from src/Avalonia.Themes.Default/Controls/TransitioningContentControl.xaml
rename to src/Avalonia.Themes.Simple/Controls/TransitioningContentControl.xaml
index 6a4d56ccb7..63185e11e6 100644
--- a/src/Avalonia.Themes.Default/Controls/TransitioningContentControl.xaml
+++ b/src/Avalonia.Themes.Simple/Controls/TransitioningContentControl.xaml
@@ -1,20 +1,21 @@
-
-
-
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/TreeView.xaml b/src/Avalonia.Themes.Simple/Controls/TreeView.xaml
new file mode 100644
index 0000000000..2bc38a0673
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/TreeView.xaml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/TreeViewItem.xaml b/src/Avalonia.Themes.Simple/Controls/TreeViewItem.xaml
new file mode 100644
index 0000000000..8b3452244c
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/TreeViewItem.xaml
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/UserControl.xaml b/src/Avalonia.Themes.Simple/Controls/UserControl.xaml
new file mode 100644
index 0000000000..3316b0298c
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/UserControl.xaml
@@ -0,0 +1,25 @@
+
diff --git a/src/Avalonia.Themes.Simple/Controls/Window.xaml b/src/Avalonia.Themes.Simple/Controls/Window.xaml
new file mode 100644
index 0000000000..00b108343e
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/Window.xaml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Simple/Controls/WindowNotificationManager.xaml b/src/Avalonia.Themes.Simple/Controls/WindowNotificationManager.xaml
new file mode 100644
index 0000000000..6dacf63be5
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Controls/WindowNotificationManager.xaml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Default/IBitmapToImageConverter.cs b/src/Avalonia.Themes.Simple/IBitmapToImageConverter.cs
similarity index 95%
rename from src/Avalonia.Themes.Default/IBitmapToImageConverter.cs
rename to src/Avalonia.Themes.Simple/IBitmapToImageConverter.cs
index 9b7fcecf45..fade026b51 100644
--- a/src/Avalonia.Themes.Default/IBitmapToImageConverter.cs
+++ b/src/Avalonia.Themes.Simple/IBitmapToImageConverter.cs
@@ -8,7 +8,7 @@ using Avalonia.Controls;
using Avalonia.Data.Converters;
using Avalonia.Media.Imaging;
-namespace Avalonia.Themes.Default
+namespace Avalonia.Themes.Simple
{
internal class IBitmapToImageConverter : IValueConverter
{
diff --git a/src/Avalonia.Themes.Default/InverseBooleanValueConverter.cs b/src/Avalonia.Themes.Simple/InverseBooleanValueConverter.cs
similarity index 94%
rename from src/Avalonia.Themes.Default/InverseBooleanValueConverter.cs
rename to src/Avalonia.Themes.Simple/InverseBooleanValueConverter.cs
index 7befc81b8e..15cc5b4a80 100644
--- a/src/Avalonia.Themes.Default/InverseBooleanValueConverter.cs
+++ b/src/Avalonia.Themes.Simple/InverseBooleanValueConverter.cs
@@ -2,7 +2,7 @@ using System;
using System.Globalization;
using Avalonia.Data.Converters;
-namespace Avalonia.Themes.Default
+namespace Avalonia.Themes.Simple
{
class InverseBooleanValueConverter : IValueConverter
{
diff --git a/src/Avalonia.Themes.Simple/Properties/AssemblyInfo.cs b/src/Avalonia.Themes.Simple/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..f00510816a
--- /dev/null
+++ b/src/Avalonia.Themes.Simple/Properties/AssemblyInfo.cs
@@ -0,0 +1,3 @@
+using Avalonia.Metadata;
+
+[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Themes.Simple")]
diff --git a/src/Avalonia.Themes.Default/SimpleTheme.cs b/src/Avalonia.Themes.Simple/SimpleTheme.cs
similarity index 89%
rename from src/Avalonia.Themes.Default/SimpleTheme.cs
rename to src/Avalonia.Themes.Simple/SimpleTheme.cs
index 98e35355c8..f225cb4c4d 100644
--- a/src/Avalonia.Themes.Default/SimpleTheme.cs
+++ b/src/Avalonia.Themes.Simple/SimpleTheme.cs
@@ -6,7 +6,7 @@ using Avalonia.Markup.Xaml.Styling;
using Avalonia.Styling;
#nullable enable
-namespace Avalonia.Themes.Default
+namespace Avalonia.Themes.Simple
{
public class SimpleTheme : AvaloniaObject, IStyle, IResourceProvider
{
@@ -23,9 +23,9 @@ namespace Avalonia.Themes.Default
/// Initializes a new instance of the class.
///
/// The base URL for the XAML context.
- public SimpleTheme(Uri baseUri)
+ public SimpleTheme(Uri? baseUri = null)
{
- _baseUri = baseUri;
+ _baseUri = baseUri ?? new Uri("avares://Avalonia.Themes.Simple/");
InitStyles(_baseUri);
}
@@ -138,18 +138,18 @@ namespace Avalonia.Themes.Default
{
new StyleInclude(baseUri)
{
- Source = new Uri("avares://Avalonia.Themes.Default/DefaultTheme.xaml")
+ Source = new Uri("avares://Avalonia.Themes.Simple/Controls/SimpleControls.xaml")
},
new StyleInclude(baseUri)
{
- Source = new Uri("avares://Avalonia.Themes.Default/Accents/Base.xaml")
+ Source = new Uri("avares://Avalonia.Themes.Simple/Accents/Base.xaml")
}
};
_simpleLight = new Styles
{
new StyleInclude(baseUri)
{
- Source = new Uri("avares://Avalonia.Themes.Default/Accents/BaseLight.xaml")
+ Source = new Uri("avares://Avalonia.Themes.Simple/Accents/BaseLight.xaml")
}
};
@@ -157,7 +157,7 @@ namespace Avalonia.Themes.Default
{
new StyleInclude(baseUri)
{
- Source = new Uri("avares://Avalonia.Themes.Default/Accents/BaseDark.xaml")
+ Source = new Uri("avares://Avalonia.Themes.Simple/Accents/BaseDark.xaml")
}
};
}
diff --git a/src/Avalonia.Themes.Default/SimpleThemeMode.cs b/src/Avalonia.Themes.Simple/SimpleThemeMode.cs
similarity index 67%
rename from src/Avalonia.Themes.Default/SimpleThemeMode.cs
rename to src/Avalonia.Themes.Simple/SimpleThemeMode.cs
index be33466327..683c751f10 100644
--- a/src/Avalonia.Themes.Default/SimpleThemeMode.cs
+++ b/src/Avalonia.Themes.Simple/SimpleThemeMode.cs
@@ -1,4 +1,4 @@
-namespace Avalonia.Themes.Default
+namespace Avalonia.Themes.Simple
{
public enum SimpleThemeMode
{
diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs
index 094cd59025..f325e6e2d6 100644
--- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs
+++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs
@@ -60,6 +60,10 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
InsertAfter(
new XDataTypeTransformer());
+ InsertBefore(
+ new AvaloniaXamlIlDeferredResourceTransformer()
+ );
+
// After everything else
InsertBefore(
new AddNameScopeRegistration(),
diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDeferredResourceTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDeferredResourceTransformer.cs
new file mode 100644
index 0000000000..662263e513
--- /dev/null
+++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDeferredResourceTransformer.cs
@@ -0,0 +1,90 @@
+using System.Collections.Generic;
+using System.Linq;
+using XamlX.Ast;
+using XamlX.Emit;
+using XamlX.IL;
+using XamlX.Transform;
+using XamlX.TypeSystem;
+
+namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
+{
+ internal class AvaloniaXamlIlDeferredResourceTransformer : IXamlAstTransformer
+ {
+ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
+ {
+ if (!(node is XamlPropertyAssignmentNode pa) || pa.Values.Count != 2)
+ return node;
+
+ if (!ShouldBeDeferred(pa.Values[1]))
+ return node;
+
+ var types = context.GetAvaloniaTypes();
+
+ if (pa.Property.DeclaringType == types.ResourceDictionary && pa.Property.Name == "Content")
+ {
+ pa.Values[1] = new XamlDeferredContentNode(pa.Values[1], types.XamlIlTypes.Object, context.Configuration);
+ pa.PossibleSetters = new List
+ {
+ new XamlDirectCallPropertySetter(types.ResourceDictionaryDeferredAdd),
+ };
+ }
+ else if (pa.Property.Name == "Resources" && pa.Property.Getter.ReturnType.Equals(types.IResourceDictionary))
+ {
+ pa.Values[1] = new XamlDeferredContentNode(pa.Values[1], types.XamlIlTypes.Object, context.Configuration);
+ pa.PossibleSetters = new List
+ {
+ new AdderSetter(pa.Property.Getter, types.ResourceDictionaryDeferredAdd),
+ };
+ }
+
+ return node;
+ }
+
+ private static bool ShouldBeDeferred(IXamlAstValueNode node)
+ {
+ // XAML compiler is currently strict about value types, allowing them to be created only through converters.
+ // At the moment it should be safe to not defer structs.
+ return !node.Type.GetClrType().IsValueType;
+ }
+
+ class AdderSetter : IXamlPropertySetter, IXamlEmitablePropertySetter
+ {
+ private readonly IXamlMethod _getter;
+ private readonly IXamlMethod _adder;
+
+ public AdderSetter(IXamlMethod getter, IXamlMethod adder)
+ {
+ _getter = getter;
+ _adder = adder;
+ TargetType = getter.DeclaringType;
+ Parameters = adder.ParametersWithThis().Skip(1).ToList();
+ }
+
+ public IXamlType TargetType { get; }
+
+ public PropertySetterBinderParameters BinderParameters { get; } = new PropertySetterBinderParameters
+ {
+ AllowMultiple = true
+ };
+
+ public IReadOnlyList Parameters { get; }
+ public void Emit(IXamlILEmitter emitter)
+ {
+ var locals = new Stack();
+ // Save all "setter" parameters
+ for (var c = Parameters.Count - 1; c >= 0; c--)
+ {
+ var loc = emitter.LocalsPool.GetLocal(Parameters[c]);
+ locals.Push(loc);
+ emitter.Stloc(loc.Local);
+ }
+
+ emitter.EmitCall(_getter);
+ while (locals.Count > 0)
+ using (var loc = locals.Pop())
+ emitter.Ldloc(loc.Local);
+ emitter.EmitCall(_adder, true);
+ }
+ }
+ }
+}
diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
index 9d9f6a08ab..dbfbe0e070 100644
--- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
+++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
@@ -98,6 +98,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public IXamlType TextDecorations { get; }
public IXamlType TextTrimming { get; }
public IXamlType ISetter { get; }
+ public IXamlType IResourceDictionary { get; }
+ public IXamlType ResourceDictionary { get; }
+ public IXamlMethod ResourceDictionaryDeferredAdd { get; }
public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg)
{
@@ -218,6 +221,12 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
TextDecorations = cfg.TypeSystem.GetType("Avalonia.Media.TextDecorations");
TextTrimming = cfg.TypeSystem.GetType("Avalonia.Media.TextTrimming");
ISetter = cfg.TypeSystem.GetType("Avalonia.Styling.ISetter");
+ IResourceDictionary = cfg.TypeSystem.GetType("Avalonia.Controls.IResourceDictionary");
+ ResourceDictionary = cfg.TypeSystem.GetType("Avalonia.Controls.ResourceDictionary");
+ ResourceDictionaryDeferredAdd = ResourceDictionary.FindMethod("AddDeferred", XamlIlTypes.Void, true, XamlIlTypes.Object,
+ cfg.TypeSystem.GetType("System.Func`2").MakeGenericType(
+ cfg.TypeSystem.GetType("System.IServiceProvider"),
+ XamlIlTypes.Object));
}
}
diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs
index add97a660b..d462a2210e 100644
--- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs
@@ -39,6 +39,8 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
targetType = setter.Property.PropertyType;
}
+ var previousWasControlTheme = false;
+
// Look upwards though the ambient context for IResourceNodes
// which might be able to give us the resource.
foreach (var parent in stack.Parents)
@@ -47,6 +49,21 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
{
return ColorToBrushConverter.Convert(value, targetType);
}
+
+ // HACK: Temporary fix for #8678. Hard-coded to only work for the DevTools main
+ // window as we don't want 3rd parties to start relying on this hack.
+ //
+ // We need to implement compile-time merging of resource dictionaries and this
+ // hack can be removed.
+ if (previousWasControlTheme &&
+ parent is ResourceDictionary hack &&
+ hack.Owner?.GetType().FullName == "Avalonia.Diagnostics.Views.MainWindow" &&
+ hack.Owner.TryGetResource(ResourceKey, out value))
+ {
+ return ColorToBrushConverter.Convert(value, targetType);
+ }
+
+ previousWasControlTheme = parent is ControlTheme;
}
if (provideTarget.TargetObject is IControl target &&
@@ -69,3 +86,4 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
}
}
}
+
diff --git a/src/Markup/Avalonia.Markup/Data/TemplateBinding.cs b/src/Markup/Avalonia.Markup/Data/TemplateBinding.cs
index 265af3c5da..4a3538fff2 100644
--- a/src/Markup/Avalonia.Markup/Data/TemplateBinding.cs
+++ b/src/Markup/Avalonia.Markup/Data/TemplateBinding.cs
@@ -19,6 +19,7 @@ namespace Avalonia.Data
private bool _isSetterValue;
private IStyledElement _target = default!;
private Type? _targetType;
+ private bool _hasProducedValue;
public TemplateBinding()
{
@@ -143,10 +144,12 @@ namespace Avalonia.Data
}
PublishNext(value);
+ _hasProducedValue = true;
}
- else
+ else if (_hasProducedValue)
{
PublishNext(AvaloniaProperty.UnsetValue);
+ _hasProducedValue = false;
}
}
diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
index 8293769138..99ab60d1ac 100644
--- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
+++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
@@ -10,6 +10,7 @@ using Avalonia.Rendering.SceneGraph;
using Avalonia.Rendering.Utilities;
using Avalonia.Utilities;
using Avalonia.Media.Imaging;
+using JetBrains.Annotations;
using SkiaSharp;
namespace Avalonia.Skia
@@ -17,7 +18,7 @@ namespace Avalonia.Skia
///
/// Skia based drawing context.
///
- internal class DrawingContextImpl : IDrawingContextImpl, ISkiaDrawingContextImpl, IDrawingContextWithAcrylicLikeSupport
+ internal class DrawingContextImpl : IDrawingContextImpl, IDrawingContextWithAcrylicLikeSupport
{
private IDisposable[] _disposables;
private readonly Vector _dpi;
@@ -38,7 +39,8 @@ namespace Avalonia.Skia
private readonly SKPaint _fillPaint = new SKPaint();
private readonly SKPaint _boxShadowPaint = new SKPaint();
private static SKShader s_acrylicNoiseShader;
- private readonly ISkiaGpuRenderSession _session;
+ private readonly ISkiaGpuRenderSession _session;
+ private bool _leased = false;
///
/// Context create info.
@@ -83,6 +85,47 @@ namespace Avalonia.Skia
public ISkiaGpuRenderSession CurrentSession;
}
+ class SkiaLeaseFeature : ISkiaSharpApiLeaseFeature
+ {
+ private readonly DrawingContextImpl _context;
+
+ public SkiaLeaseFeature(DrawingContextImpl context)
+ {
+ _context = context;
+ }
+
+ public ISkiaSharpApiLease Lease()
+ {
+ _context.CheckLease();
+ return new ApiLease(_context);
+ }
+
+ class ApiLease : ISkiaSharpApiLease
+ {
+ private DrawingContextImpl _context;
+ private readonly SKMatrix _revertTransform;
+
+ public ApiLease(DrawingContextImpl context)
+ {
+ _revertTransform = context.Canvas.TotalMatrix;
+ _context = context;
+ _context._leased = true;
+ }
+
+ public SKCanvas SkCanvas => _context.Canvas;
+ public GRContext GrContext => _context.GrContext;
+ public SKSurface SkSurface => _context.Surface;
+ public double CurrentOpacity => _context._currentOpacity;
+
+ public void Dispose()
+ {
+ _context.Canvas.SetMatrix(_revertTransform);
+ _context._leased = false;
+ _context = null;
+ }
+ }
+ }
+
///
/// Create new drawing context.
///
@@ -123,20 +166,23 @@ namespace Avalonia.Skia
public SKCanvas Canvas { get; }
public SKSurface Surface { get; }
- SKCanvas ISkiaDrawingContextImpl.SkCanvas => Canvas;
- SKSurface ISkiaDrawingContextImpl.SkSurface => Surface;
- GRContext ISkiaDrawingContextImpl.GrContext => _grContext;
- double ISkiaDrawingContextImpl.CurrentOpacity => _currentOpacity;
-
+ private void CheckLease()
+ {
+ if (_leased)
+ throw new InvalidOperationException("The underlying graphics API is currently leased");
+ }
+
///
public void Clear(Color color)
{
+ CheckLease();
Canvas.Clear(color.ToSKColor());
}
///
public void DrawBitmap(IRef source, double opacity, Rect sourceRect, Rect destRect, BitmapInterpolationMode bitmapInterpolationMode)
{
+ CheckLease();
var drawableImage = (IDrawableBitmapImpl)source.Item;
var s = sourceRect.ToSKRect();
var d = destRect.ToSKRect();
@@ -157,6 +203,7 @@ namespace Avalonia.Skia
///
public void DrawBitmap(IRef source, IBrush opacityMask, Rect opacityMaskRect, Rect destRect)
{
+ CheckLease();
PushOpacityMask(opacityMask, opacityMaskRect);
DrawBitmap(source, 1, new Rect(0, 0, source.Item.PixelSize.Width, source.Item.PixelSize.Height), destRect, BitmapInterpolationMode.Default);
PopOpacityMask();
@@ -165,6 +212,7 @@ namespace Avalonia.Skia
///
public void DrawLine(IPen pen, Point p1, Point p2)
{
+ CheckLease();
using (var paint = CreatePaint(_strokePaint, pen, new Size(Math.Abs(p2.X - p1.X), Math.Abs(p2.Y - p1.Y))))
{
if (paint.Paint is object)
@@ -177,6 +225,7 @@ namespace Avalonia.Skia
///
public void DrawGeometry(IBrush brush, IPen pen, IGeometryImpl geometry)
{
+ CheckLease();
var impl = (GeometryImpl) geometry;
var size = geometry.Bounds.Size;
@@ -260,6 +309,7 @@ namespace Avalonia.Skia
{
if (rect.Rect.Height <= 0 || rect.Rect.Width <= 0)
return;
+ CheckLease();
var rc = rect.Rect.ToSKRect();
var isRounded = rect.IsRounded;
@@ -296,6 +346,7 @@ namespace Avalonia.Skia
{
if (rect.Rect.Height <= 0 || rect.Rect.Width <= 0)
return;
+ CheckLease();
// Arbitrary chosen values
// On OSX Skia breaks OpenGL context when asked to draw, e. g. (0, 0, 623, 6666600) rect
if (rect.Rect.Height > 8192 || rect.Rect.Width > 8192)
@@ -421,7 +472,8 @@ namespace Avalonia.Skia
{
if (rect.Height <= 0 || rect.Width <= 0)
return;
-
+ CheckLease();
+
var rc = rect.ToSKRect();
if (brush != null)
@@ -447,6 +499,7 @@ namespace Avalonia.Skia
///
public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun)
{
+ CheckLease();
using (var paintWrapper = CreatePaint(_fillPaint, foreground, glyphRun.Size))
{
var glyphRunImpl = (GlyphRunImpl)glyphRun.GlyphRunImpl;
@@ -459,18 +512,21 @@ namespace Avalonia.Skia
///
public IDrawingContextLayerImpl CreateLayer(Size size)
{
+ CheckLease();
return CreateRenderTarget(size, true);
}
///
public void PushClip(Rect clip)
{
+ CheckLease();
Canvas.Save();
Canvas.ClipRect(clip.ToSKRect());
}
public void PushClip(RoundedRect clip)
{
+ CheckLease();
Canvas.Save();
Canvas.ClipRoundRect(clip.ToSKRoundRect(), antialias:true);
}
@@ -478,12 +534,14 @@ namespace Avalonia.Skia
///
public void PopClip()
{
+ CheckLease();
Canvas.Restore();
}
///
public void PushOpacity(double opacity)
{
+ CheckLease();
_opacityStack.Push(_currentOpacity);
_currentOpacity *= opacity;
}
@@ -491,6 +549,7 @@ namespace Avalonia.Skia
///
public void PopOpacity()
{
+ CheckLease();
_currentOpacity = _opacityStack.Pop();
}
@@ -499,6 +558,7 @@ namespace Avalonia.Skia
{
if(_disposed)
return;
+ CheckLease();
try
{
if (_grContext != null)
@@ -523,6 +583,7 @@ namespace Avalonia.Skia
///
public void PushGeometryClip(IGeometryImpl clip)
{
+ CheckLease();
Canvas.Save();
Canvas.ClipPath(((GeometryImpl)clip).EffectivePath, SKClipOperation.Intersect, true);
}
@@ -530,12 +591,14 @@ namespace Avalonia.Skia
///
public void PopGeometryClip()
{
+ CheckLease();
Canvas.Restore();
}
///
public void PushBitmapBlendMode(BitmapBlendingMode blendingMode)
{
+ CheckLease();
_blendingModeStack.Push(_currentBlendingMode);
_currentBlendingMode = blendingMode;
}
@@ -543,14 +606,20 @@ namespace Avalonia.Skia
///
public void PopBitmapBlendMode()
{
+ CheckLease();
_currentBlendingMode = _blendingModeStack.Pop();
}
- public void Custom(ICustomDrawOperation custom) => custom.Render(this);
+ public void Custom(ICustomDrawOperation custom)
+ {
+ CheckLease();
+ custom.Render(this);
+ }
///
public void PushOpacityMask(IBrush mask, Rect bounds)
{
+ CheckLease();
// TODO: This should be disposed
var paint = new SKPaint();
@@ -561,6 +630,7 @@ namespace Avalonia.Skia
///
public void PopOpacityMask()
{
+ CheckLease();
using (var paint = new SKPaint { BlendMode = SKBlendMode.DstIn })
{
Canvas.SaveLayer(paint);
@@ -580,6 +650,7 @@ namespace Avalonia.Skia
get { return _currentTransform; }
set
{
+ CheckLease();
if (_currentTransform == value)
return;
@@ -596,6 +667,14 @@ namespace Avalonia.Skia
}
}
+ [CanBeNull]
+ public object GetFeature(Type t)
+ {
+ if (t == typeof(ISkiaSharpApiLeaseFeature))
+ return new SkiaLeaseFeature(this);
+ return null;
+ }
+
///
/// Configure paint wrapper for using gradient brush.
///
diff --git a/src/Skia/Avalonia.Skia/Helpers/DrawingContextHelper.cs b/src/Skia/Avalonia.Skia/Helpers/DrawingContextHelper.cs
index d0b45b7c5d..a078c364a2 100644
--- a/src/Skia/Avalonia.Skia/Helpers/DrawingContextHelper.cs
+++ b/src/Skia/Avalonia.Skia/Helpers/DrawingContextHelper.cs
@@ -33,7 +33,7 @@ namespace Avalonia.Skia.Helpers
/// Unsupported - Wraps a GPU Backed SkiaSurface in an Avalonia DrawingContext.
///
[Obsolete]
- public static ISkiaDrawingContextImpl WrapSkiaSurface(this SKSurface surface, GRContext grContext, Vector dpi, params IDisposable[] disposables)
+ public static IDrawingContextImpl WrapSkiaSurface(this SKSurface surface, GRContext grContext, Vector dpi, params IDisposable[] disposables)
{
var createInfo = new DrawingContextImpl.CreateInfo
{
@@ -50,7 +50,7 @@ namespace Avalonia.Skia.Helpers
/// Unsupported - Wraps a non-GPU Backed SkiaSurface in an Avalonia DrawingContext.
///
[Obsolete]
- public static ISkiaDrawingContextImpl WrapSkiaSurface(this SKSurface surface, Vector dpi, params IDisposable[] disposables)
+ public static IDrawingContextImpl WrapSkiaSurface(this SKSurface surface, Vector dpi, params IDisposable[] disposables)
{
var createInfo = new DrawingContextImpl.CreateInfo
{
@@ -63,7 +63,7 @@ namespace Avalonia.Skia.Helpers
}
[Obsolete]
- public static ISkiaDrawingContextImpl CreateDrawingContext(Size size, Vector dpi, GRContext grContext = null)
+ public static IDrawingContextImpl CreateDrawingContext(Size size, Vector dpi, GRContext grContext = null)
{
if (grContext is null)
{
@@ -90,9 +90,11 @@ namespace Avalonia.Skia.Helpers
}
[Obsolete]
- public static void DrawTo(this ISkiaDrawingContextImpl source, ISkiaDrawingContextImpl destination, SKPaint paint = null)
+ public static void DrawTo(this IDrawingContextImpl source, IDrawingContextImpl destination, SKPaint paint = null)
{
- destination.SkCanvas.DrawSurface(source.SkSurface, new SKPoint(0, 0), paint);
+ var src = (DrawingContextImpl)source;
+ var dst = (DrawingContextImpl)destination;
+ dst.Canvas.DrawSurface(src.Surface, new SKPoint(0, 0), paint);
}
}
}
diff --git a/src/Skia/Avalonia.Skia/ISkiaDrawingContextImpl.cs b/src/Skia/Avalonia.Skia/ISkiaDrawingContextImpl.cs
deleted file mode 100644
index 1b60154d46..0000000000
--- a/src/Skia/Avalonia.Skia/ISkiaDrawingContextImpl.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using Avalonia.Metadata;
-using Avalonia.Platform;
-using SkiaSharp;
-
-namespace Avalonia.Skia
-{
- [Unstable]
- public interface ISkiaDrawingContextImpl : IDrawingContextImpl
- {
- SKCanvas SkCanvas { get; }
- GRContext GrContext { get; }
- SKSurface SkSurface { get; }
- double CurrentOpacity { get; }
- }
-}
diff --git a/src/Skia/Avalonia.Skia/ISkiaSharpApiLeaseFeature.cs b/src/Skia/Avalonia.Skia/ISkiaSharpApiLeaseFeature.cs
new file mode 100644
index 0000000000..b3966c0324
--- /dev/null
+++ b/src/Skia/Avalonia.Skia/ISkiaSharpApiLeaseFeature.cs
@@ -0,0 +1,20 @@
+using System;
+using Avalonia.Metadata;
+using SkiaSharp;
+
+namespace Avalonia.Skia;
+
+[Unstable]
+public interface ISkiaSharpApiLeaseFeature
+{
+ public ISkiaSharpApiLease Lease();
+}
+
+[Unstable]
+public interface ISkiaSharpApiLease : IDisposable
+{
+ SKCanvas SkCanvas { get; }
+ GRContext GrContext { get; }
+ SKSurface SkSurface { get; }
+ double CurrentOpacity { get; }
+}
\ No newline at end of file
diff --git a/src/Skia/Avalonia.Skia/ImmutableBitmap.cs b/src/Skia/Avalonia.Skia/ImmutableBitmap.cs
index a80f406989..6400d67fde 100644
--- a/src/Skia/Avalonia.Skia/ImmutableBitmap.cs
+++ b/src/Skia/Avalonia.Skia/ImmutableBitmap.cs
@@ -1,11 +1,8 @@
using System;
using System.IO;
-using System.Runtime.CompilerServices;
-using System.Security.Cryptography;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Skia.Helpers;
-using Avalonia.Media.Imaging;
using SkiaSharp;
namespace Avalonia.Skia
diff --git a/src/Web/Avalonia.Web.Blazor/Interop/Storage/StorageProviderInterop.cs b/src/Web/Avalonia.Web.Blazor/Interop/Storage/StorageProviderInterop.cs
index 14dc53d7b5..2bc46e97b5 100644
--- a/src/Web/Avalonia.Web.Blazor/Interop/Storage/StorageProviderInterop.cs
+++ b/src/Web/Avalonia.Web.Blazor/Interop/Storage/StorageProviderInterop.cs
@@ -145,7 +145,7 @@ namespace Avalonia.Web.Blazor.Interop.Storage
public bool CanBookmark => true;
- public Task SaveBookmark()
+ public Task SaveBookmarkAsync()
{
return FileHandle.InvokeAsync("saveBookmark").AsTask();
}
@@ -155,7 +155,7 @@ namespace Avalonia.Web.Blazor.Interop.Storage
return Task.FromResult(null);
}
- public Task ReleaseBookmark()
+ public Task ReleaseBookmarkAsync()
{
return FileHandle.InvokeAsync("deleteBookmark").AsTask();
}
@@ -174,7 +174,7 @@ namespace Avalonia.Web.Blazor.Interop.Storage
}
public bool CanOpenRead => true;
- public async Task OpenRead()
+ public async Task OpenReadAsync()
{
var stream = await FileHandle.InvokeAsync("openRead");
// Remove maxAllowedSize limit, as developer can decide if they read only small part or everything.
@@ -182,7 +182,7 @@ namespace Avalonia.Web.Blazor.Interop.Storage
}
public bool CanOpenWrite => true;
- public async Task OpenWrite()
+ public async Task OpenWriteAsync()
{
var properties = await FileHandle.InvokeAsync("getProperties");
var streamWriter = await FileHandle.InvokeAsync("openWrite");
@@ -196,5 +196,30 @@ namespace Avalonia.Web.Blazor.Interop.Storage
public JSStorageFolder(IJSInProcessObjectReference fileHandle) : base(fileHandle)
{
}
+
+ public async Task> GetItemsAsync()
+ {
+ var items = await FileHandle.InvokeAsync("getItems");
+ if (items is null)
+ {
+ return Array.Empty();
+ }
+
+ var count = items.Invoke("count");
+
+ return Enumerable.Range(0, count)
+ .Select(index =>
+ {
+ var reference = items.Invoke("at", index);
+ return reference.Invoke("getKind") switch
+ {
+ "directory" => (IStorageItem)new JSStorageFolder(reference),
+ "file" => new JSStorageFile(reference),
+ _ => null
+ };
+ })
+ .Where(i => i is not null)
+ .ToArray()!;
+ }
}
}
diff --git a/src/Web/Avalonia.Web.Blazor/Interop/Typescript/StorageProvider.ts b/src/Web/Avalonia.Web.Blazor/Interop/Typescript/StorageProvider.ts
index c32eef3226..aee74b9067 100644
--- a/src/Web/Avalonia.Web.Blazor/Interop/Typescript/StorageProvider.ts
+++ b/src/Web/Avalonia.Web.Blazor/Interop/Typescript/StorageProvider.ts
@@ -14,6 +14,8 @@ declare global {
queryPermission(options?: { mode: PermissionsMode }): Promise<"granted" | "denied" | "prompt">;
requestPermission(options?: { mode: PermissionsMode }): Promise<"granted" | "denied" | "prompt">;
+
+ entries(): AsyncIterableIterator<[string, FileSystemFileHandle]>;
}
type WellKnownDirectory = "desktop" | "documents" | "downloads" | "music" | "pictures" | "videos";
type StartInDirectory = WellKnownDirectory | FileSystemFileHandle;
@@ -53,7 +55,7 @@ class IndexedDbWrapper {
}
public connect(): Promise {
- var conn = window.indexedDB.open(this.databaseName, 1);
+ const conn = window.indexedDB.open(this.databaseName, 1);
conn.onupgradeneeded = event => {
const db = (>event.target).result;
@@ -85,7 +87,7 @@ class InnerDbConnection {
const os = this.openStore(store, "readwrite");
return new Promise((resolve, reject) => {
- var response = os.put(obj, key);
+ const response = os.put(obj, key);
response.onsuccess = () => {
resolve(response.result);
};
@@ -99,7 +101,7 @@ class InnerDbConnection {
const os = this.openStore(store, "readonly");
return new Promise((resolve, reject) => {
- var response = os.get(key);
+ const response = os.get(key);
response.onsuccess = () => {
resolve(response.result);
};
@@ -113,7 +115,7 @@ class InnerDbConnection {
const os = this.openStore(store, "readwrite");
return new Promise((resolve, reject) => {
- var response = os.delete(key);
+ const response = os.delete(key);
response.onsuccess = () => {
resolve();
};
@@ -134,17 +136,20 @@ const avaloniaDb = new IndexedDbWrapper("AvaloniaDb", [
])
class StorageItem {
- constructor(private handle: FileSystemFileHandle, private bookmarkId?: string) { }
+ constructor(public handle: FileSystemFileHandle, private bookmarkId?: string) { }
public getName(): string {
return this.handle.name
}
+ public getKind(): string {
+ return this.handle.kind;
+ }
+
public async openRead(): Promise {
await this.verityPermissions('read');
- var file = await this.handle.getFile();
- return file;
+ return await this.handle.getFile();
}
public async openWrite(): Promise {
@@ -154,7 +159,7 @@ class StorageItem {
}
public async getProperties(): Promise<{ Size: number, LastModified: number, Type: string }> {
- var file = this.handle.getFile && await this.handle.getFile();
+ const file = this.handle.getFile && await this.handle.getFile();
return file && {
Size: file.size,
@@ -163,6 +168,18 @@ class StorageItem {
}
}
+ public async getItems(): Promise {
+ if (this.handle.kind !== "directory"){
+ return new StorageItems([]);
+ }
+
+ const items: StorageItem[] = [];
+ for await (const [key, value] of this.handle.entries()) {
+ items.push(new StorageItem(value));
+ }
+ return new StorageItems(items);
+ }
+
private async verityPermissions(mode: PermissionsMode): Promise {
if (await this.handle.queryPermission({ mode }) === 'granted') {
return;
@@ -235,12 +252,12 @@ export class StorageProvider {
}
public static async selectFolderDialog(
- startIn: StartInDirectory | null)
+ startIn: StorageItem | null)
: Promise {
// 'Picker' API doesn't accept "null" as a parameter, so it should be set to undefined.
const options: DirectoryPickerOptions = {
- startIn: (startIn || undefined)
+ startIn: (startIn?.handle || undefined)
};
const handle = await window.showDirectoryPicker(options);
@@ -248,12 +265,12 @@ export class StorageProvider {
}
public static async openFileDialog(
- startIn: StartInDirectory | null, multiple: boolean,
+ startIn: StorageItem | null, multiple: boolean,
types: FilePickerAcceptType[] | null, excludeAcceptAllOption: boolean)
: Promise {
const options: OpenFilePickerOptions = {
- startIn: (startIn || undefined),
+ startIn: (startIn?.handle || undefined),
multiple,
excludeAcceptAllOption,
types: (types || undefined)
@@ -264,12 +281,12 @@ export class StorageProvider {
}
public static async saveFileDialog(
- startIn: StartInDirectory | null, suggestedName: string | null,
+ startIn: StorageItem | null, suggestedName: string | null,
types: FilePickerAcceptType[] | null, excludeAcceptAllOption: boolean)
: Promise {
const options: SaveFilePickerOptions = {
- startIn: (startIn || undefined),
+ startIn: (startIn?.handle || undefined),
suggestedName: (suggestedName || undefined),
excludeAcceptAllOption,
types: (types || undefined)
diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
index 7f1af46e97..81fa8c4bce 100644
--- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
+++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using Avalonia.Controls;
@@ -9,7 +8,6 @@ using Avalonia.Direct2D1.Media.Imaging;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
-using Avalonia.Media.Imaging;
using SharpDX.DirectWrite;
using GlyphRun = Avalonia.Media.GlyphRun;
using TextAlignment = Avalonia.Media.TextAlignment;
diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
index a7f1d9c3e5..180ae491b3 100644
--- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
+++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
@@ -614,5 +614,6 @@ namespace Avalonia.Direct2D1.Media
}
public void Custom(ICustomDrawOperation custom) => custom.Render(this);
+ public object GetFeature(Type t) => null;
}
}
diff --git a/src/iOS/Avalonia.iOS/Storage/IOSStorageItem.cs b/src/iOS/Avalonia.iOS/Storage/IOSStorageItem.cs
index 6fb296d0e0..a801e83562 100644
--- a/src/iOS/Avalonia.iOS/Storage/IOSStorageItem.cs
+++ b/src/iOS/Avalonia.iOS/Storage/IOSStorageItem.cs
@@ -1,6 +1,8 @@
using System;
+using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
+using System.Linq;
using System.Threading.Tasks;
using Avalonia.Logging;
using Avalonia.Platform.Storage;
@@ -49,13 +51,13 @@ internal abstract class IOSStorageItem : IStorageBookmarkItem
return Task.FromResult(new IOSStorageFolder(Url.RemoveLastPathComponent()));
}
- public Task ReleaseBookmark()
+ public Task ReleaseBookmarkAsync()
{
// no-op
return Task.CompletedTask;
}
- public Task SaveBookmark()
+ public Task SaveBookmarkAsync()
{
try
{
@@ -102,12 +104,12 @@ internal sealed class IOSStorageFile : IOSStorageItem, IStorageBookmarkFile
public bool CanOpenWrite => true;
- public Task OpenRead()
+ public Task OpenReadAsync()
{
return Task.FromResult(new IOSSecurityScopedStream(Url, FileAccess.Read));
}
- public Task OpenWrite()
+ public Task OpenWriteAsync()
{
return Task.FromResult(new IOSSecurityScopedStream(Url, FileAccess.Write));
}
@@ -118,4 +120,19 @@ internal sealed class IOSStorageFolder : IOSStorageItem, IStorageBookmarkFolder
public IOSStorageFolder(NSUrl url) : base(url)
{
}
+
+ public Task> GetItemsAsync()
+ {
+ var content = NSFileManager.DefaultManager.GetDirectoryContent(Url, null, NSDirectoryEnumerationOptions.None, out var error);
+ if (error is not null)
+ {
+ return Task.FromException>(new NSErrorException(error));
+ }
+
+ var items = content
+ .Select(u => u.HasDirectoryPath ? (IStorageItem)new IOSStorageFolder(u) : new IOSStorageFile(u))
+ .ToArray();
+
+ return Task.FromResult>(items);
+ }
}
diff --git a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj
index 1cf68c1605..f509bb21ba 100644
--- a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj
+++ b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/src/tools/DevGenerators/CompositionGenerator/Generator.KeyFrameAnimation.cs b/src/tools/DevGenerators/CompositionGenerator/Generator.KeyFrameAnimation.cs
index 7ad40f68e4..9455f5fac2 100644
--- a/src/tools/DevGenerators/CompositionGenerator/Generator.KeyFrameAnimation.cs
+++ b/src/tools/DevGenerators/CompositionGenerator/Generator.KeyFrameAnimation.cs
@@ -8,6 +8,8 @@ namespace Avalonia.SourceGenerator.CompositionGenerator
using Avalonia.Rendering.Composition.Animations;
using Avalonia.Rendering.Composition.Expressions;
+// Special license applies License.md
+
namespace Avalonia.Rendering.Composition
{{
";
@@ -56,4 +58,4 @@ namespace Avalonia.Rendering.Composition
_output.AddSource("CompositionAnimations.cs", code);
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs b/tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs
index 705c8fad9c..02012bf62b 100644
--- a/tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs
+++ b/tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs
@@ -408,10 +408,34 @@ public class CompositorHitTestingTests : CompositorTestsBase
s.AssertHitTest(175, 100, null);
}
}
+
+ [Fact]
+ public void HitTest_Should_Not_Hit_Controls_Next_Pixel()
+ {
+ using (var s = new CompositorServices(new Size(200, 200)))
+ {
+ Border targetRectangle;
+
+ var stackPanel = new StackPanel
+ {
+ Orientation = Orientation.Vertical,
+ HorizontalAlignment = HorizontalAlignment.Left,
+ Children =
+ {
+ new Border { Width = 10, Height = 10, Background= Brushes.Red},
+ { targetRectangle = new Border { Width = 10, Height = 10, Background = Brushes.Green} }
+ }
+ };
+
+ s.TopLevel.Content = stackPanel;
+
+ s.AssertHitTest(new Point(5, 10), null, targetRectangle);
+ }
+ }
private IDisposable TestApplication()
{
return UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
}
-}
\ No newline at end of file
+}
diff --git a/tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs b/tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs
index 33c7b3e0f8..d3fdbb63db 100644
--- a/tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs
+++ b/tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs
@@ -537,6 +537,38 @@ namespace Avalonia.Base.UnitTests.Rendering
}
}
+ [Fact]
+ public void HitTest_Should_Not_Hit_Controls_Next_Pixel()
+ {
+ using (TestApplication())
+ {
+ Border targetRectangle;
+
+ var root = new TestRoot
+ {
+ Width = 50,
+ Height = 200,
+ Child = new StackPanel
+ {
+ Orientation = Orientation.Vertical,
+ HorizontalAlignment = HorizontalAlignment.Left,
+ Children =
+ {
+ new Border { Width = 50, Height = 50, Background = Brushes.Red},
+ { targetRectangle = new Border { Width = 50, Height = 50, Background = Brushes.Green} }
+ }
+ }
+ };
+
+ root.Renderer = new DeferredRenderer(root, null);
+ root.Measure(Size.Infinity);
+ root.Arrange(new Rect(root.DesiredSize));
+
+ var result = root.Renderer.HitTest(new Point(25, 50), root, null);
+ Assert.Equal(new[] { targetRectangle }, result);
+ }
+ }
+
private IDisposable TestApplication()
{
return UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
diff --git a/tests/Avalonia.Base.UnitTests/Utilities/UriExtensionsTests.cs b/tests/Avalonia.Base.UnitTests/Utilities/UriExtensionsTests.cs
index 5c3ac6adeb..4a879c8ced 100644
--- a/tests/Avalonia.Base.UnitTests/Utilities/UriExtensionsTests.cs
+++ b/tests/Avalonia.Base.UnitTests/Utilities/UriExtensionsTests.cs
@@ -10,9 +10,9 @@ public class UriExtensionsTests
public void Assembly_Name_From_Query_Parsed()
{
const string key = "assembly";
- const string value = "Avalonia.Themes.Default";
+ const string value = "Avalonia.Themes.Simple";
- var uri = new Uri($"resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?{key}={value}");
+ var uri = new Uri($"resm:Avalonia.Themes.Simple.Accents.BaseLight.xaml?{key}={value}");
var name = uri.GetAssemblyNameFromQuery();
Assert.Equal(value, name);
@@ -21,7 +21,7 @@ public class UriExtensionsTests
[Fact]
public void Assembly_Name_From_Empty_Query_Not_Parsed()
{
- var uri = new Uri("resm:Avalonia.Themes.Default.Accents.BaseLight.xaml");
+ var uri = new Uri("resm:Avalonia.Themes.Simple.Accents.BaseLight.xaml");
var name = uri.GetAssemblyNameFromQuery();
Assert.Equal(string.Empty, name);
diff --git a/tests/Avalonia.Benchmarks/Avalonia.Benchmarks.csproj b/tests/Avalonia.Benchmarks/Avalonia.Benchmarks.csproj
index 5d17808e0c..3f4978f544 100644
--- a/tests/Avalonia.Benchmarks/Avalonia.Benchmarks.csproj
+++ b/tests/Avalonia.Benchmarks/Avalonia.Benchmarks.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/tests/Avalonia.Benchmarks/NullDrawingContextImpl.cs b/tests/Avalonia.Benchmarks/NullDrawingContextImpl.cs
index 6fb2a5ac24..8436881122 100644
--- a/tests/Avalonia.Benchmarks/NullDrawingContextImpl.cs
+++ b/tests/Avalonia.Benchmarks/NullDrawingContextImpl.cs
@@ -1,4 +1,5 @@
-using Avalonia.Media;
+using System;
+using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Rendering.SceneGraph;
using Avalonia.Utilities;
@@ -99,5 +100,7 @@ namespace Avalonia.Benchmarks
public void Custom(ICustomDrawOperation custom)
{
}
+
+ public object GetFeature(Type t) => null;
}
}
diff --git a/tests/Avalonia.Benchmarks/Themes/ThemeBenchmark.cs b/tests/Avalonia.Benchmarks/Themes/ThemeBenchmark.cs
index 9a5b49790d..86ba4c6005 100644
--- a/tests/Avalonia.Benchmarks/Themes/ThemeBenchmark.cs
+++ b/tests/Avalonia.Benchmarks/Themes/ThemeBenchmark.cs
@@ -4,6 +4,8 @@ using Avalonia.Controls;
using Avalonia.Markup.Xaml.Styling;
using Avalonia.Platform;
using Avalonia.Styling;
+using Avalonia.Themes.Fluent;
+using Avalonia.Themes.Simple;
using Avalonia.UnitTests;
using BenchmarkDotNet.Attributes;
@@ -25,32 +27,25 @@ namespace Avalonia.Benchmarks.Themes
}
[Benchmark]
- [Arguments("avares://Avalonia.Themes.Fluent/FluentDark.xaml")]
- [Arguments("avares://Avalonia.Themes.Fluent/FluentLight.xaml")]
- public bool InitFluentTheme(string themeUri)
+ [Arguments(FluentThemeMode.Dark)]
+ [Arguments(FluentThemeMode.Light)]
+ public bool InitFluentTheme(FluentThemeMode mode)
{
- UnitTestApplication.Current.Styles[0] = new StyleInclude(new Uri("resm:Styles?assembly=Avalonia.Benchmarks"))
+ UnitTestApplication.Current.Styles[0] = new FluentTheme(new Uri("resm:Styles?assembly=Avalonia.Benchmarks"))
{
- Source = new Uri(themeUri)
+ Mode = mode
};
return ((IResourceHost)UnitTestApplication.Current).TryGetResource("SystemAccentColor", out _);
}
[Benchmark]
- [Arguments("avares://Avalonia.Themes.Default/Accents/BaseLight.xaml")]
- [Arguments("avares://Avalonia.Themes.Default/Accents/BaseDark.xaml")]
- public bool InitDefaultTheme(string themeUri)
+ [Arguments(SimpleThemeMode.Dark)]
+ [Arguments(SimpleThemeMode.Light)]
+ public bool InitSimpleTheme(SimpleThemeMode mode)
{
- UnitTestApplication.Current.Styles[0] = new Styles
+ UnitTestApplication.Current.Styles[0] = new SimpleTheme(new Uri("resm:Styles?assembly=Avalonia.Benchmarks"))
{
- new StyleInclude(new Uri("resm:Styles?assembly=Avalonia.Benchmarks"))
- {
- Source = new Uri(themeUri)
- },
- new StyleInclude(new Uri("resm:Styles?assembly=Avalonia.Benchmarks"))
- {
- Source = new Uri("avares://Avalonia.Themes.Default/DefaultTheme.xaml")
- }
+ Mode = mode
};
return ((IResourceHost)UnitTestApplication.Current).TryGetResource("ThemeAccentColor", out _);
}
diff --git a/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs
index afa153a593..f6d96edb99 100644
--- a/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs
@@ -9,7 +9,6 @@ using Avalonia.Data;
using Avalonia.Input;
using Avalonia.LogicalTree;
using Avalonia.Styling;
-using Avalonia.Threading;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
using Xunit;
@@ -19,7 +18,7 @@ namespace Avalonia.Controls.UnitTests
public class ListBoxTests
{
private MouseTestHelper _mouse = new MouseTestHelper();
-
+
[Fact]
public void Should_Use_ItemTemplate_To_Create_Item_Content()
{
@@ -433,6 +432,47 @@ namespace Avalonia.Controls.UnitTests
}
}
+ [Fact]
+ public void ListBox_Should_Be_Valid_After_Remove_Of_Item_In_NonVisibleArea()
+ {
+ using (UnitTestApplication.Start(TestServices.StyledWindow))
+ {
+ var items = new AvaloniaList(Enumerable.Range(1, 30).Select(v => v.ToString()));
+
+ var wnd = new Window() { Width = 100, Height = 100, IsVisible = true };
+
+ var target = new ListBox()
+ {
+ AutoScrollToSelectedItem = true,
+ Height = 100,
+ Width = 50,
+ VirtualizationMode = ItemVirtualizationMode.Simple,
+ ItemTemplate = new FuncDataTemplate((c, _) => new Border() { Height = 10 }),
+ Items = items,
+ };
+ wnd.Content = target;
+
+ var lm = wnd.LayoutManager;
+
+ lm.ExecuteInitialLayoutPass();
+
+ //select last / scroll to last item
+ target.SelectedItem = items.Last();
+
+ lm.ExecuteLayoutPass();
+
+ //remove the first item (in non realized area of the listbox)
+ items.Remove("1");
+ lm.ExecuteLayoutPass();
+
+ Assert.Equal("30", target.ItemContainerGenerator.ContainerFromIndex(items.Count - 1).DataContext);
+ Assert.Equal("29", target.ItemContainerGenerator.ContainerFromIndex(items.Count - 2).DataContext);
+ Assert.Equal("28", target.ItemContainerGenerator.ContainerFromIndex(items.Count - 3).DataContext);
+ Assert.Equal("27", target.ItemContainerGenerator.ContainerFromIndex(items.Count - 4).DataContext);
+ Assert.Equal("26", target.ItemContainerGenerator.ContainerFromIndex(items.Count - 5).DataContext);
+ }
+ }
+
[Fact]
public void Clicking_Item_Should_Raise_BringIntoView_For_Correct_Control()
{
@@ -656,7 +696,6 @@ namespace Avalonia.Controls.UnitTests
public string Value { get; }
}
-
[Fact]
public void SelectedItem_Validation()
{
@@ -670,11 +709,11 @@ namespace Avalonia.Controls.UnitTests
};
Prepare(target);
-
+
var exception = new System.InvalidCastException("failed validation");
var textObservable = new BehaviorSubject(new BindingNotification(exception, BindingErrorType.DataValidationError));
target.Bind(ComboBox.SelectedItemProperty, textObservable);
-
+
Assert.True(DataValidationErrors.GetHasErrors(target));
Assert.True(DataValidationErrors.GetErrors(target).SequenceEqual(new[] { exception }));
}
diff --git a/tests/Avalonia.Controls.UnitTests/ListBoxTests_Single.cs b/tests/Avalonia.Controls.UnitTests/ListBoxTests_Single.cs
index 8f795104bf..bf516748cc 100644
--- a/tests/Avalonia.Controls.UnitTests/ListBoxTests_Single.cs
+++ b/tests/Avalonia.Controls.UnitTests/ListBoxTests_Single.cs
@@ -5,10 +5,12 @@ using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Input;
+using Avalonia.Input.Platform;
using Avalonia.LogicalTree;
using Avalonia.Styling;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
+using Moq;
using Xunit;
namespace Avalonia.Controls.UnitTests
@@ -60,104 +62,123 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Clicking_Item_Should_Select_It()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = new FuncControlTemplate(CreateListBoxTemplate),
- Items = new[] { "Foo", "Bar", "Baz " },
- };
-
- ApplyTemplate(target);
- _mouse.Click(target.Presenter.Panel.Children[0]);
-
- Assert.Equal(0, target.SelectedIndex);
+ var target = new ListBox
+ {
+ Template = new FuncControlTemplate(CreateListBoxTemplate),
+ Items = new[] { "Foo", "Bar", "Baz " },
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ ApplyTemplate(target);
+ _mouse.Click(target.Presenter.Panel.Children[0]);
+
+ Assert.Equal(0, target.SelectedIndex);
+ }
}
[Fact]
public void Clicking_Selected_Item_Should_Not_Deselect_It()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = new FuncControlTemplate(CreateListBoxTemplate),
- Items = new[] { "Foo", "Bar", "Baz " },
- };
-
- ApplyTemplate(target);
- target.SelectedIndex = 0;
+ var target = new ListBox
+ {
+ Template = new FuncControlTemplate(CreateListBoxTemplate),
+ Items = new[] { "Foo", "Bar", "Baz " },
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ ApplyTemplate(target);
+ target.SelectedIndex = 0;
- _mouse.Click(target.Presenter.Panel.Children[0]);
+ _mouse.Click(target.Presenter.Panel.Children[0]);
- Assert.Equal(0, target.SelectedIndex);
+ Assert.Equal(0, target.SelectedIndex);
+ }
}
[Fact]
public void Clicking_Item_Should_Select_It_When_SelectionMode_Toggle()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = new FuncControlTemplate(CreateListBoxTemplate),
- Items = new[] { "Foo", "Bar", "Baz " },
- SelectionMode = SelectionMode.Single | SelectionMode.Toggle,
- };
-
- ApplyTemplate(target);
+ var target = new ListBox
+ {
+ Template = new FuncControlTemplate(CreateListBoxTemplate),
+ Items = new[] { "Foo", "Bar", "Baz " },
+ SelectionMode = SelectionMode.Single | SelectionMode.Toggle,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ ApplyTemplate(target);
- _mouse.Click(target.Presenter.Panel.Children[0]);
+ _mouse.Click(target.Presenter.Panel.Children[0]);
- Assert.Equal(0, target.SelectedIndex);
+ Assert.Equal(0, target.SelectedIndex);
+ }
}
[Fact]
public void Clicking_Selected_Item_Should_Deselect_It_When_SelectionMode_Toggle()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = new FuncControlTemplate(CreateListBoxTemplate),
- Items = new[] { "Foo", "Bar", "Baz " },
- SelectionMode = SelectionMode.Toggle,
- };
+ var target = new ListBox
+ {
+ Template = new FuncControlTemplate(CreateListBoxTemplate),
+ Items = new[] { "Foo", "Bar", "Baz " },
+ SelectionMode = SelectionMode.Toggle,
+ };
- ApplyTemplate(target);
- target.SelectedIndex = 0;
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ ApplyTemplate(target);
+ target.SelectedIndex = 0;
- _mouse.Click(target.Presenter.Panel.Children[0]);
+ _mouse.Click(target.Presenter.Panel.Children[0]);
- Assert.Equal(-1, target.SelectedIndex);
+ Assert.Equal(-1, target.SelectedIndex);
+ }
}
[Fact]
public void Clicking_Selected_Item_Should_Not_Deselect_It_When_SelectionMode_ToggleAlwaysSelected()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = new FuncControlTemplate(CreateListBoxTemplate),
- Items = new[] { "Foo", "Bar", "Baz " },
- SelectionMode = SelectionMode.Toggle | SelectionMode.AlwaysSelected,
- };
-
- ApplyTemplate(target);
- target.SelectedIndex = 0;
+ var target = new ListBox
+ {
+ Template = new FuncControlTemplate(CreateListBoxTemplate),
+ Items = new[] { "Foo", "Bar", "Baz " },
+ SelectionMode = SelectionMode.Toggle | SelectionMode.AlwaysSelected,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ ApplyTemplate(target);
+ target.SelectedIndex = 0;
- _mouse.Click(target.Presenter.Panel.Children[0]);
+ _mouse.Click(target.Presenter.Panel.Children[0]);
- Assert.Equal(0, target.SelectedIndex);
+ Assert.Equal(0, target.SelectedIndex);
+ }
}
[Fact]
public void Clicking_Another_Item_Should_Select_It_When_SelectionMode_Toggle()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = new FuncControlTemplate(CreateListBoxTemplate),
- Items = new[] { "Foo", "Bar", "Baz " },
- SelectionMode = SelectionMode.Single | SelectionMode.Toggle,
- };
-
- ApplyTemplate(target);
- target.SelectedIndex = 1;
+ var target = new ListBox
+ {
+ Template = new FuncControlTemplate(CreateListBoxTemplate),
+ Items = new[] { "Foo", "Bar", "Baz " },
+ SelectionMode = SelectionMode.Single | SelectionMode.Toggle,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ ApplyTemplate(target);
+ target.SelectedIndex = 1;
- _mouse.Click(target.Presenter.Panel.Children[0]);
+ _mouse.Click(target.Presenter.Panel.Children[0]);
- Assert.Equal(0, target.SelectedIndex);
+ Assert.Equal(0, target.SelectedIndex);
+ }
}
[Fact]
diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
index 4b6b6a1182..330cbfd7b9 100644
--- a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
@@ -14,6 +14,7 @@ using Avalonia.Controls.Selection;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Input;
+using Avalonia.Input.Platform;
using Avalonia.Interactivity;
using Avalonia.Markup.Data;
using Avalonia.Platform;
@@ -1115,42 +1116,48 @@ namespace Avalonia.Controls.UnitTests.Primitives
[Fact]
public void Setting_SelectedItem_With_Pointer_Should_Set_TabOnceActiveElement()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz " },
- };
-
- Prepare(target);
- _helper.Down((Interactive)target.Presenter.Panel.Children[1]);
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz " },
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ Prepare(target);
+ _helper.Down((Interactive)target.Presenter.Panel.Children[1]);
- var panel = target.Presenter.Panel;
+ var panel = target.Presenter.Panel;
- Assert.Equal(
- KeyboardNavigation.GetTabOnceActiveElement((InputElement)panel),
- panel.Children[1]);
+ Assert.Equal(
+ KeyboardNavigation.GetTabOnceActiveElement((InputElement)panel),
+ panel.Children[1]);
+ }
}
[Fact]
public void Removing_SelectedItem_Should_Clear_TabOnceActiveElement()
{
- var items = new ObservableCollection(new[] { "Foo", "Bar", "Baz " });
-
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = items,
- };
+ var items = new ObservableCollection(new[] { "Foo", "Bar", "Baz " });
- Prepare(target);
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = items,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ Prepare(target);
- _helper.Down(target.Presenter.Panel.Children[1]);
+ _helper.Down(target.Presenter.Panel.Children[1]);
- items.RemoveAt(1);
+ items.RemoveAt(1);
- var panel = target.Presenter.Panel;
+ var panel = target.Presenter.Panel;
- Assert.Null(KeyboardNavigation.GetTabOnceActiveElement((InputElement)panel));
+ Assert.Null(KeyboardNavigation.GetTabOnceActiveElement((InputElement)panel));
+ }
}
[Fact]
@@ -1230,31 +1237,37 @@ namespace Avalonia.Controls.UnitTests.Primitives
[Fact]
public void Should_Select_Correct_Item_When_Duplicate_Items_Are_Present()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
- };
-
- Prepare(target);
- _helper.Down((Interactive)target.Presenter.Panel.Children[3]);
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ Prepare(target);
+ _helper.Down((Interactive)target.Presenter.Panel.Children[3]);
- Assert.Equal(3, target.SelectedIndex);
+ Assert.Equal(3, target.SelectedIndex);
+ }
}
[Fact]
public void Should_Apply_Selected_Pseudoclass_To_Correct_Item_When_Duplicate_Items_Are_Present()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
- };
-
- Prepare(target);
- _helper.Down((Interactive)target.Presenter.Panel.Children[3]);
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ Prepare(target);
+ _helper.Down((Interactive)target.Presenter.Panel.Children[3]);
- Assert.Equal(new[] { ":pressed", ":selected" }, target.Presenter.Panel.Children[3].Classes);
+ Assert.Equal(new[] { ":pressed", ":selected" }, target.Presenter.Panel.Children[3].Classes);
+ }
}
[Fact]
diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs
index 6b26d76371..5d2f4e2a64 100644
--- a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs
+++ b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs
@@ -10,8 +10,10 @@ using Avalonia.Controls.Selection;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Input;
+using Avalonia.Input.Platform;
using Avalonia.Interactivity;
using Avalonia.UnitTests;
+using Moq;
using Xunit;
namespace Avalonia.Controls.UnitTests.Primitives
@@ -701,261 +703,290 @@ namespace Avalonia.Controls.UnitTests.Primitives
[Fact]
public void Shift_Selecting_From_No_Selection_Selects_From_Start()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz" },
- SelectionMode = SelectionMode.Multiple,
- };
-
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
- _helper.Click((Interactive)target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Shift);
-
- var panel = target.Presenter.Panel;
-
- Assert.Equal(new[] { "Foo", "Bar", "Baz" }, target.SelectedItems);
- Assert.Equal(new[] { 0, 1, 2 }, SelectedContainers(target));
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz" },
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
+ _helper.Click((Interactive)target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Shift);
+
+ var panel = target.Presenter.Panel;
+
+ Assert.Equal(new[] { "Foo", "Bar", "Baz" }, target.SelectedItems);
+ Assert.Equal(new[] { 0, 1, 2 }, SelectedContainers(target));
+ }
}
[Fact]
public void Ctrl_Selecting_Raises_SelectionChanged_Events()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz", "Qux" },
- SelectionMode = SelectionMode.Multiple,
- };
-
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz", "Qux" },
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
- SelectionChangedEventArgs receivedArgs = null;
+ SelectionChangedEventArgs receivedArgs = null;
- target.SelectionChanged += (_, args) => receivedArgs = args;
+ target.SelectionChanged += (_, args) => receivedArgs = args;
- void VerifyAdded(string selection)
- {
- Assert.NotNull(receivedArgs);
- Assert.Equal(new[] { selection }, receivedArgs.AddedItems);
- Assert.Empty(receivedArgs.RemovedItems);
- }
+ void VerifyAdded(string selection)
+ {
+ Assert.NotNull(receivedArgs);
+ Assert.Equal(new[] { selection }, receivedArgs.AddedItems);
+ Assert.Empty(receivedArgs.RemovedItems);
+ }
- void VerifyRemoved(string selection)
- {
- Assert.NotNull(receivedArgs);
- Assert.Equal(new[] { selection }, receivedArgs.RemovedItems);
- Assert.Empty(receivedArgs.AddedItems);
- }
+ void VerifyRemoved(string selection)
+ {
+ Assert.NotNull(receivedArgs);
+ Assert.Equal(new[] { selection }, receivedArgs.RemovedItems);
+ Assert.Empty(receivedArgs.AddedItems);
+ }
- _helper.Click((Interactive)target.Presenter.Panel.Children[1]);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[1]);
- VerifyAdded("Bar");
+ VerifyAdded("Bar");
- receivedArgs = null;
- _helper.Click((Interactive)target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
+ receivedArgs = null;
+ _helper.Click((Interactive)target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
- VerifyAdded("Baz");
+ VerifyAdded("Baz");
- receivedArgs = null;
- _helper.Click((Interactive)target.Presenter.Panel.Children[3], modifiers: KeyModifiers.Control);
+ receivedArgs = null;
+ _helper.Click((Interactive)target.Presenter.Panel.Children[3], modifiers: KeyModifiers.Control);
- VerifyAdded("Qux");
+ VerifyAdded("Qux");
- receivedArgs = null;
- _helper.Click((Interactive)target.Presenter.Panel.Children[1], modifiers: KeyModifiers.Control);
+ receivedArgs = null;
+ _helper.Click((Interactive)target.Presenter.Panel.Children[1], modifiers: KeyModifiers.Control);
- VerifyRemoved("Bar");
+ VerifyRemoved("Bar");
+ }
}
[Fact]
public void Ctrl_Selecting_SelectedItem_With_Multiple_Selection_Active_Sets_SelectedItem_To_Next_Selection()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz", "Qux" },
- SelectionMode = SelectionMode.Multiple,
- };
-
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
- _helper.Click((Interactive)target.Presenter.Panel.Children[1]);
- _helper.Click((Interactive)target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
- _helper.Click((Interactive)target.Presenter.Panel.Children[3], modifiers: KeyModifiers.Control);
-
- Assert.Equal(1, target.SelectedIndex);
- Assert.Equal("Bar", target.SelectedItem);
- Assert.Equal(new[] { "Bar", "Baz", "Qux" }, target.SelectedItems);
-
- _helper.Click((Interactive)target.Presenter.Panel.Children[1], modifiers: KeyModifiers.Control);
-
- Assert.Equal(2, target.SelectedIndex);
- Assert.Equal("Baz", target.SelectedItem);
- Assert.Equal(new[] { "Baz", "Qux" }, target.SelectedItems);
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz", "Qux" },
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
+ _helper.Click((Interactive)target.Presenter.Panel.Children[1]);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[3], modifiers: KeyModifiers.Control);
+
+ Assert.Equal(1, target.SelectedIndex);
+ Assert.Equal("Bar", target.SelectedItem);
+ Assert.Equal(new[] { "Bar", "Baz", "Qux" }, target.SelectedItems);
+
+ _helper.Click((Interactive)target.Presenter.Panel.Children[1], modifiers: KeyModifiers.Control);
+
+ Assert.Equal(2, target.SelectedIndex);
+ Assert.Equal("Baz", target.SelectedItem);
+ Assert.Equal(new[] { "Baz", "Qux" }, target.SelectedItems);
+ }
}
[Fact]
public void Ctrl_Selecting_Non_SelectedItem_With_Multiple_Selection_Active_Leaves_SelectedItem_The_Same()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz" },
- SelectionMode = SelectionMode.Multiple,
- };
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz" },
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
- _helper.Click((Interactive)target.Presenter.Panel.Children[1]);
- _helper.Click((Interactive)target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
+ _helper.Click((Interactive)target.Presenter.Panel.Children[1]);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
- Assert.Equal(1, target.SelectedIndex);
- Assert.Equal("Bar", target.SelectedItem);
+ Assert.Equal(1, target.SelectedIndex);
+ Assert.Equal("Bar", target.SelectedItem);
- _helper.Click((Interactive)target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
- Assert.Equal(1, target.SelectedIndex);
- Assert.Equal("Bar", target.SelectedItem);
+ Assert.Equal(1, target.SelectedIndex);
+ Assert.Equal("Bar", target.SelectedItem);
+ }
}
[Fact]
public void Should_Ctrl_Select_Correct_Item_When_Duplicate_Items_Are_Present()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
- SelectionMode = SelectionMode.Multiple,
- };
-
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
- _helper.Click((Interactive)target.Presenter.Panel.Children[3]);
- _helper.Click((Interactive)target.Presenter.Panel.Children[4], modifiers: KeyModifiers.Control);
-
- var panel = target.Presenter.Panel;
-
- Assert.Equal(new[] { "Foo", "Bar" }, target.SelectedItems);
- Assert.Equal(new[] { 3, 4 }, SelectedContainers(target));
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
+ _helper.Click((Interactive)target.Presenter.Panel.Children[3]);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[4], modifiers: KeyModifiers.Control);
+
+ var panel = target.Presenter.Panel;
+
+ Assert.Equal(new[] { "Foo", "Bar" }, target.SelectedItems);
+ Assert.Equal(new[] { 3, 4 }, SelectedContainers(target));
+ }
}
[Fact]
public void Should_Shift_Select_Correct_Item_When_Duplicates_Are_Present()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
- SelectionMode = SelectionMode.Multiple,
- };
-
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
- _helper.Click((Interactive)target.Presenter.Panel.Children[3]);
- _helper.Click((Interactive)target.Presenter.Panel.Children[5], modifiers: KeyModifiers.Shift);
-
- var panel = target.Presenter.Panel;
-
- Assert.Equal(new[] { "Foo", "Bar", "Baz" }, target.SelectedItems);
- Assert.Equal(new[] { 3, 4, 5 }, SelectedContainers(target));
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
+ _helper.Click((Interactive)target.Presenter.Panel.Children[3]);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[5], modifiers: KeyModifiers.Shift);
+
+ var panel = target.Presenter.Panel;
+
+ Assert.Equal(new[] { "Foo", "Bar", "Baz" }, target.SelectedItems);
+ Assert.Equal(new[] { 3, 4, 5 }, SelectedContainers(target));
+ }
}
[Fact]
public void Can_Shift_Select_All_Items_When_Duplicates_Are_Present()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
- SelectionMode = SelectionMode.Multiple,
- };
-
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
- _helper.Click((Interactive)target.Presenter.Panel.Children[0]);
- _helper.Click((Interactive)target.Presenter.Panel.Children[5], modifiers: KeyModifiers.Shift);
-
- var panel = target.Presenter.Panel;
-
- Assert.Equal(new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" }, target.SelectedItems);
- Assert.Equal(new[] { 0, 1, 2, 3, 4, 5 }, SelectedContainers(target));
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
+ _helper.Click((Interactive)target.Presenter.Panel.Children[0]);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[5], modifiers: KeyModifiers.Shift);
+
+ var panel = target.Presenter.Panel;
+
+ Assert.Equal(new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" }, target.SelectedItems);
+ Assert.Equal(new[] { 0, 1, 2, 3, 4, 5 }, SelectedContainers(target));
+ }
}
[Fact]
public void Shift_Selecting_Raises_SelectionChanged_Events()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz", "Qux" },
- SelectionMode = SelectionMode.Multiple,
- };
-
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz", "Qux" },
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
- SelectionChangedEventArgs receivedArgs = null;
+ SelectionChangedEventArgs receivedArgs = null;
- target.SelectionChanged += (_, args) => receivedArgs = args;
+ target.SelectionChanged += (_, args) => receivedArgs = args;
- void VerifyAdded(params string[] selection)
- {
- Assert.NotNull(receivedArgs);
- Assert.Equal(selection, receivedArgs.AddedItems);
- Assert.Empty(receivedArgs.RemovedItems);
- }
+ void VerifyAdded(params string[] selection)
+ {
+ Assert.NotNull(receivedArgs);
+ Assert.Equal(selection, receivedArgs.AddedItems);
+ Assert.Empty(receivedArgs.RemovedItems);
+ }
- void VerifyRemoved(string selection)
- {
- Assert.NotNull(receivedArgs);
- Assert.Equal(new[] { selection }, receivedArgs.RemovedItems);
- Assert.Empty(receivedArgs.AddedItems);
- }
+ void VerifyRemoved(string selection)
+ {
+ Assert.NotNull(receivedArgs);
+ Assert.Equal(new[] { selection }, receivedArgs.RemovedItems);
+ Assert.Empty(receivedArgs.AddedItems);
+ }
- _helper.Click((Interactive)target.Presenter.Panel.Children[1]);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[1]);
- VerifyAdded("Bar");
+ VerifyAdded("Bar");
- receivedArgs = null;
- _helper.Click((Interactive)target.Presenter.Panel.Children[3], modifiers: KeyModifiers.Shift);
+ receivedArgs = null;
+ _helper.Click((Interactive)target.Presenter.Panel.Children[3], modifiers: KeyModifiers.Shift);
- VerifyAdded("Baz" ,"Qux");
+ VerifyAdded("Baz", "Qux");
- receivedArgs = null;
- _helper.Click((Interactive)target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Shift);
+ receivedArgs = null;
+ _helper.Click((Interactive)target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Shift);
- VerifyRemoved("Qux");
+ VerifyRemoved("Qux");
+ }
}
[Fact]
public void Duplicate_Items_Are_Added_To_SelectedItems_In_Order()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
- SelectionMode = SelectionMode.Multiple,
- };
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
+ SelectionMode = SelectionMode.Multiple,
+ };
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
- _helper.Click((Interactive)target.Presenter.Panel.Children[0]);
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
+ _helper.Click((Interactive)target.Presenter.Panel.Children[0]);
- Assert.Equal(new[] { "Foo" }, target.SelectedItems);
+ Assert.Equal(new[] { "Foo" }, target.SelectedItems);
- _helper.Click((Interactive)target.Presenter.Panel.Children[4], modifiers: KeyModifiers.Control);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[4], modifiers: KeyModifiers.Control);
- Assert.Equal(new[] { "Foo", "Bar" }, target.SelectedItems);
+ Assert.Equal(new[] { "Foo", "Bar" }, target.SelectedItems);
- _helper.Click((Interactive)target.Presenter.Panel.Children[3], modifiers: KeyModifiers.Control);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[3], modifiers: KeyModifiers.Control);
- Assert.Equal(new[] { "Foo", "Bar", "Foo" }, target.SelectedItems);
+ Assert.Equal(new[] { "Foo", "Bar", "Foo" }, target.SelectedItems);
- _helper.Click((Interactive)target.Presenter.Panel.Children[1], modifiers: KeyModifiers.Control);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[1], modifiers: KeyModifiers.Control);
- Assert.Equal(new[] { "Foo", "Bar", "Foo", "Bar" }, target.SelectedItems);
+ Assert.Equal(new[] { "Foo", "Bar", "Foo", "Bar" }, target.SelectedItems);
+ }
}
[Fact]
@@ -1158,70 +1189,79 @@ namespace Avalonia.Controls.UnitTests.Primitives
[Fact]
public void Left_Click_On_SelectedItem_Should_Clear_Existing_Selection()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz" },
- ItemTemplate = new FuncDataTemplate((x, _) => new TextBlock { Width = 20, Height = 10 }),
- SelectionMode = SelectionMode.Multiple,
- };
-
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
- target.SelectAll();
-
- Assert.Equal(3, target.SelectedItems.Count);
-
- _helper.Click((Interactive)target.Presenter.Panel.Children[0]);
-
- Assert.Equal(1, target.SelectedItems.Count);
- Assert.Equal(new[] { "Foo", }, target.SelectedItems);
- Assert.Equal(new[] { 0 }, SelectedContainers(target));
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz" },
+ ItemTemplate = new FuncDataTemplate((x, _) => new TextBlock { Width = 20, Height = 10 }),
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
+ target.SelectAll();
+
+ Assert.Equal(3, target.SelectedItems.Count);
+
+ _helper.Click((Interactive)target.Presenter.Panel.Children[0]);
+
+ Assert.Equal(1, target.SelectedItems.Count);
+ Assert.Equal(new[] { "Foo", }, target.SelectedItems);
+ Assert.Equal(new[] { 0 }, SelectedContainers(target));
+ }
}
[Fact]
public void Right_Click_On_SelectedItem_Should_Not_Clear_Existing_Selection()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz" },
- ItemTemplate = new FuncDataTemplate((x, _) => new TextBlock { Width = 20, Height = 10 }),
- SelectionMode = SelectionMode.Multiple,
- };
-
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
- target.SelectAll();
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz" },
+ ItemTemplate = new FuncDataTemplate((x, _) => new TextBlock { Width = 20, Height = 10 }),
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
+ target.SelectAll();
- Assert.Equal(3, target.SelectedItems.Count);
+ Assert.Equal(3, target.SelectedItems.Count);
- _helper.Click((Interactive)target.Presenter.Panel.Children[0], MouseButton.Right);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[0], MouseButton.Right);
- Assert.Equal(3, target.SelectedItems.Count);
+ Assert.Equal(3, target.SelectedItems.Count);
+ }
}
[Fact]
public void Right_Click_On_UnselectedItem_Should_Clear_Existing_Selection()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz" },
- ItemTemplate = new FuncDataTemplate((x, _) => new TextBlock { Width = 20, Height = 10 }),
- SelectionMode = SelectionMode.Multiple,
- };
-
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
- _helper.Click((Interactive)target.Presenter.Panel.Children[0]);
- _helper.Click((Interactive)target.Presenter.Panel.Children[1], modifiers: KeyModifiers.Shift);
-
- Assert.Equal(2, target.SelectedItems.Count);
-
- _helper.Click((Interactive)target.Presenter.Panel.Children[2], MouseButton.Right);
-
- Assert.Equal(1, target.SelectedItems.Count);
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz" },
+ ItemTemplate = new FuncDataTemplate((x, _) => new TextBlock { Width = 20, Height = 10 }),
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
+ _helper.Click((Interactive)target.Presenter.Panel.Children[0]);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[1], modifiers: KeyModifiers.Shift);
+
+ Assert.Equal(2, target.SelectedItems.Count);
+
+ _helper.Click((Interactive)target.Presenter.Panel.Children[2], MouseButton.Right);
+
+ Assert.Equal(1, target.SelectedItems.Count);
+ }
}
[Fact]
@@ -1253,41 +1293,47 @@ namespace Avalonia.Controls.UnitTests.Primitives
[Fact]
public void Shift_Right_Click_Should_Not_Select_Multiple()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz" },
- ItemTemplate = new FuncDataTemplate((x, _) => new TextBlock { Width = 20, Height = 10 }),
- SelectionMode = SelectionMode.Multiple,
- };
-
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
-
- _helper.Click((Interactive)target.Presenter.Panel.Children[0]);
- _helper.Click((Interactive)target.Presenter.Panel.Children[2], MouseButton.Right, modifiers: KeyModifiers.Shift);
-
- Assert.Equal(1, target.SelectedItems.Count);
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz" },
+ ItemTemplate = new FuncDataTemplate((x, _) => new TextBlock { Width = 20, Height = 10 }),
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
+
+ _helper.Click((Interactive)target.Presenter.Panel.Children[0]);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[2], MouseButton.Right, modifiers: KeyModifiers.Shift);
+
+ Assert.Equal(1, target.SelectedItems.Count);
+ }
}
[Fact]
public void Ctrl_Right_Click_Should_Not_Select_Multiple()
{
- var target = new ListBox
+ using (UnitTestApplication.Start())
{
- Template = Template(),
- Items = new[] { "Foo", "Bar", "Baz" },
- ItemTemplate = new FuncDataTemplate((x, _) => new TextBlock { Width = 20, Height = 10 }),
- SelectionMode = SelectionMode.Multiple,
- };
-
- target.ApplyTemplate();
- target.Presenter.ApplyTemplate();
-
- _helper.Click((Interactive)target.Presenter.Panel.Children[0]);
- _helper.Click((Interactive)target.Presenter.Panel.Children[2], MouseButton.Right, modifiers: KeyModifiers.Control);
-
- Assert.Equal(1, target.SelectedItems.Count);
+ var target = new ListBox
+ {
+ Template = Template(),
+ Items = new[] { "Foo", "Bar", "Baz" },
+ ItemTemplate = new FuncDataTemplate((x, _) => new TextBlock { Width = 20, Height = 10 }),
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ target.ApplyTemplate();
+ target.Presenter.ApplyTemplate();
+
+ _helper.Click((Interactive)target.Presenter.Panel.Children[0]);
+ _helper.Click((Interactive)target.Presenter.Panel.Children[2], MouseButton.Right, modifiers: KeyModifiers.Control);
+
+ Assert.Equal(1, target.SelectedItems.Count);
+ }
}
[Fact]
diff --git a/tests/Avalonia.Controls.UnitTests/RichTextBlockTests.cs b/tests/Avalonia.Controls.UnitTests/RichTextBlockTests.cs
index eb4b88956d..c74f13b808 100644
--- a/tests/Avalonia.Controls.UnitTests/RichTextBlockTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/RichTextBlockTests.cs
@@ -48,5 +48,49 @@ namespace Avalonia.Controls.UnitTests
Assert.False(target.IsMeasureValid);
}
}
+
+ [Fact]
+ public void Changing_Inlines_Should_Invalidate_Measure()
+ {
+ using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
+ {
+ var target = new RichTextBlock();
+
+ var inlines = new InlineCollection { new Run("Hello") };
+
+ target.Measure(Size.Infinity);
+
+ Assert.True(target.IsMeasureValid);
+
+ target.Inlines = inlines;
+
+ Assert.False(target.IsMeasureValid);
+ }
+ }
+
+ [Fact]
+ public void Changing_Inlines_Should_Reset_Inlines_Parent()
+ {
+ using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
+ {
+ var target = new RichTextBlock();
+
+ var run = new Run("Hello");
+
+ target.Inlines.Add(run);
+
+ target.Measure(Size.Infinity);
+
+ Assert.True(target.IsMeasureValid);
+
+ target.Inlines = null;
+
+ Assert.Null(run.Parent);
+
+ target.Inlines = new InlineCollection { run };
+
+ Assert.Equal(target, run.Parent);
+ }
+ }
}
}
diff --git a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs
index d784caf2db..9cf21423a3 100644
--- a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs
@@ -18,6 +18,7 @@ using Avalonia.LogicalTree;
using Avalonia.Styling;
using Avalonia.UnitTests;
using JetBrains.Annotations;
+using Moq;
using Xunit;
namespace Avalonia.Controls.UnitTests
@@ -885,28 +886,31 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Right_Click_On_SelectedItem_Should_Not_Clear_Existing_Selection()
{
- var tree = CreateTestTreeData();
- var target = new TreeView
+ using (UnitTestApplication.Start())
{
- Template = CreateTreeViewTemplate(),
- Items = tree,
- SelectionMode = SelectionMode.Multiple,
- };
-
- var visualRoot = new TestRoot();
- visualRoot.Child = target;
+ var tree = CreateTestTreeData();
+ var target = new TreeView
+ {
+ Template = CreateTreeViewTemplate(),
+ Items = tree,
+ SelectionMode = SelectionMode.Multiple,
+ };
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(new Mock().Object);
+ var visualRoot = new TestRoot();
+ visualRoot.Child = target;
- CreateNodeDataTemplate(target);
- ApplyTemplates(target);
- target.ExpandSubTree((TreeViewItem)target.Presenter.Panel.Children[0]);
- target.SelectAll();
+ CreateNodeDataTemplate(target);
+ ApplyTemplates(target);
+ target.ExpandSubTree((TreeViewItem)target.Presenter.Panel.Children[0]);
+ target.SelectAll();
- AssertChildrenSelected(target, tree[0]);
- Assert.Equal(5, target.SelectedItems.Count);
+ AssertChildrenSelected(target, tree[0]);
+ Assert.Equal(5, target.SelectedItems.Count);
- _mouse.Click((Interactive)target.Presenter.Panel.Children[0], MouseButton.Right);
+ _mouse.Click((Interactive)target.Presenter.Panel.Children[0], MouseButton.Right);
- Assert.Equal(5, target.SelectedItems.Count);
+ Assert.Equal(5, target.SelectedItems.Count);
+ }
}
[Fact]
diff --git a/tests/Avalonia.DesignerSupport.TestApp/App.xaml b/tests/Avalonia.DesignerSupport.TestApp/App.xaml
index 5a33ffff80..ad32431b37 100644
--- a/tests/Avalonia.DesignerSupport.TestApp/App.xaml
+++ b/tests/Avalonia.DesignerSupport.TestApp/App.xaml
@@ -1,10 +1,7 @@
-
-
-
-
-
-
+
+
+
+
diff --git a/tests/Avalonia.DesignerSupport.TestApp/Avalonia.DesignerSupport.TestApp.csproj b/tests/Avalonia.DesignerSupport.TestApp/Avalonia.DesignerSupport.TestApp.csproj
index f66b2b0457..278b0e087e 100644
--- a/tests/Avalonia.DesignerSupport.TestApp/Avalonia.DesignerSupport.TestApp.csproj
+++ b/tests/Avalonia.DesignerSupport.TestApp/Avalonia.DesignerSupport.TestApp.csproj
@@ -21,7 +21,7 @@
-
+
diff --git a/tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj b/tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj
index 52acc78db1..4a90da77e7 100644
--- a/tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj
+++ b/tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj
@@ -13,7 +13,7 @@
-
+
diff --git a/tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj b/tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj
index a00b24bdd7..4572f7ae7c 100644
--- a/tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj
+++ b/tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj
@@ -15,7 +15,7 @@
-
+
diff --git a/tests/Avalonia.Markup.UnitTests/Data/TemplateBindingTests.cs b/tests/Avalonia.Markup.UnitTests/Data/TemplateBindingTests.cs
index d9ea3e374c..979dbec674 100644
--- a/tests/Avalonia.Markup.UnitTests/Data/TemplateBindingTests.cs
+++ b/tests/Avalonia.Markup.UnitTests/Data/TemplateBindingTests.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Avalonia.Controls;
@@ -217,6 +218,37 @@ namespace Avalonia.Markup.UnitTests.Data
}
}
+ [Fact]
+ public void Should_Not_Pass_UnsetValue_To_MultiBinding_During_ApplyTemplate()
+ {
+ var converter = new MultiConverter();
+ var source = new Button
+ {
+ Content = "foo",
+ Template = new FuncControlTemplate