diff --git a/Avalonia.sln.DotSettings b/Avalonia.sln.DotSettings
index 7060f4a62a..25d62b0494 100644
--- a/Avalonia.sln.DotSettings
+++ b/Avalonia.sln.DotSettings
@@ -37,4 +37,5 @@
<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
<Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" />
<Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" />
+ True
True
\ No newline at end of file
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 721a0415f4..e67fa14c57 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -31,6 +31,8 @@ jobs:
condition: not(canceled())
- job: macOS
+ variables:
+ SolutionDir: '$(Build.SourcesDirectory)'
pool:
vmImage: 'macOS-10.14'
steps:
@@ -97,6 +99,8 @@ jobs:
- job: Windows
pool:
vmImage: 'windows-2019'
+ variables:
+ SolutionDir: '$(Build.SourcesDirectory)'
steps:
- task: UseDotNet@2
displayName: 'Use .NET Core SDK 3.1.401'
diff --git a/build.ps1 b/build.ps1
index 57e2f80075..3672e82d3b 100644
--- a/build.ps1
+++ b/build.ps1
@@ -62,6 +62,8 @@ else {
} else {
ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath }
}
+
+ $env:PATH="$DotNetDirectory;$env:PATH"
}
Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)"
diff --git a/build/ApiDiff.props b/build/ApiDiff.props
index da82fbcc51..3d322f56d5 100644
--- a/build/ApiDiff.props
+++ b/build/ApiDiff.props
@@ -7,6 +7,6 @@
-
+
diff --git a/build/Assets/Icon.png b/build/Assets/Icon.png
new file mode 100644
index 0000000000..41a2a618fb
Binary files /dev/null and b/build/Assets/Icon.png differ
diff --git a/build/SharedVersion.props b/build/SharedVersion.props
index d3cebef418..a5c0aa1bea 100644
--- a/build/SharedVersion.props
+++ b/build/SharedVersion.props
@@ -10,10 +10,17 @@
CS1591
latest
MIT
- https://avatars2.githubusercontent.com/u/14075148?s=200
+ Icon.png
Avalonia is a WPF/UWP-inspired cross-platform XAML-based UI framework providing a flexible styling system and supporting a wide range of Operating Systems such as Windows (.NET Framework, .NET Core), Linux (via Xorg), MacOS and with experimental support for Android and iOS.
avalonia;avaloniaui;mvvm;rx;reactive extensions;android;ios;mac;forms;wpf;net;netstandard;net461;uwp;xamarin
https://github.com/AvaloniaUI/Avalonia/releases
git
+ $(MSBuildThisFileDirectory)\avalonia.snk
+ false
+ $(DefineConstants);SIGNED_BUILD
+
+
+
+
diff --git a/build/SourceLink.props b/build/SourceLink.props
index 0c9b6a34f8..e27727c9e8 100644
--- a/build/SourceLink.props
+++ b/build/SourceLink.props
@@ -1,5 +1,5 @@
-
+
-
\ No newline at end of file
+
diff --git a/build/XUnit.props b/build/XUnit.props
index 079565d184..a75e1bac86 100644
--- a/build/XUnit.props
+++ b/build/XUnit.props
@@ -11,4 +11,8 @@
+
+ $(MSBuildThisFileDirectory)\avalonia.snk
+ False
+
diff --git a/build/avalonia.snk b/build/avalonia.snk
new file mode 100644
index 0000000000..10b49deb31
Binary files /dev/null and b/build/avalonia.snk differ
diff --git a/dirs.proj b/dirs.proj
index bf32abef72..594f2c22d3 100644
--- a/dirs.proj
+++ b/dirs.proj
@@ -21,6 +21,7 @@
+
diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm
index fb945a105e..67b1ea50a6 100644
--- a/native/Avalonia.Native/src/OSX/window.mm
+++ b/native/Avalonia.Native/src/OSX/window.mm
@@ -1338,6 +1338,12 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
}
_parent->BaseEvents->RunRenderPriorityJobs();
+
+ if (_parent == nullptr)
+ {
+ return;
+ }
+
_parent->BaseEvents->Paint();
}
diff --git a/nukebuild/BuildTasksPatcher.cs b/nukebuild/BuildTasksPatcher.cs
index 44f01da669..e3766ae23f 100644
--- a/nukebuild/BuildTasksPatcher.cs
+++ b/nukebuild/BuildTasksPatcher.cs
@@ -29,7 +29,11 @@ public class BuildTasksPatcher
InputAssemblies = new[]
{
temp, typeof(Mono.Cecil.AssemblyDefinition).Assembly.GetModules()[0]
- .FullyQualifiedName
+ .FullyQualifiedName,
+ typeof(Mono.Cecil.Rocks.MethodBodyRocks).Assembly.GetModules()[0].FullyQualifiedName,
+ typeof(Mono.Cecil.Pdb.PdbReaderProvider).Assembly.GetModules()[0].FullyQualifiedName,
+ typeof(Mono.Cecil.Mdb.MdbReaderProvider).Assembly.GetModules()[0].FullyQualifiedName
+
},
SearchDirectories = new string[0],
OutputFile = output
diff --git a/nukebuild/_build.csproj b/nukebuild/_build.csproj
index b06e49f2eb..77cfb83427 100644
--- a/nukebuild/_build.csproj
+++ b/nukebuild/_build.csproj
@@ -16,7 +16,7 @@
-
+
diff --git a/packages/Avalonia/AvaloniaBuildTasks.targets b/packages/Avalonia/AvaloniaBuildTasks.targets
index 84a62bb5c0..612c368633 100644
--- a/packages/Avalonia/AvaloniaBuildTasks.targets
+++ b/packages/Avalonia/AvaloniaBuildTasks.targets
@@ -87,6 +87,9 @@
ProjectDirectory="$(MSBuildProjectDirectory)"
VerifyIl="$(AvaloniaXamlIlVerifyIl)"
ReportImportance="$(AvaloniaXamlReportImportance)"
+ AssemblyOriginatorKeyFile="$(AssemblyOriginatorKeyFile)"
+ SignAssembly="$(SignAssembly)"
+ DelaySign="$(DelaySign)"
/>
()
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ desktop.MainWindow = new MainWindow();
+ base.OnFrameworkInitializationCompleted();
+ }
+
+ public static int Main(string[] args)
+ => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
+
+ public static AppBuilder BuildAvaloniaApp()
+ => AppBuilder.Configure()
.UsePlatformDetect()
.UseReactiveUI()
- .LogToDebug()
- .Start();
- }
+ .LogToTrace();
}
}
diff --git a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
index 1a112d0d7d..c6405dabb6 100644
--- a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
+++ b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
@@ -3,6 +3,7 @@
Exe
net461
+ x64
diff --git a/samples/ControlCatalog.Desktop/Program.cs b/samples/ControlCatalog.Desktop/Program.cs
index b2df1953f5..5af646b180 100644
--- a/samples/ControlCatalog.Desktop/Program.cs
+++ b/samples/ControlCatalog.Desktop/Program.cs
@@ -10,19 +10,15 @@ namespace ControlCatalog
internal class Program
{
[STAThread]
- static void Main(string[] args)
- {
- // TODO: Make this work with GTK/Skia/Cairo depending on command-line args
- // again.
- BuildAvaloniaApp().Start();
- }
+ public static int Main(string[] args)
+ => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
///
/// This method is needed for IDE previewer infrastructure
///
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure()
- .LogToDebug()
+ .LogToTrace()
.UsePlatformDetect()
.UseReactiveUI();
diff --git a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
index 28b0257eda..d5aedf7783 100644
--- a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
+++ b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
@@ -11,9 +11,8 @@
-
-
+
diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs
index 142736a0bb..675ea2e10f 100644
--- a/samples/ControlCatalog.NetCore/Program.cs
+++ b/samples/ControlCatalog.NetCore/Program.cs
@@ -7,12 +7,11 @@ using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Dialogs;
using Avalonia.Headless;
using Avalonia.LogicalTree;
-using Avalonia.Skia;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
-using Avalonia.Dialogs;
namespace ControlCatalog.NetCore
{
@@ -121,7 +120,7 @@ namespace ControlCatalog.NetCore
.UseSkia()
.UseReactiveUI()
.UseManagedSystemDialogs()
- .LogToDebug();
+ .LogToTrace();
static void SilenceConsole()
{
diff --git a/samples/ControlCatalog/App.xaml b/samples/ControlCatalog/App.xaml
index 9bac320c79..6aad44c0d5 100644
--- a/samples/ControlCatalog/App.xaml
+++ b/samples/ControlCatalog/App.xaml
@@ -12,6 +12,16 @@
+
+
+
diff --git a/samples/ControlCatalog/App.xaml.cs b/samples/ControlCatalog/App.xaml.cs
index cb50cba540..22f4e9be1f 100644
--- a/samples/ControlCatalog/App.xaml.cs
+++ b/samples/ControlCatalog/App.xaml.cs
@@ -81,7 +81,7 @@ namespace ControlCatalog
public override void Initialize()
{
- Styles.Insert(0, FluentDark);
+ Styles.Insert(0, FluentLight);
AvaloniaXamlLoader.Load(this);
}
diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml
index 790813fda0..488aa0535f 100644
--- a/samples/ControlCatalog/MainView.xaml
+++ b/samples/ControlCatalog/MainView.xaml
@@ -14,6 +14,7 @@
+
@@ -77,8 +78,8 @@
Full Decorations
- Fluent - Dark
Fluent - Light
+ Fluent - Dark
Simple - Light
Simple - Dark
diff --git a/samples/ControlCatalog/MainView.xaml.cs b/samples/ControlCatalog/MainView.xaml.cs
index b0c205246e..c84f2f06b6 100644
--- a/samples/ControlCatalog/MainView.xaml.cs
+++ b/samples/ControlCatalog/MainView.xaml.cs
@@ -38,10 +38,10 @@ namespace ControlCatalog
switch (themes.SelectedIndex)
{
case 0:
- Application.Current.Styles[0] = App.FluentDark;
+ Application.Current.Styles[0] = App.FluentLight;
break;
case 1:
- Application.Current.Styles[0] = App.FluentLight;
+ Application.Current.Styles[0] = App.FluentDark;
break;
case 2:
Application.Current.Styles[0] = App.DefaultLight;
diff --git a/samples/ControlCatalog/Pages/LabelsPage.axaml b/samples/ControlCatalog/Pages/LabelsPage.axaml
new file mode 100644
index 0000000000..32c46f080d
--- /dev/null
+++ b/samples/ControlCatalog/Pages/LabelsPage.axaml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/LabelsPage.axaml.cs b/samples/ControlCatalog/Pages/LabelsPage.axaml.cs
new file mode 100644
index 0000000000..b8503d6ae6
--- /dev/null
+++ b/samples/ControlCatalog/Pages/LabelsPage.axaml.cs
@@ -0,0 +1,43 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using ControlCatalog.Models;
+using ReactiveUI;
+
+namespace ControlCatalog.Pages
+{
+ public class LabelsPage : UserControl
+ {
+ private Person _person;
+
+ public LabelsPage()
+ {
+ CreateDefaultPerson();
+ this.InitializeComponent();
+ }
+
+ private void CreateDefaultPerson()
+ {
+ DataContext = _person = new Person
+ {
+ FirstName = "John",
+ LastName = "Doe",
+ IsBanned = true,
+ };
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ public void DoSave()
+ {
+
+ }
+ public void DoCancel()
+ {
+ CreateDefaultPerson();
+ }
+ }
+}
diff --git a/samples/ControlCatalog/Pages/TextBlockPage.xaml b/samples/ControlCatalog/Pages/TextBlockPage.xaml
index 4a1c196917..d4f72f161a 100644
--- a/samples/ControlCatalog/Pages/TextBlockPage.xaml
+++ b/samples/ControlCatalog/Pages/TextBlockPage.xaml
@@ -18,8 +18,8 @@
-
-
+
+
diff --git a/samples/ControlCatalog/Pages/TextBoxPage.xaml b/samples/ControlCatalog/Pages/TextBoxPage.xaml
index 481a459159..8b07ac3f85 100644
--- a/samples/ControlCatalog/Pages/TextBoxPage.xaml
+++ b/samples/ControlCatalog/Pages/TextBoxPage.xaml
@@ -2,8 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.Pages.TextBoxPage">
- TextBox
- A control into which the user can input text
+
+
-
+
-
- resm fonts
-
-
-
-
-
-
-
- res fonts
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/Previewer/App.xaml.cs b/samples/Previewer/App.xaml.cs
index fffa987a27..ab83d45cd3 100644
--- a/samples/Previewer/App.xaml.cs
+++ b/samples/Previewer/App.xaml.cs
@@ -1,4 +1,5 @@
using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace Previewer
@@ -9,6 +10,13 @@ namespace Previewer
{
AvaloniaXamlLoader.Load(this);
}
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ desktop.MainWindow = new MainWindow();
+ base.OnFrameworkInitializationCompleted();
+ }
}
-}
\ No newline at end of file
+}
diff --git a/samples/Previewer/Program.cs b/samples/Previewer/Program.cs
index 48363e27f2..b12b93974a 100644
--- a/samples/Previewer/Program.cs
+++ b/samples/Previewer/Program.cs
@@ -1,13 +1,14 @@
-using System;
-using Avalonia;
+using Avalonia;
namespace Previewer
{
class Program
{
- static void Main(string[] args)
- {
- AppBuilder.Configure().UsePlatformDetect().Start();
- }
+ public static AppBuilder BuildAvaloniaApp()
+ => AppBuilder.Configure()
+ .UsePlatformDetect();
+
+ public static int Main(string[] args)
+ => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}
-}
\ No newline at end of file
+}
diff --git a/samples/RenderDemo/App.xaml.cs b/samples/RenderDemo/App.xaml.cs
index 233160b025..e6ec963d75 100644
--- a/samples/RenderDemo/App.xaml.cs
+++ b/samples/RenderDemo/App.xaml.cs
@@ -1,4 +1,5 @@
using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
@@ -11,15 +12,27 @@ namespace RenderDemo
AvaloniaXamlLoader.Load(this);
}
+ public override void OnFrameworkInitializationCompleted()
+ {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ desktop.MainWindow = new MainWindow();
+ base.OnFrameworkInitializationCompleted();
+ }
+
// TODO: Make this work with GTK/Skia/Cairo depending on command-line args
// again.
- static void Main(string[] args) => BuildAvaloniaApp().Start();
+ static void Main(string[] args)
+ => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
// App configuration, used by the entry point and previewer
static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure()
+ .With(new Win32PlatformOptions
+ {
+ OverlayPopups = true,
+ })
.UsePlatformDetect()
.UseReactiveUI()
- .LogToDebug();
+ .LogToTrace();
}
}
diff --git a/samples/RenderDemo/Pages/GlyphRunPage.xaml b/samples/RenderDemo/Pages/GlyphRunPage.xaml
index fb3e318a0e..c2914e8847 100644
--- a/samples/RenderDemo/Pages/GlyphRunPage.xaml
+++ b/samples/RenderDemo/Pages/GlyphRunPage.xaml
@@ -6,9 +6,9 @@
x:Class="RenderDemo.Pages.GlyphRunPage">
-
-
+
diff --git a/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs b/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs
index ddee880288..857358f6b2 100644
--- a/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs
+++ b/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs
@@ -9,7 +9,7 @@ namespace RenderDemo.Pages
{
public class GlyphRunPage : UserControl
{
- private DrawingPresenter _drawingPresenter;
+ private Image _imageControl;
private GlyphTypeface _glyphTypeface = Typeface.Default.GlyphTypeface;
private readonly Random _rand = new Random();
private ushort[] _glyphIndices = new ushort[1];
@@ -25,7 +25,8 @@ namespace RenderDemo.Pages
{
AvaloniaXamlLoader.Load(this);
- _drawingPresenter = this.FindControl("drawingPresenter");
+ _imageControl = this.FindControl("imageControl");
+ _imageControl.Source = new DrawingImage();
DispatcherTimer.Run(() =>
{
@@ -73,7 +74,7 @@ namespace RenderDemo.Pages
drawingGroup.Children.Add(geometryDrawing);
- _drawingPresenter.Drawing = drawingGroup;
+ (_imageControl.Source as DrawingImage).Drawing = drawingGroup;
}
}
}
diff --git a/samples/Sandbox/Program.cs b/samples/Sandbox/Program.cs
index 4d7eda8d9f..7d41a8b8c0 100644
--- a/samples/Sandbox/Program.cs
+++ b/samples/Sandbox/Program.cs
@@ -10,7 +10,7 @@ namespace Sandbox
AppBuilder.Configure()
.UsePlatformDetect()
.UseReactiveUI()
- .LogToDebug()
+ .LogToTrace()
.StartWithClassicDesktopLifetime(args);
}
}
diff --git a/samples/VirtualizationDemo/App.xaml.cs b/samples/VirtualizationDemo/App.xaml.cs
index 5990dd282c..81b80c1f40 100644
--- a/samples/VirtualizationDemo/App.xaml.cs
+++ b/samples/VirtualizationDemo/App.xaml.cs
@@ -1,4 +1,5 @@
using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace VirtualizationDemo
@@ -9,5 +10,12 @@ namespace VirtualizationDemo
{
AvaloniaXamlLoader.Load(this);
}
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ desktop.MainWindow = new MainWindow();
+ base.OnFrameworkInitializationCompleted();
+ }
}
}
diff --git a/samples/VirtualizationDemo/Program.cs b/samples/VirtualizationDemo/Program.cs
index 93ea5e1b88..46c05f74b2 100644
--- a/samples/VirtualizationDemo/Program.cs
+++ b/samples/VirtualizationDemo/Program.cs
@@ -1,19 +1,17 @@
-using System;
-using Avalonia;
-using Avalonia.Controls;
+using Avalonia;
using Avalonia.ReactiveUI;
namespace VirtualizationDemo
{
class Program
{
- static void Main(string[] args)
- {
- AppBuilder.Configure()
- .UsePlatformDetect()
- .UseReactiveUI()
- .LogToDebug()
- .Start();
- }
+ public static AppBuilder BuildAvaloniaApp()
+ => AppBuilder.Configure()
+ .UsePlatformDetect()
+ .UseReactiveUI()
+ .LogToTrace();
+
+ public static int Main(string[] args)
+ => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}
}
diff --git a/samples/interop/Direct3DInteropSample/App.paml.cs b/samples/interop/Direct3DInteropSample/App.paml.cs
index 1b6d5fd39c..29365decfe 100644
--- a/samples/interop/Direct3DInteropSample/App.paml.cs
+++ b/samples/interop/Direct3DInteropSample/App.paml.cs
@@ -1,4 +1,5 @@
using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace Direct3DInteropSample
@@ -9,5 +10,12 @@ namespace Direct3DInteropSample
{
AvaloniaXamlLoader.Load(this);
}
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ desktop.MainWindow = new MainWindow();
+ base.OnFrameworkInitializationCompleted();
+ }
}
}
diff --git a/samples/interop/Direct3DInteropSample/Program.cs b/samples/interop/Direct3DInteropSample/Program.cs
index 21302fa68a..bf8e76d7e4 100644
--- a/samples/interop/Direct3DInteropSample/Program.cs
+++ b/samples/interop/Direct3DInteropSample/Program.cs
@@ -1,19 +1,16 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Avalonia;
+using Avalonia;
namespace Direct3DInteropSample
{
class Program
{
- static void Main(string[] args)
- {
- AppBuilder.Configure()
- .With(new Win32PlatformOptions {UseDeferredRendering = false})
- .UseWin32().UseDirect2D1().Start();
- }
+ public static AppBuilder BuildAvaloniaApp()
+ => AppBuilder.Configure()
+ .With(new Win32PlatformOptions { UseDeferredRendering = false })
+ .UseWin32()
+ .UseDirect2D1();
+
+ public static int Main(string[] args)
+ => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}
}
diff --git a/samples/interop/NativeEmbedSample/NativeEmbedSample.csproj b/samples/interop/NativeEmbedSample/NativeEmbedSample.csproj
index cc831ef8ae..c25442b52c 100644
--- a/samples/interop/NativeEmbedSample/NativeEmbedSample.csproj
+++ b/samples/interop/NativeEmbedSample/NativeEmbedSample.csproj
@@ -9,11 +9,10 @@
-
-
+
Designer
diff --git a/src/Avalonia.Animation/Properties/AssemblyInfo.cs b/src/Avalonia.Animation/Properties/AssemblyInfo.cs
index d34fd06272..221b51e95a 100644
--- a/src/Avalonia.Animation/Properties/AssemblyInfo.cs
+++ b/src/Avalonia.Animation/Properties/AssemblyInfo.cs
@@ -6,5 +6,10 @@ using System.Runtime.CompilerServices;
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Animation.Easings")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Animation.Animators")]
+#if SIGNED_BUILD
+[assembly: InternalsVisibleTo("Avalonia.LeakTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
+[assembly: InternalsVisibleTo("Avalonia.Animation.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
+#else
[assembly: InternalsVisibleTo("Avalonia.LeakTests")]
[assembly: InternalsVisibleTo("Avalonia.Animation.UnitTests")]
+#endif
diff --git a/src/Avalonia.Base/ApiCompatBaseline.txt b/src/Avalonia.Base/ApiCompatBaseline.txt
index 4668a572c5..5d19373a92 100644
--- a/src/Avalonia.Base/ApiCompatBaseline.txt
+++ b/src/Avalonia.Base/ApiCompatBaseline.txt
@@ -1,3 +1,4 @@
Compat issues with assembly Avalonia.Base:
CannotAddAbstractMembers : Member 'protected System.IObservable Avalonia.AvaloniaProperty.GetChanged()' is abstract in the implementation but is missing in the contract.
-Total Issues: 1
+TypesMustExist : Type 'Avalonia.Logging.DebugLogSink' does not exist in the implementation but it does exist in the contract.
+Total Issues: 2
diff --git a/src/Avalonia.Base/AvaloniaLocator.cs b/src/Avalonia.Base/AvaloniaLocator.cs
index f9bbe38bec..3163d15c1b 100644
--- a/src/Avalonia.Base/AvaloniaLocator.cs
+++ b/src/Avalonia.Base/AvaloniaLocator.cs
@@ -54,6 +54,23 @@ namespace Avalonia
return _locator;
}
+ public AvaloniaLocator ToLazy(Func func) where TImlp : TService
+ {
+ var constructed = false;
+ TImlp instance = default;
+ _locator._registry[typeof (TService)] = () =>
+ {
+ if (!constructed)
+ {
+ instance = func();
+ constructed = true;
+ }
+
+ return instance;
+ };
+ return _locator;
+ }
+
public AvaloniaLocator ToSingleton() where TImpl : class, TService, new()
{
TImpl instance = null;
diff --git a/src/Avalonia.Base/AvaloniaObject.cs b/src/Avalonia.Base/AvaloniaObject.cs
index 65233f9230..6645d25b5d 100644
--- a/src/Avalonia.Base/AvaloniaObject.cs
+++ b/src/Avalonia.Base/AvaloniaObject.cs
@@ -113,16 +113,8 @@ namespace Avalonia
/// The binding information.
public IBinding this[IndexerDescriptor binding]
{
- get
- {
- return new IndexerBinding(this, binding.Property, binding.Mode);
- }
-
- set
- {
- var sourceBinding = value as IBinding;
- this.Bind(binding.Property, sourceBinding);
- }
+ get { return new IndexerBinding(this, binding.Property, binding.Mode); }
+ set { this.Bind(binding.Property, value); }
}
public bool CheckAccess() => Dispatcher.UIThread.CheckAccess();
diff --git a/src/Avalonia.Base/Data/Core/Plugins/InpcPropertyAccessorPlugin.cs b/src/Avalonia.Base/Data/Core/Plugins/InpcPropertyAccessorPlugin.cs
index 8fc2a7b77c..3bf6842cd6 100644
--- a/src/Avalonia.Base/Data/Core/Plugins/InpcPropertyAccessorPlugin.cs
+++ b/src/Avalonia.Base/Data/Core/Plugins/InpcPropertyAccessorPlugin.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using Avalonia.Utilities;
@@ -11,8 +12,11 @@ namespace Avalonia.Data.Core.Plugins
///
public class InpcPropertyAccessorPlugin : IPropertyAccessorPlugin
{
+ private readonly Dictionary<(Type, string), PropertyInfo> _propertyLookup =
+ new Dictionary<(Type, string), PropertyInfo>();
+
///
- public bool Match(object obj, string propertyName) => GetPropertyWithName(obj.GetType(), propertyName) != null;
+ public bool Match(object obj, string propertyName) => GetFirstPropertyWithName(obj.GetType(), propertyName) != null;
///
/// Starts monitoring the value of a property on an object.
@@ -30,7 +34,7 @@ namespace Avalonia.Data.Core.Plugins
reference.TryGetTarget(out object instance);
- var p = GetPropertyWithName(instance.GetType(), propertyName);
+ var p = GetFirstPropertyWithName(instance.GetType(), propertyName);
if (p != null)
{
@@ -44,12 +48,40 @@ namespace Avalonia.Data.Core.Plugins
}
}
- private static PropertyInfo GetPropertyWithName(Type type, string propertyName)
+ private PropertyInfo GetFirstPropertyWithName(Type type, string propertyName)
{
- const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Public |
- BindingFlags.Static | BindingFlags.Instance;
+ var key = (type, propertyName);
+
+ if (!_propertyLookup.TryGetValue(key, out PropertyInfo propertyInfo))
+ {
+ propertyInfo = TryFindAndCacheProperty(type, propertyName);
+ }
+
+ return propertyInfo;
+ }
+
+ private PropertyInfo TryFindAndCacheProperty(Type type, string propertyName)
+ {
+ PropertyInfo found = null;
+
+ const BindingFlags bindingFlags =
+ BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
+
+ var properties = type.GetProperties(bindingFlags);
+
+ foreach (PropertyInfo propertyInfo in properties)
+ {
+ if (propertyInfo.Name == propertyName)
+ {
+ found = propertyInfo;
+
+ break;
+ }
+ }
+
+ _propertyLookup.Add((type, propertyName), found);
- return type.GetProperty(propertyName, bindingFlags);
+ return found;
}
private class Accessor : PropertyAccessorBase, IWeakSubscriber
diff --git a/src/Avalonia.Base/Logging/DebugLogSink.cs b/src/Avalonia.Base/Logging/TraceLogSink.cs
similarity index 92%
rename from src/Avalonia.Base/Logging/DebugLogSink.cs
rename to src/Avalonia.Base/Logging/TraceLogSink.cs
index 3695afa860..f597844378 100644
--- a/src/Avalonia.Base/Logging/DebugLogSink.cs
+++ b/src/Avalonia.Base/Logging/TraceLogSink.cs
@@ -6,12 +6,12 @@ using Avalonia.Utilities;
namespace Avalonia.Logging
{
- public class DebugLogSink : ILogSink
+ public class TraceLogSink : ILogSink
{
private readonly LogEventLevel _level;
private readonly IList _areas;
- public DebugLogSink(
+ public TraceLogSink(
LogEventLevel minimumLevel,
IList areas = null)
{
@@ -28,7 +28,7 @@ namespace Avalonia.Logging
{
if (IsEnabled(level, area))
{
- Debug.WriteLine(Format
diff --git a/src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs b/src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs
index 95e59dde2b..8e1f6c257d 100644
--- a/src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs
+++ b/src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs
@@ -39,7 +39,9 @@ namespace Avalonia.Build.Tasks
var res = XamlCompilerTaskExecutor.Compile(BuildEngine, input,
File.ReadAllLines(ReferencesFilePath).Where(l => !string.IsNullOrWhiteSpace(l)).ToArray(),
- ProjectDirectory, OutputPath, VerifyIl, outputImportance);
+ ProjectDirectory, OutputPath, VerifyIl, outputImportance,
+ (SignAssembly && !DelaySign) ? AssemblyOriginatorKeyFile : null
+ );
if (!res.Success)
return false;
if (!res.WrittenFile)
@@ -73,6 +75,10 @@ namespace Avalonia.Build.Tasks
public string OutputPath { get; set; }
public bool VerifyIl { get; set; }
+
+ public string AssemblyOriginatorKeyFile { get; set; }
+ public bool SignAssembly { get; set; }
+ public bool DelaySign { get; set; }
public string ReportImportance { get; set; }
diff --git a/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
index c9c9c562bd..6b01af2ede 100644
--- a/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
+++ b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
@@ -42,7 +42,7 @@ namespace Avalonia.Build.Tasks
}
public static CompileResult Compile(IBuildEngine engine, string input, string[] references, string projectDirectory,
- string output, bool verifyIl, MessageImportance logImportance)
+ string output, bool verifyIl, MessageImportance logImportance, string strongNameKey)
{
var typeSystem = new CecilTypeSystem(references.Concat(new[] {input}), input);
var asm = typeSystem.TargetAssemblyDefinition;
@@ -345,6 +345,20 @@ namespace Avalonia.Build.Tasks
}
res.Remove();
}
+
+
+ // Technically that's a hack, but it fixes corert incompatibility caused by deterministic builds
+ int dupeCounter = 1;
+ foreach (var grp in typeDef.NestedTypes.GroupBy(x => x.Name))
+ {
+ if (grp.Count() > 1)
+ {
+ foreach (var dupe in grp)
+ dupe.Name += "_dup" + dupeCounter++;
+ }
+ }
+
+
return true;
}
@@ -361,10 +375,12 @@ namespace Avalonia.Build.Tasks
loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldnull));
loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
- asm.Write(output, new WriterParameters
- {
- WriteSymbols = asm.MainModule.HasSymbols
- });
+
+ var writerParameters = new WriterParameters { WriteSymbols = asm.MainModule.HasSymbols };
+ if (!string.IsNullOrWhiteSpace(strongNameKey))
+ writerParameters.StrongNameKeyBlob = File.ReadAllBytes(strongNameKey);
+
+ asm.Write(output, writerParameters);
return new CompileResult(true, true);
}
diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs
index 23c4acdf6c..92ddd4e736 100644
--- a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs
+++ b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs
@@ -665,6 +665,7 @@ namespace Avalonia.Controls
///
/// The data item represented by the row that contains the intended cell.
///
+ /// When the method returns, contains the applied binding.
///
/// A new editing element that is bound to the column's property value.
///
diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs
index 856d1f6566..7f8d205949 100644
--- a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs
+++ b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs
@@ -340,8 +340,6 @@ namespace Avalonia.Controls
if (OwningGrid != null && OwningGrid.ColumnHeaders != null)
{
- args.Pointer.Capture(this);
-
_dragMode = DragMode.MouseDown;
_frozenColumnsWidth = OwningGrid.ColumnsInternal.GetVisibleFrozenEdgedColumnsWidth();
_lastMousePositionHeaders = this.Translate(OwningGrid.ColumnHeaders, mousePosition);
@@ -413,8 +411,9 @@ namespace Avalonia.Controls
}
//TODO DragEvents
- internal void OnMouseMove(ref bool handled, Point mousePosition, Point mousePositionHeaders)
+ internal void OnMouseMove(PointerEventArgs args, Point mousePosition, Point mousePositionHeaders)
{
+ var handled = args.Handled;
if (handled || OwningGrid == null || OwningGrid.ColumnHeaders == null)
{
return;
@@ -438,7 +437,10 @@ namespace Avalonia.Controls
}
_lastMousePositionHeaders = mousePositionHeaders;
-
+
+ if (args.Pointer.Captured != this && _dragMode == DragMode.Drag)
+ args.Pointer.Capture(this);
+
SetDragCursor(mousePosition);
}
@@ -506,8 +508,7 @@ namespace Avalonia.Controls
Point mousePosition = e.GetPosition(this);
Point mousePositionHeaders = e.GetPosition(OwningGrid.ColumnHeaders);
- bool handled = false;
- OnMouseMove(ref handled, mousePosition, mousePositionHeaders);
+ OnMouseMove(e, mousePosition, mousePositionHeaders);
}
///
diff --git a/src/Avalonia.Controls.DataGrid/Properties/AssemblyInfo.cs b/src/Avalonia.Controls.DataGrid/Properties/AssemblyInfo.cs
index 82b01e99bb..1b122996d2 100644
--- a/src/Avalonia.Controls.DataGrid/Properties/AssemblyInfo.cs
+++ b/src/Avalonia.Controls.DataGrid/Properties/AssemblyInfo.cs
@@ -1,10 +1,13 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using Avalonia.Metadata;
-
+#if SIGNED_BUILD
+[assembly: InternalsVisibleTo("Avalonia.Controls.DataGrid.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
+[assembly: InternalsVisibleTo("Avalonia.DesignerSupport, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
+#else
[assembly: InternalsVisibleTo("Avalonia.Controls.DataGrid.UnitTests")]
[assembly: InternalsVisibleTo("Avalonia.DesignerSupport")]
-
+#endif
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls.Collections")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls.Primitives")]
diff --git a/src/Avalonia.Controls/ApiCompatBaseline.txt b/src/Avalonia.Controls/ApiCompatBaseline.txt
index af88c569a6..16c801201c 100644
--- a/src/Avalonia.Controls/ApiCompatBaseline.txt
+++ b/src/Avalonia.Controls/ApiCompatBaseline.txt
@@ -8,6 +8,12 @@ MembersMustExist : Member 'public void Avalonia.Controls.ListBox.Selection.set(A
TypesMustExist : Type 'Avalonia.Controls.SelectionModel' does not exist in the implementation but it does exist in the contract.
TypesMustExist : Type 'Avalonia.Controls.SelectionModelChildrenRequestedEventArgs' does not exist in the implementation but it does exist in the contract.
TypesMustExist : Type 'Avalonia.Controls.SelectionModelSelectionChangedEventArgs' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public Avalonia.StyledProperty Avalonia.StyledProperty Avalonia.Controls.SplitView.ContentProperty' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public Avalonia.StyledProperty Avalonia.StyledProperty Avalonia.Controls.SplitView.PaneProperty' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public Avalonia.Controls.IControl Avalonia.Controls.SplitView.Content.get()' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public void Avalonia.Controls.SplitView.Content.set(Avalonia.Controls.IControl)' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public Avalonia.Controls.IControl Avalonia.Controls.SplitView.Pane.get()' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public void Avalonia.Controls.SplitView.Pane.set(Avalonia.Controls.IControl)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public Avalonia.DirectProperty Avalonia.DirectProperty Avalonia.Controls.TreeView.SelectionProperty' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public Avalonia.Interactivity.RoutedEvent Avalonia.Interactivity.RoutedEvent Avalonia.Controls.TreeView.SelectionChangedEvent' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public Avalonia.Controls.ISelectionModel Avalonia.Controls.TreeView.Selection.get()' does not exist in the implementation but it does exist in the contract.
@@ -17,4 +23,4 @@ InterfacesShouldHaveSameMembers : Interface member 'public System.String[] Avalo
MembersMustExist : Member 'public Avalonia.DirectProperty Avalonia.DirectProperty Avalonia.Controls.Primitives.SelectingItemsControl.SelectionProperty' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'protected Avalonia.Controls.ISelectionModel Avalonia.Controls.Primitives.SelectingItemsControl.Selection.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'protected void Avalonia.Controls.Primitives.SelectingItemsControl.Selection.set(Avalonia.Controls.ISelectionModel)' does not exist in the implementation but it does exist in the contract.
-Total Issues: 18
+Total Issues: 24
diff --git a/src/Avalonia.Controls/Calendar/CalendarItem.cs b/src/Avalonia.Controls/Calendar/CalendarItem.cs
index e9ea942142..e830717b95 100644
--- a/src/Avalonia.Controls/Calendar/CalendarItem.cs
+++ b/src/Avalonia.Controls/Calendar/CalendarItem.cs
@@ -36,11 +36,7 @@ namespace Avalonia.Controls.Primitives
private Button _headerButton;
private Button _nextButton;
private Button _previousButton;
- private Grid _monthView;
- private Grid _yearView;
private ITemplate _dayTitleTemplate;
- private CalendarButton _lastCalendarButton;
- private CalendarDayButton _lastCalendarDayButton;
private DateTime _currentMonth;
private bool _isMouseLeftButtonDown = false;
@@ -160,38 +156,12 @@ namespace Avalonia.Controls.Primitives
///
/// Gets the Grid that hosts the content when in month mode.
///
- internal Grid MonthView
- {
- get { return _monthView; }
- private set
- {
- if (_monthView != null)
- _monthView.PointerLeave -= MonthView_MouseLeave;
-
- _monthView = value;
-
- if (_monthView != null)
- _monthView.PointerLeave += MonthView_MouseLeave;
- }
- }
+ internal Grid MonthView { get; set; }
///
/// Gets the Grid that hosts the content when in year or decade mode.
///
- internal Grid YearView
- {
- get { return _yearView; }
- private set
- {
- if (_yearView != null)
- _yearView.PointerLeave -= YearView_MouseLeave;
-
- _yearView = value;
-
- if (_yearView != null)
- _yearView.PointerLeave += YearView_MouseLeave;
- }
- }
-
+ internal Grid YearView { get; set; }
+
private void PopulateGrids()
{
if (MonthView != null)
@@ -226,7 +196,6 @@ namespace Avalonia.Controls.Primitives
cell.CalendarDayButtonMouseDown += Cell_MouseLeftButtonDown;
cell.CalendarDayButtonMouseUp += Cell_MouseLeftButtonUp;
cell.PointerEnter += Cell_MouseEnter;
- cell.PointerLeave += Cell_MouseLeave;
cell.Click += Cell_Click;
children.Add(cell);
}
@@ -256,7 +225,6 @@ namespace Avalonia.Controls.Primitives
month.CalendarLeftMouseButtonDown += Month_CalendarButtonMouseDown;
month.CalendarLeftMouseButtonUp += Month_CalendarButtonMouseUp;
month.PointerEnter += Month_MouseEnter;
- month.PointerLeave += Month_MouseLeave;
children.Add(month);
}
}
@@ -937,17 +905,7 @@ namespace Avalonia.Controls.Primitives
}
}
}
- internal void Cell_MouseLeave(object sender, PointerEventArgs e)
- {
- if (_isMouseLeftButtonDown)
- {
- CalendarDayButton b = (CalendarDayButton)sender;
- // The button is in Pressed state. Change the state to normal.
- if (e.Pointer.Captured == b)
- e.Pointer.Capture(null);
- _lastCalendarDayButton = b;
- }
- }
+
internal void Cell_MouseLeftButtonDown(object sender, PointerPressedEventArgs e)
{
if (Owner != null)
@@ -1207,35 +1165,6 @@ namespace Avalonia.Controls.Primitives
}
}
- private void Month_MouseLeave(object sender, PointerEventArgs e)
- {
- if (_isMouseLeftButtonDownYearView)
- {
- CalendarButton b = (CalendarButton)sender;
- // The button is in Pressed state. Change the state to normal.
- if (e.Pointer.Captured == b)
- e.Pointer.Capture(null);
- //b.ReleaseMouseCapture();
-
- _lastCalendarButton = b;
- }
- }
- private void MonthView_MouseLeave(object sender, PointerEventArgs e)
- {
- if (_lastCalendarDayButton != null)
- {
- e.Pointer.Capture(_lastCalendarDayButton);
- }
- }
-
- private void YearView_MouseLeave(object sender, PointerEventArgs e)
- {
- if (_lastCalendarButton != null)
- {
- e.Pointer.Capture(_lastCalendarButton);
- }
- }
-
internal void UpdateDisabled(bool isEnabled)
{
PseudoClasses.Set(":calendardisabled", !isEnabled);
diff --git a/src/Avalonia.Controls/ContextMenu.cs b/src/Avalonia.Controls/ContextMenu.cs
index c4df5c1815..ec9649bc64 100644
--- a/src/Avalonia.Controls/ContextMenu.cs
+++ b/src/Avalonia.Controls/ContextMenu.cs
@@ -62,6 +62,12 @@ namespace Avalonia.Controls
public static readonly StyledProperty PlacementRectProperty =
AvaloniaProperty.Register(nameof(PlacementRect));
+ ///
+ /// Defines the property.
+ ///
+ public static readonly StyledProperty WindowManagerAddShadowHintProperty =
+ Popup.WindowManagerAddShadowHintProperty.AddOwner();
+
///
/// Defines the property.
///
@@ -158,6 +164,12 @@ namespace Avalonia.Controls
set { SetValue(PlacementModeProperty, value); }
}
+ public bool WindowManagerAddShadowHint
+ {
+ get { return GetValue(WindowManagerAddShadowHintProperty); }
+ set { SetValue(WindowManagerAddShadowHintProperty, value); }
+ }
+
///
/// Gets or sets the the anchor rectangle within the parent that the context menu will be placed
/// relative to when is .
@@ -267,6 +279,7 @@ namespace Avalonia.Controls
PlacementTarget = PlacementTarget ?? control,
IsLightDismissEnabled = true,
OverlayDismissEventPassThrough = true,
+ WindowManagerAddShadowHint = WindowManagerAddShadowHint,
};
_popup.Opened += PopupOpened;
diff --git a/src/Avalonia.Controls/IScrollAnchorProvider.cs b/src/Avalonia.Controls/IScrollAnchorProvider.cs
index 93f3a0abb8..7ba02e99ea 100644
--- a/src/Avalonia.Controls/IScrollAnchorProvider.cs
+++ b/src/Avalonia.Controls/IScrollAnchorProvider.cs
@@ -1,4 +1,6 @@
-namespace Avalonia.Controls
+#nullable enable
+
+namespace Avalonia.Controls
{
///
/// Specifies a contract for a scrolling control that supports scroll anchoring.
@@ -8,7 +10,7 @@
///
/// The currently chosen anchor element to use for scroll anchoring.
///
- IControl CurrentAnchor { get; }
+ IControl? CurrentAnchor { get; }
///
/// Registers a control as a potential scroll anchor candidate.
diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs
index 3aec06e4eb..4dc8aec6f3 100644
--- a/src/Avalonia.Controls/ItemsControl.cs
+++ b/src/Avalonia.Controls/ItemsControl.cs
@@ -169,7 +169,7 @@ namespace Avalonia.Controls
///
/// The collection.
/// The index.
- /// The index of the item or -1 if the item was not found.
+ /// The item at the given index or null if the index is out of bounds.
protected static object ElementAt(IEnumerable items, int index)
{
if (index != -1 && index < items.Count())
diff --git a/src/Avalonia.Controls/Label.cs b/src/Avalonia.Controls/Label.cs
new file mode 100644
index 0000000000..76708b8f00
--- /dev/null
+++ b/src/Avalonia.Controls/Label.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Text;
+using Avalonia.Controls.Primitives;
+using Avalonia.Controls.Templates;
+using Avalonia.Data;
+using Avalonia.Input;
+using Avalonia.Interactivity;
+
+namespace Avalonia.Controls
+{
+ ///
+ /// Label control. Focuses on pointer click or access key press (Alt + accessKey)
+ ///
+ public class Label : ContentControl
+ {
+ ///
+ /// Defines the Direct property
+ ///
+ public static readonly DirectProperty
@@ -53,6 +52,7 @@
diff --git a/src/Avalonia.Themes.Fluent/TabStripItem.xaml b/src/Avalonia.Themes.Fluent/TabStripItem.xaml
index 628ab8dddd..78ef102705 100644
--- a/src/Avalonia.Themes.Fluent/TabStripItem.xaml
+++ b/src/Avalonia.Themes.Fluent/TabStripItem.xaml
@@ -38,7 +38,6 @@
TextBlock.FontSize="{TemplateBinding FontSize}"
TextBlock.FontWeight="{TemplateBinding FontWeight}" />
@@ -46,6 +45,9 @@
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/ToggleButton.xaml b/src/Avalonia.Themes.Fluent/ToggleButton.xaml
index 49e2280a6d..dd8e51e4e5 100644
--- a/src/Avalonia.Themes.Fluent/ToggleButton.xaml
+++ b/src/Avalonia.Themes.Fluent/ToggleButton.xaml
@@ -29,7 +29,6 @@
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
- CornerRadius="{DynamicResource ControlCornerRadius}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Padding="{TemplateBinding Padding}"
@@ -38,6 +37,10 @@
+
+
+
+
+