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/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/MainView.xaml b/samples/ControlCatalog/MainView.xaml
index bd5beafe29..f001425964 100644
--- a/samples/ControlCatalog/MainView.xaml
+++ b/samples/ControlCatalog/MainView.xaml
@@ -44,6 +44,7 @@
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
+
diff --git a/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml b/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml
index a49616e543..1a53217842 100644
--- a/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml
+++ b/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml
@@ -1,5 +1,6 @@
AutoCompleteBox
@@ -56,6 +57,16 @@
Width="200"
Margin="0,0,0,8"
FilterMode="None"/>
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml b/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml
index c3f9f65dd9..4ac2330403 100644
--- a/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml
+++ b/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml
@@ -1,6 +1,7 @@
+ x:Class="ControlCatalog.Pages.ButtonSpinnerPage"
+ xmlns:sys="clr-namespace:System;assembly=netstandard">
ButtonSpinner
@@ -19,6 +20,14 @@
ShowButtonSpinner="{Binding #showSpinCheck.IsChecked}">
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/ComboBoxPage.xaml b/samples/ControlCatalog/Pages/ComboBoxPage.xaml
index 369f703718..025b85492c 100644
--- a/samples/ControlCatalog/Pages/ComboBoxPage.xaml
+++ b/samples/ControlCatalog/Pages/ComboBoxPage.xaml
@@ -1,6 +1,7 @@
+ x:Class="ControlCatalog.Pages.ComboBoxPage"
+ xmlns:sys="clr-namespace:System;assembly=netstandard">
ComboBox
A drop-down list.
@@ -35,6 +36,16 @@
+
+
+ Inline Items
+ Inline Item 2
+ Inline Item 3
+ Inline Item 4
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/DateTimePickerPage.xaml b/samples/ControlCatalog/Pages/DateTimePickerPage.xaml
index af6b6e8605..45056a9a76 100644
--- a/samples/ControlCatalog/Pages/DateTimePickerPage.xaml
+++ b/samples/ControlCatalog/Pages/DateTimePickerPage.xaml
@@ -2,6 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:sys="clr-namespace:System;assembly=netstandard"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="ControlCatalog.Pages.DateTimePickerPage">
@@ -30,6 +31,16 @@
+
+
+
+
+
+
+
+
+
A DatePicker with day formatted and year hidden.
+
+
+
+
+
+
+
+
A TimePicker with a header and minute increments specified.
diff --git a/samples/ControlCatalog/Pages/LabelsPage.axaml b/samples/ControlCatalog/Pages/LabelsPage.axaml
new file mode 100644
index 0000000000..961e7ba7e6
--- /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/NumericUpDownPage.xaml b/samples/ControlCatalog/Pages/NumericUpDownPage.xaml
index 0d7e5da17f..d75622f1fb 100644
--- a/samples/ControlCatalog/Pages/NumericUpDownPage.xaml
+++ b/samples/ControlCatalog/Pages/NumericUpDownPage.xaml
@@ -1,5 +1,6 @@
Numeric up-down control
@@ -75,6 +76,15 @@
+
+ NumericUpDown with Validation Errors:
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/RelativePanelPage.axaml b/samples/ControlCatalog/Pages/RelativePanelPage.axaml
index 3657d52bd9..4dcdcc195f 100644
--- a/samples/ControlCatalog/Pages/RelativePanelPage.axaml
+++ b/samples/ControlCatalog/Pages/RelativePanelPage.axaml
@@ -23,16 +23,16 @@
-
+
-
+
-
+
@@ -41,19 +41,19 @@
-
+
-
+
-
+
-
+
-
+
diff --git a/samples/ControlCatalog/Pages/SliderPage.xaml b/samples/ControlCatalog/Pages/SliderPage.xaml
index ea31ed0050..b3f32ed421 100644
--- a/samples/ControlCatalog/Pages/SliderPage.xaml
+++ b/samples/ControlCatalog/Pages/SliderPage.xaml
@@ -1,5 +1,6 @@
Slider
@@ -21,6 +22,15 @@
IsSnapToTickEnabled="True"
Ticks="0,20,25,40,75,100"
Width="300" />
+
+
+
+
+
+ x:Class="ControlCatalog.Pages.TextBoxPage"
+ xmlns:sys="clr-namespace:System;assembly=netstandard">
- 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 340ccdae19..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,9 +12,17 @@ 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()
@@ -24,6 +33,6 @@ namespace RenderDemo
})
.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/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/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/DateTimePickers/DateTimePickerPanel.cs b/src/Avalonia.Controls/DateTimePickers/DateTimePickerPanel.cs
index daee7968eb..a0e8c03195 100644
--- a/src/Avalonia.Controls/DateTimePickers/DateTimePickerPanel.cs
+++ b/src/Avalonia.Controls/DateTimePickers/DateTimePickerPanel.cs
@@ -486,9 +486,9 @@ namespace Avalonia.Controls.Primitives
switch (panelType)
{
case DateTimePickerPanelType.Year:
- return new DateTime(value, FormatDate.Month, FormatDate.Day).ToString(ItemFormat);
+ return new DateTime(value, 1, 1).ToString(ItemFormat);
case DateTimePickerPanelType.Month:
- return new DateTime(FormatDate.Year, value, FormatDate.Day).ToString(ItemFormat);
+ return new DateTime(FormatDate.Year, value, 1).ToString(ItemFormat);
case DateTimePickerPanelType.Day:
return new DateTime(FormatDate.Year, FormatDate.Month, value).ToString(ItemFormat);
case DateTimePickerPanelType.Hour:
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..9d5eda464f
--- /dev/null
+++ b/src/Avalonia.Controls/Label.cs
@@ -0,0 +1,75 @@
+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
/// The object to which the property value is written.
/// The value to set. (The element to align this element's bottom edge with.)
+ [ResolveByName]
public static void SetAlignBottomWith(AvaloniaObject obj, object value)
{
obj.SetValue(AlignBottomWithProperty, value);
@@ -185,6 +187,7 @@ namespace Avalonia.Controls
///
/// The object to which the property value is written.
/// The value to set. (The element to align this element's horizontal center with.)
+ [ResolveByName]
public static void SetAlignHorizontalCenterWith(AvaloniaObject obj, object value)
{
obj.SetValue(AlignHorizontalCenterWithProperty, value);
@@ -250,6 +253,7 @@ namespace Avalonia.Controls
///
/// The object to which the property value is written.
/// The value to set. (The element to align this element's left edge with.)
+ [ResolveByName]
public static void SetAlignLeftWith(AvaloniaObject obj, object value)
{
obj.SetValue(AlignLeftWithProperty, value);
@@ -315,6 +319,7 @@ namespace Avalonia.Controls
///
/// The object to which the property value is written.
/// The value to set. (The element to align this element's right edge with.)
+ [ResolveByName]
public static void SetAlignRightWith(AvaloniaObject obj, object value)
{
obj.SetValue(AlignRightWithProperty, value);
@@ -376,6 +381,7 @@ namespace Avalonia.Controls
///
/// The object to which the property value is written.
/// The value to set. (The element to align this element's top edge with.)
+ [ResolveByName]
public static void SetAlignTopWith(AvaloniaObject obj, object value)
{
obj.SetValue(AlignTopWithProperty, value);
@@ -437,7 +443,7 @@ namespace Avalonia.Controls
///
/// The object to which the property value is written.
/// The value to set. (The element to align this element's horizontal center with.)
-
+ [ResolveByName]
public static void SetAlignVerticalCenterWith(AvaloniaObject obj, object value)
{
obj.SetValue(AlignVerticalCenterWithProperty, value);
@@ -468,7 +474,7 @@ namespace Avalonia.Controls
///
/// The object to which the property value is written.
/// The value to set. (The element to position this element below.)
-
+ [ResolveByName]
public static void SetBelow(AvaloniaObject obj, object value)
{
obj.SetValue(BelowProperty, value);
@@ -500,6 +506,7 @@ namespace Avalonia.Controls
///
/// The object to which the property value is written.
/// The value to set. (The element to position this element to the left of.)
+ [ResolveByName]
public static void SetLeftOf(AvaloniaObject obj, object value)
{
obj.SetValue(LeftOfProperty, value);
@@ -531,6 +538,7 @@ namespace Avalonia.Controls
///
/// The object to which the property value is written.
/// The value to set. (The element to position this element to the right of.)
+ [ResolveByName]
public static void SetRightOf(AvaloniaObject obj, object value)
{
obj.SetValue(RightOfProperty, value);
diff --git a/src/Avalonia.Controls/ResolveByNameAttribute.cs b/src/Avalonia.Controls/ResolveByNameAttribute.cs
index a00e3f8a1b..a13b10d630 100644
--- a/src/Avalonia.Controls/ResolveByNameAttribute.cs
+++ b/src/Avalonia.Controls/ResolveByNameAttribute.cs
@@ -2,8 +2,12 @@
namespace Avalonia.Controls
{
+ ///
+ /// Indicates that the property resolves an element by Name or x:Name.
+ /// When applying this to attached properties, ensure to put on both
+ /// the Getter and Setter methods.
+ ///
public class ResolveByNameAttribute : Attribute
{
-
}
}
diff --git a/src/Avalonia.Controls/Selection/SelectionModel.cs b/src/Avalonia.Controls/Selection/SelectionModel.cs
index 3b5d57a7b8..054974e4f1 100644
--- a/src/Avalonia.Controls/Selection/SelectionModel.cs
+++ b/src/Avalonia.Controls/Selection/SelectionModel.cs
@@ -442,7 +442,8 @@ namespace Avalonia.Controls.Selection
RaisePropertyChanged(nameof(SelectedIndex));
}
- if (e.Action == NotifyCollectionChangedAction.Remove && e.OldStartingIndex <= oldSelectedIndex)
+ if ((e.Action == NotifyCollectionChangedAction.Remove && e.OldStartingIndex <= oldSelectedIndex) ||
+ e.Action == NotifyCollectionChangedAction.Reset)
{
RaisePropertyChanged(nameof(SelectedItem));
}
diff --git a/src/Avalonia.Controls/SplitView.cs b/src/Avalonia.Controls/SplitView.cs
index 8267efc466..4500d52484 100644
--- a/src/Avalonia.Controls/SplitView.cs
+++ b/src/Avalonia.Controls/SplitView.cs
@@ -9,6 +9,8 @@ using Avalonia.Platform;
using Avalonia.VisualTree;
using System;
using System.Reactive.Disposables;
+using Avalonia.Controls.Presenters;
+using Avalonia.Controls.Templates;
namespace Avalonia.Controls
{
@@ -78,7 +80,7 @@ namespace Avalonia.Controls
[PseudoClasses(":compactoverlay", ":compactinline", ":overlay", ":inline")]
[PseudoClasses(":left", ":right")]
[PseudoClasses(":lightdismiss")]
- public class SplitView : TemplatedControl
+ public class SplitView : ContentControl
{
/*
Pseudo classes & combos
@@ -87,12 +89,6 @@ namespace Avalonia.Controls
:left :right
*/
- ///
- /// Defines the property
- ///
- public static readonly StyledProperty ContentProperty =
- AvaloniaProperty.Register(nameof(Content));
-
///
/// Defines the property
///
@@ -133,8 +129,14 @@ namespace Avalonia.Controls
///
/// Defines the property
///
- public static readonly StyledProperty PaneProperty =
- AvaloniaProperty.Register(nameof(Pane));
+ public static readonly StyledProperty PaneProperty =
+ AvaloniaProperty.Register(nameof(Pane));
+
+ ///
+ /// Defines the property.
+ ///
+ public static readonly StyledProperty PaneTemplateProperty =
+ AvaloniaProperty.Register(nameof(PaneTemplate));
///
/// Defines the property
@@ -166,16 +168,7 @@ namespace Avalonia.Controls
CompactPaneLengthProperty.Changed.AddClassHandler((x, v) => x.OnCompactPaneLengthChanged(v));
PanePlacementProperty.Changed.AddClassHandler((x, v) => x.OnPanePlacementChanged(v));
DisplayModeProperty.Changed.AddClassHandler((x, v) => x.OnDisplayModeChanged(v));
- }
-
- ///
- /// Gets or sets the content of the SplitView
- ///
- [Content]
- public IControl Content
- {
- get => GetValue(ContentProperty);
- set => SetValue(ContentProperty, value);
+
}
///
@@ -265,11 +258,20 @@ namespace Avalonia.Controls
///
/// Gets or sets the Pane for the SplitView
///
- public IControl Pane
+ public object Pane
{
get => GetValue(PaneProperty);
set => SetValue(PaneProperty, value);
}
+
+ ///
+ /// Gets or sets the data template used to display the header content of the control.
+ ///
+ public IDataTemplate? PaneTemplate
+ {
+ get => GetValue(PaneTemplateProperty);
+ set => SetValue(PaneTemplateProperty, value);
+ }
///
/// Gets or sets whether WinUI equivalent LightDismissOverlayMode is enabled
@@ -312,6 +314,18 @@ namespace Avalonia.Controls
///
public event EventHandler PaneOpening;
+ protected override bool RegisterContentPresenter(IContentPresenter presenter)
+ {
+ var result = base.RegisterContentPresenter(presenter);
+
+ if (presenter.Name == "PART_PanePresenter")
+ {
+ return true;
+ }
+
+ return result;
+ }
+
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
diff --git a/src/Avalonia.Controls/Templates/FuncDataTemplate.cs b/src/Avalonia.Controls/Templates/FuncDataTemplate.cs
index 1afd86a11e..5dff13997e 100644
--- a/src/Avalonia.Controls/Templates/FuncDataTemplate.cs
+++ b/src/Avalonia.Controls/Templates/FuncDataTemplate.cs
@@ -1,5 +1,6 @@
using System;
using System.Reactive.Linq;
+using Avalonia.Controls.Primitives;
namespace Avalonia.Controls.Templates
{
@@ -30,6 +31,31 @@ namespace Avalonia.Controls.Templates
},
true);
+ ///
+ /// The default data template used in the case where no matching data template is found
+ /// but should be used.
+ ///
+ public static readonly FuncDataTemplate Access =
+ new FuncDataTemplate(
+ (data, s) =>
+ {
+ if (data != null)
+ {
+ var result = new AccessText();
+ result.Bind(TextBlock.TextProperty,
+ result.GetObservable(Control.DataContextProperty).Select(x => x?.ToString()));
+ return result;
+ }
+ else
+ {
+ return null;
+ }
+ },
+ true);
+
+ ///
+ /// The implementation of the method.
+ ///
private readonly Func _match;
private readonly bool _supportsRecycling;
@@ -42,7 +68,7 @@ namespace Avalonia.Controls.Templates
///
/// Whether the control can be recycled.
public FuncDataTemplate(
- Type type,
+ Type type,
Func build,
bool supportsRecycling = false)
: this(o => IsInstance(o, type), build, supportsRecycling)
diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs
index d61519e697..31517ba59d 100644
--- a/src/Avalonia.Controls/TextBlock.cs
+++ b/src/Avalonia.Controls/TextBlock.cs
@@ -3,6 +3,7 @@ using Avalonia.LogicalTree;
using Avalonia.Media;
using Avalonia.Media.TextFormatting;
using Avalonia.Metadata;
+using Avalonia.Layout;
namespace Avalonia.Controls
{
@@ -427,14 +428,32 @@ namespace Avalonia.Controls
case TextAlignment.Center:
offsetX = (width - TextLayout.Size.Width) / 2;
break;
+
case TextAlignment.Right:
- offsetX = width - TextLayout.Size.Width;
+ offsetX = width - TextLayout.Size.Width;
break;
}
var padding = Padding;
- using (context.PushPostTransform(Matrix.CreateTranslation(padding.Left + offsetX, padding.Top)))
+ var top = padding.Top;
+ var textSize = TextLayout.Size;
+
+ if (Bounds.Height < textSize.Height)
+ {
+ switch (VerticalAlignment)
+ {
+ case VerticalAlignment.Center:
+ top += (Bounds.Height - textSize.Height) / 2;
+ break;
+
+ case VerticalAlignment.Bottom:
+ top += (Bounds.Height - textSize.Height);
+ break;
+ }
+ }
+
+ using (context.PushPostTransform(Matrix.CreateTranslation(padding.Left + offsetX, top)))
{
TextLayout.Draw(context);
}
diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs
index 317b6d3f2e..54574a7e1c 100644
--- a/src/Avalonia.Controls/Window.cs
+++ b/src/Avalonia.Controls/Window.cs
@@ -451,7 +451,7 @@ namespace Avalonia.Controls
///
/// The dialog result.
///
- /// When the window is shown with the
+ /// When the window is shown with the
/// or method, the
/// resulting task will produce the value when the window
/// is closed.
diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs
index d9a0d17518..9363c28705 100644
--- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs
+++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs
@@ -23,6 +23,8 @@ namespace Avalonia.Diagnostics.ViewModels
if (visual is IControl control)
{
+ ElementName = control.Name;
+
var removed = Observable.FromEventPattern(
x => control.DetachedFromLogicalTree += x,
x => control.DetachedFromLogicalTree -= x);
@@ -61,6 +63,11 @@ namespace Avalonia.Diagnostics.ViewModels
private set { RaiseAndSetIfChanged(ref _classes, value); }
}
+ public string ElementName
+ {
+ get;
+ }
+
public IVisual Visual
{
get;
diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml
index b2d3a8bddb..8aad5fffd8 100644
--- a/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml
+++ b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml
@@ -26,6 +26,12 @@
+
+
+
+
diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs
index 10861538ae..c4f9185728 100644
--- a/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs
+++ b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs
@@ -76,7 +76,13 @@ namespace Avalonia.Diagnostics.Views
if (e.Modifiers == modifiers)
{
var point = (Root as IInputRoot)?.MouseDevice?.GetPosition(Root) ?? default;
- var control = Root.GetVisualsAt(point, x => (!(x is AdornerLayer) && x.IsVisible))
+
+ var control = Root.GetVisualsAt(point, x =>
+ {
+ if (x is AdornerLayer || !x.IsVisible) return false;
+ if (!(x is IInputElement ie)) return true;
+ return ie.IsHitTestVisible;
+ })
.FirstOrDefault();
if (control != null)
diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml
index a1e6ca7d37..98de9b611e 100644
--- a/src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml
+++ b/src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml
@@ -2,7 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:Avalonia.Diagnostics.ViewModels"
x:Class="Avalonia.Diagnostics.Views.TreePageView">
-
+
+
diff --git a/src/Avalonia.Dialogs/ApiCompatBaseline.txt b/src/Avalonia.Dialogs/ApiCompatBaseline.txt
new file mode 100644
index 0000000000..fcc74cf864
--- /dev/null
+++ b/src/Avalonia.Dialogs/ApiCompatBaseline.txt
@@ -0,0 +1 @@
+Total Issues: 0
diff --git a/src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj b/src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj
index 260d7350d2..81af76dc20 100644
--- a/src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj
+++ b/src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj
@@ -6,9 +6,7 @@
+
-
-
-
diff --git a/src/Avalonia.Input/MouseDevice.cs b/src/Avalonia.Input/MouseDevice.cs
index cec5029c18..5c63546f5d 100644
--- a/src/Avalonia.Input/MouseDevice.cs
+++ b/src/Avalonia.Input/MouseDevice.cs
@@ -19,6 +19,7 @@ namespace Avalonia.Input
private readonly Pointer _pointer;
private bool _disposed;
+ private PixelPoint? _position;
public MouseDevice(Pointer? pointer = null)
{
@@ -39,10 +40,11 @@ namespace Avalonia.Input
///
/// Gets the mouse position, in screen coordinates.
///
+ [Obsolete("Use events instead")]
public PixelPoint Position
{
- get;
- protected set;
+ get => _position ?? new PixelPoint(-1, -1);
+ protected set => _position = value;
}
///
@@ -91,7 +93,16 @@ namespace Avalonia.Input
public void SceneInvalidated(IInputRoot root, Rect rect)
{
- var clientPoint = root.PointToClient(Position);
+ // Pointer is outside of the target area
+ if (_position == null )
+ {
+ if (root.PointerOverElement != null)
+ ClearPointerOver(this, 0, root, PointerPointProperties.None, KeyModifiers.None);
+ return;
+ }
+
+
+ var clientPoint = root.PointToClient(_position.Value);
if (rect.Contains(clientPoint))
{
@@ -132,7 +143,7 @@ namespace Avalonia.Input
if(mouse._disposed)
return;
- Position = e.Root.PointToScreen(e.Position);
+ _position = e.Root.PointToScreen(e.Position);
var props = CreateProperties(e);
var keyModifiers = KeyModifiersUtils.ConvertToKey(e.InputModifiers);
switch (e.Type)
@@ -176,6 +187,7 @@ namespace Avalonia.Input
device = device ?? throw new ArgumentNullException(nameof(device));
root = root ?? throw new ArgumentNullException(nameof(root));
+ _position = null;
ClearPointerOver(this, timestamp, root, properties, inputModifiers);
}
diff --git a/src/Avalonia.Layout/Properties/AssemblyInfo.cs b/src/Avalonia.Layout/Properties/AssemblyInfo.cs
index 0a6a32493a..63afaa8e3e 100644
--- a/src/Avalonia.Layout/Properties/AssemblyInfo.cs
+++ b/src/Avalonia.Layout/Properties/AssemblyInfo.cs
@@ -1,7 +1,9 @@
using System.Runtime.CompilerServices;
using Avalonia.Metadata;
-
+#if SIGNED_BUILD
+[assembly: InternalsVisibleTo("Avalonia.Layout.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
+#else
[assembly: InternalsVisibleTo("Avalonia.Layout.UnitTests")]
-
+#endif
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Layout")]
diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs
index 5d35c773d7..0ecf8f856a 100644
--- a/src/Avalonia.Native/WindowImplBase.cs
+++ b/src/Avalonia.Native/WindowImplBase.cs
@@ -251,6 +251,9 @@ namespace Avalonia.Native
public bool RawTextInputEvent(uint timeStamp, string text)
{
+ if (_inputRoot is null)
+ return false;
+
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
var args = new RawTextInputEventArgs(_keyboard, timeStamp, _inputRoot, text);
@@ -262,6 +265,9 @@ namespace Avalonia.Native
public bool RawKeyEvent(AvnRawKeyEventType type, uint timeStamp, AvnInputModifiers modifiers, uint key)
{
+ if (_inputRoot is null)
+ return false;
+
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
var args = new RawKeyEventArgs(_keyboard, timeStamp, _inputRoot, (RawKeyEventType)type, (Key)key, (RawInputModifiers)modifiers);
@@ -278,6 +284,9 @@ namespace Avalonia.Native
public void RawMouseEvent(AvnRawMouseEventType type, uint timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta)
{
+ if (_inputRoot is null)
+ return;
+
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
switch (type)
@@ -332,8 +341,7 @@ namespace Avalonia.Native
public void Invalidate(Rect rect)
{
- if (!_deferredRendering && _native != null)
- _native.Invalidate(new AvnRect { Height = rect.Height, Width = rect.Width, X = rect.X, Y = rect.Y });
+ _native?.Invalidate(new AvnRect { Height = rect.Height, Width = rect.Width, X = rect.X, Y = rect.Y });
}
public void SetInputRoot(IInputRoot inputRoot)
diff --git a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs
index 8c9b028164..3a332f37ad 100644
--- a/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs
+++ b/src/Avalonia.OpenGL/Angle/AngleEglInterface.cs
@@ -1,15 +1,13 @@
using System;
using System.Runtime.InteropServices;
using Avalonia.OpenGL.Egl;
-using Avalonia.Platform;
-using Avalonia.Platform.Interop;
namespace Avalonia.OpenGL.Angle
{
public class AngleEglInterface : EglInterface
{
- [DllImport("libegl.dll", CharSet = CharSet.Ansi)]
- static extern IntPtr eglGetProcAddress(string proc);
+ [DllImport("av_libGLESv2.dll", CharSet = CharSet.Ansi)]
+ static extern IntPtr EGL_GetProcAddress(string proc);
public AngleEglInterface() : base(LoadAngle())
{
@@ -20,14 +18,14 @@ namespace Avalonia.OpenGL.Angle
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
- var disp = eglGetProcAddress("eglGetPlatformDisplayEXT");
+ var disp = EGL_GetProcAddress("eglGetPlatformDisplayEXT");
if (disp == IntPtr.Zero)
{
throw new OpenGlException("libegl.dll doesn't have eglGetPlatformDisplayEXT entry point");
}
- return eglGetProcAddress;
+ return EGL_GetProcAddress;
}
throw new PlatformNotSupportedException();
diff --git a/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs
index 191fb53204..94e7728d68 100644
--- a/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs
+++ b/src/Avalonia.OpenGL/Angle/AngleWin32EglDisplay.cs
@@ -82,7 +82,14 @@ namespace Avalonia.OpenGL.Angle
{
if (PlatformApi != AngleOptions.PlatformApi.DirectX11)
throw new InvalidOperationException("Current platform API is " + PlatformApi);
- return egl.CreatePBufferFromClientBuffer(EGL_D3D_TEXTURE_ANGLE, handle, new[] { EGL_NONE, EGL_NONE });
+ return egl.CreatePBufferFromClientBuffer(EGL_D3D_TEXTURE_ANGLE, handle, new[] { EGL_NONE, EGL_NONE });
+ }
+
+ public EglSurface WrapDirect3D11Texture(EglPlatformOpenGlInterface egl, IntPtr handle, int offsetX, int offsetY, int width, int height)
+ {
+ if (PlatformApi != AngleOptions.PlatformApi.DirectX11)
+ throw new InvalidOperationException("Current platform API is " + PlatformApi);
+ return egl.CreatePBufferFromClientBuffer(EGL_D3D_TEXTURE_ANGLE, handle, new[] { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_TRUE, EGL_TEXTURE_OFFSET_X_ANGLE, offsetX, EGL_TEXTURE_OFFSET_Y_ANGLE, offsetY, EGL_NONE });
}
}
}
diff --git a/src/Avalonia.OpenGL/Egl/EglConsts.cs b/src/Avalonia.OpenGL/Egl/EglConsts.cs
index 58f5f1cef5..530d3401f6 100644
--- a/src/Avalonia.OpenGL/Egl/EglConsts.cs
+++ b/src/Avalonia.OpenGL/Egl/EglConsts.cs
@@ -205,5 +205,11 @@ namespace Avalonia.OpenGL.Egl
public const int EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE = 0x3200;
public const int EGL_D3D_TEXTURE_ANGLE = 0x33A3;
+
+
+ public const int EGL_TEXTURE_OFFSET_X_ANGLE = 0x3490;
+ public const int EGL_TEXTURE_OFFSET_Y_ANGLE = 0x3491;
+
+ public const int EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE = 0x33A6;
}
}
diff --git a/src/Avalonia.ReactiveUI.Events/Avalonia.ReactiveUI.Events.csproj b/src/Avalonia.ReactiveUI.Events/Avalonia.ReactiveUI.Events.csproj
index 75eeb92f42..7f58e455f9 100644
--- a/src/Avalonia.ReactiveUI.Events/Avalonia.ReactiveUI.Events.csproj
+++ b/src/Avalonia.ReactiveUI.Events/Avalonia.ReactiveUI.Events.csproj
@@ -2,6 +2,7 @@
netstandard2.0
Avalonia.ReactiveUI.Events
+ false
diff --git a/src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj b/src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj
index d01a495108..624c5772a9 100644
--- a/src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj
+++ b/src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj
@@ -2,6 +2,7 @@
netstandard2.0
Avalonia.ReactiveUI
+ false
diff --git a/src/Avalonia.ReactiveUI/ReactiveUserControl.cs b/src/Avalonia.ReactiveUI/ReactiveUserControl.cs
index fc48a8853d..31f4691c90 100644
--- a/src/Avalonia.ReactiveUI/ReactiveUserControl.cs
+++ b/src/Avalonia.ReactiveUI/ReactiveUserControl.cs
@@ -1,3 +1,6 @@
+using System;
+using System.Reactive.Disposables;
+using System.Reactive.Linq;
using Avalonia;
using Avalonia.VisualTree;
using Avalonia.Controls;
@@ -6,8 +9,10 @@ using ReactiveUI;
namespace Avalonia.ReactiveUI
{
///
- /// A ReactiveUI UserControl that implements
- /// and will activate your ViewModel automatically if it supports activation.
+ /// A ReactiveUI that implements the interface and
+ /// will activate your ViewModel automatically if the view model implements .
+ /// When the DataContext property changes, this class will update the ViewModel property with the new DataContext
+ /// value, and vice versa.
///
/// ViewModel type.
public class ReactiveUserControl : UserControl, IViewFor where TViewModel : class
@@ -20,7 +25,14 @@ namespace Avalonia.ReactiveUI
///
public ReactiveUserControl()
{
- DataContextChanged += (sender, args) => ViewModel = DataContext as TViewModel;
+ // This WhenActivated block calls ViewModel's WhenActivated
+ // block if the ViewModel implements IActivatableViewModel.
+ this.WhenActivated(disposables => { });
+
+ this.ObservableForProperty(x => x.ViewModel, false, true)
+ .Subscribe(args => DataContext = args.Value);
+ this.ObservableForProperty(x => x.DataContext, false, true)
+ .Subscribe(args => ViewModel = args.Value as TViewModel);
}
///
diff --git a/src/Avalonia.ReactiveUI/ReactiveWindow.cs b/src/Avalonia.ReactiveUI/ReactiveWindow.cs
index 5695a727af..1204266b63 100644
--- a/src/Avalonia.ReactiveUI/ReactiveWindow.cs
+++ b/src/Avalonia.ReactiveUI/ReactiveWindow.cs
@@ -1,3 +1,6 @@
+using System;
+using System.Reactive.Disposables;
+using System.Reactive.Linq;
using Avalonia;
using Avalonia.VisualTree;
using Avalonia.Controls;
@@ -6,8 +9,10 @@ using ReactiveUI;
namespace Avalonia.ReactiveUI
{
///
- /// A ReactiveUI Window that implements
- /// and will activate your ViewModel automatically if it supports activation.
+ /// A ReactiveUI that implements the interface and will
+ /// activate your ViewModel automatically if the view model implements . When
+ /// the DataContext property changes, this class will update the ViewModel property with the new DataContext value,
+ /// and vice versa.
///
/// ViewModel type.
public class ReactiveWindow : Window, IViewFor where TViewModel : class
@@ -20,7 +25,14 @@ namespace Avalonia.ReactiveUI
///
public ReactiveWindow()
{
- DataContextChanged += (sender, args) => ViewModel = DataContext as TViewModel;
+ // This WhenActivated block calls ViewModel's WhenActivated
+ // block if the ViewModel implements IActivatableViewModel.
+ this.WhenActivated(disposables => { });
+
+ this.ObservableForProperty(x => x.ViewModel, false, true)
+ .Subscribe(args => DataContext = args.Value);
+ this.ObservableForProperty(x => x.DataContext, false, true)
+ .Subscribe(args => ViewModel = args.Value as TViewModel);
}
///
diff --git a/src/Avalonia.Styling/Properties/AssemblyInfo.cs b/src/Avalonia.Styling/Properties/AssemblyInfo.cs
index b231f3b406..34c71fffe3 100644
--- a/src/Avalonia.Styling/Properties/AssemblyInfo.cs
+++ b/src/Avalonia.Styling/Properties/AssemblyInfo.cs
@@ -5,4 +5,8 @@ using Avalonia.Metadata;
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.LogicalTree")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Styling")]
-[assembly: InternalsVisibleTo("Avalonia.Styling.UnitTests")]
\ No newline at end of file
+#if SIGNED_BUILD
+[assembly: InternalsVisibleTo("Avalonia.Styling.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
+#else
+[assembly: InternalsVisibleTo("Avalonia.Styling.UnitTests")]
+#endif
diff --git a/src/Avalonia.Themes.Default/DefaultTheme.xaml b/src/Avalonia.Themes.Default/DefaultTheme.xaml
index 625b409598..107fc07875 100644
--- a/src/Avalonia.Themes.Default/DefaultTheme.xaml
+++ b/src/Avalonia.Themes.Default/DefaultTheme.xaml
@@ -12,7 +12,8 @@
-
+
+
diff --git a/src/Avalonia.Themes.Default/Label.xaml b/src/Avalonia.Themes.Default/Label.xaml
new file mode 100644
index 0000000000..d93381aa69
--- /dev/null
+++ b/src/Avalonia.Themes.Default/Label.xaml
@@ -0,0 +1,17 @@
+
diff --git a/src/Avalonia.Themes.Default/SplitView.xaml b/src/Avalonia.Themes.Default/SplitView.xaml
index 2fb59cdbc4..18da3edb46 100644
--- a/src/Avalonia.Themes.Default/SplitView.xaml
+++ b/src/Avalonia.Themes.Default/SplitView.xaml
@@ -32,12 +32,12 @@
ClipToBounds="True"
HorizontalAlignment="Left"
ZIndex="100">
-
+
-
+
@@ -106,14 +106,14 @@
ClipToBounds="True"
HorizontalAlignment="Right"
ZIndex="100">
-
+
-
+
diff --git a/src/Avalonia.Themes.Fluent/ButtonSpinner.xaml b/src/Avalonia.Themes.Fluent/ButtonSpinner.xaml
index 82265ea282..12b4845522 100644
--- a/src/Avalonia.Themes.Fluent/ButtonSpinner.xaml
+++ b/src/Avalonia.Themes.Fluent/ButtonSpinner.xaml
@@ -65,56 +65,59 @@
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/ComboBox.xaml b/src/Avalonia.Themes.Fluent/ComboBox.xaml
index 8155264f18..2eee656dc6 100644
--- a/src/Avalonia.Themes.Fluent/ComboBox.xaml
+++ b/src/Avalonia.Themes.Fluent/ComboBox.xaml
@@ -44,105 +44,107 @@
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ Grid.Column="1"
+ IsHitTestVisible="False"
+ Margin="0,0,10,0"
+ Height="12"
+ Width="12"
+ HorizontalAlignment="Right"
+ VerticalAlignment="Center">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -232,4 +234,9 @@
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/DataValidationErrors.xaml b/src/Avalonia.Themes.Fluent/DataValidationErrors.xaml
index 902fc74c0c..ed31f7b573 100644
--- a/src/Avalonia.Themes.Fluent/DataValidationErrors.xaml
+++ b/src/Avalonia.Themes.Fluent/DataValidationErrors.xaml
@@ -14,39 +14,31 @@
-
-
+
+
-
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/DatePicker.xaml b/src/Avalonia.Themes.Fluent/DatePicker.xaml
index 6fbfa1bbf7..b6e36861e0 100644
--- a/src/Avalonia.Themes.Fluent/DatePicker.xaml
+++ b/src/Avalonia.Themes.Fluent/DatePicker.xaml
@@ -125,77 +125,79 @@
-
-
+
+
+
-
+
-
-
-
+
+
+
-
+
+
@@ -228,6 +230,11 @@
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/NumericUpDown.xaml b/src/Avalonia.Themes.Fluent/NumericUpDown.xaml
index cc5e2234f8..1da48ebd8a 100644
--- a/src/Avalonia.Themes.Fluent/NumericUpDown.xaml
+++ b/src/Avalonia.Themes.Fluent/NumericUpDown.xaml
@@ -39,6 +39,7 @@
VerticalContentAlignment="Stretch"
AllowSpin="{TemplateBinding AllowSpin}"
ShowButtonSpinner="{TemplateBinding ShowButtonSpinner}"
+ DataValidationErrors.Errors="{TemplateBinding (DataValidationErrors.Errors)}"
ButtonSpinnerLocation="{TemplateBinding ButtonSpinnerLocation}">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
@@ -102,56 +104,58 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
@@ -260,4 +264,12 @@
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/SplitView.xaml b/src/Avalonia.Themes.Fluent/SplitView.xaml
index 71e92459f1..7d6f7a9b9a 100644
--- a/src/Avalonia.Themes.Fluent/SplitView.xaml
+++ b/src/Avalonia.Themes.Fluent/SplitView.xaml
@@ -32,12 +32,12 @@
ClipToBounds="True"
HorizontalAlignment="Left"
ZIndex="100">
-
+
-
+
@@ -106,14 +106,14 @@
ClipToBounds="True"
HorizontalAlignment="Right"
ZIndex="100">
-
+
-
+
diff --git a/src/Avalonia.Themes.Fluent/TextBox.xaml b/src/Avalonia.Themes.Fluent/TextBox.xaml
index 162835ae10..139a61abdf 100644
--- a/src/Avalonia.Themes.Fluent/TextBox.xaml
+++ b/src/Avalonia.Themes.Fluent/TextBox.xaml
@@ -36,16 +36,7 @@
-
-
-
-
-
+
-
-
-
+
-
-
+
diff --git a/src/Avalonia.Themes.Fluent/TimePicker.xaml b/src/Avalonia.Themes.Fluent/TimePicker.xaml
index 84352213e1..91969d8733 100644
--- a/src/Avalonia.Themes.Fluent/TimePicker.xaml
+++ b/src/Avalonia.Themes.Fluent/TimePicker.xaml
@@ -41,94 +41,96 @@
-
-
+
+
+
-
+
-
-
-
+
+
+
-
+
+
@@ -161,6 +163,10 @@
+
+