diff --git a/.gitmodules b/.gitmodules index 0b2349ad42..bdd5d5ca4d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,9 +5,6 @@ path = src/Avalonia.HtmlRenderer/external url = https://github.com/AvaloniaUI/HTML-Renderer.git branch = perspex-pcl -[submodule "src/Markup/Avalonia.Markup.Xaml/OmniXAML"] - path = src/Markup/Avalonia.Markup.Xaml/OmniXAML - url = https://github.com/AvaloniaUI/OmniXAML.git -[submodule "src/Markup/Avalonia.Markup.Xaml/glass"] - path = src/Markup/Avalonia.Markup.Xaml/glass - url = https://github.com/SuperJMN/glass +[submodule "src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github"] + path = src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github + url = https://github.com/cwensley/Portable.Xaml.git diff --git a/build.cake b/build.cake index cab2ba9b0a..c56089ab55 100644 --- a/build.cake +++ b/build.cake @@ -403,7 +403,8 @@ Task("Inspect") { var badIssues = new []{"PossibleNullReferenceException"}; var whitelist = new []{"tests", "src\\android", "src\\ios", - "src\\windows\\avalonia.designer", "src\\avalonia.htmlrenderer\\external"}; + "src\\windows\\avalonia.designer", "src\\avalonia.htmlrenderer\\external", + "src\\markup\\avalonia.markup.xaml\\portablexaml\\portable.xaml.github"}; Information("Running code inspections"); diff --git a/build/Markup.props b/build/Markup.props index 36c4cb28d8..0e4baf5da9 100644 --- a/build/Markup.props +++ b/build/Markup.props @@ -5,5 +5,9 @@ + + + + diff --git a/build/XUnit.props b/build/XUnit.props index 27e0afc987..d59cee6536 100644 --- a/build/XUnit.props +++ b/build/XUnit.props @@ -12,4 +12,16 @@ + + true + + + + + true + + diff --git a/packages.cake b/packages.cake index 07c77f64fd..5f268188dc 100644 --- a/packages.cake +++ b/packages.cake @@ -8,6 +8,42 @@ public class Packages public string NugetPackagesDir {get; private set;} public string SkiaSharpVersion {get; private set; } public string SkiaSharpLinuxVersion {get; private set; } + public Dictionary>> PackageVersions{get; private set;} + + + + class DependencyBuilder : List + { + Packages _parent; + public DependencyBuilder(Packages parent) + { + _parent = parent; + } + + string GetVersion(string name) + { + return _parent.PackageVersions[name].First().Item1; + } + + + public DependencyBuilder Dep(string name, params string[] fws) + { + if(fws.Length == 0) + Add(new NuSpecDependency() { Id = name, Version = GetVersion(name) }); + foreach(var fw in fws) + Add(new NuSpecDependency() { Id = name, TargetFramework = fw, Version = GetVersion(name) }); + return this; + } + public DependencyBuilder Deps(string[] fws, params string[] deps) + { + foreach(var fw in fws) + foreach(var name in deps) + Add(new NuSpecDependency() { Id = name, TargetFramework = fw, Version = GetVersion(name) }); + return this; + } + } + + //new NuSpecDependency() { Id = "System.Threading.ThreadPool", TargetFramework = "netcoreapp1.0", Version = "4.3.0" }, public Packages(ICakeContext context, Parameters parameters) { // NUGET NUSPECS @@ -26,7 +62,7 @@ public class Packages // Key: Package Id // Value is Tuple where Item1: Package Version, Item2: The *.csproj/*.props file path. var packageVersions = new Dictionary>>(); - + PackageVersions = packageVersions; System.IO.Directory.EnumerateFiles(((DirectoryPath)context.Directory("./build")).FullPath, "*.props", SearchOption.AllDirectories).ToList().ForEach(fileName => { @@ -150,12 +186,12 @@ public class Packages }; var coreLibrariesFiles = coreLibraries.Select((lib) => { - return (FilePath)context.File(lib[0] + lib[1] + "/bin/" + parameters.DirSuffix + "/netstandard1.1/" + lib[1] + lib[2]); + return (FilePath)context.File(lib[0] + lib[1] + "/bin/" + parameters.DirSuffix + "/netstandard1.3/" + lib[1] + lib[2]); }).ToList(); var coreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => { return new NuSpecContent { - Source = file.FullPath, Target = "lib/netstandard1.1" + Source = file.FullPath, Target = "lib/netstandard1.3" }; }); @@ -195,13 +231,12 @@ public class Packages new NuGetPackSettings() { Id = "Avalonia", - Dependencies = new [] + Dependencies = new DependencyBuilder(this) { new NuSpecDependency() { Id = "Serilog", Version = SerilogVersion }, new NuSpecDependency() { Id = "Splat", Version = SplatVersion }, new NuSpecDependency() { Id = "Sprache", Version = SpracheVersion }, new NuSpecDependency() { Id = "System.Reactive", Version = SystemReactiveVersion }, - new NuSpecDependency() { Id = "System.ValueTuple", Version = SystemValueTupleVersion }, //.NET Core new NuSpecDependency() { Id = "System.Threading.ThreadPool", TargetFramework = "netcoreapp1.0", Version = "4.3.0" }, new NuSpecDependency() { Id = "Microsoft.Extensions.DependencyModel", TargetFramework = "netcoreapp1.0", Version = "1.1.0" }, @@ -210,8 +245,11 @@ public class Packages new NuSpecDependency() { Id = "Serilog", TargetFramework = "netcoreapp1.0", Version = SerilogVersion }, new NuSpecDependency() { Id = "Sprache", TargetFramework = "netcoreapp1.0", Version = SpracheVersion }, new NuSpecDependency() { Id = "System.Reactive", TargetFramework = "netcoreapp1.0", Version = SystemReactiveVersion }, - new NuSpecDependency() { Id = "System.ValueTuple", TargetFramework = "netcoreapp1.0", Version = SystemValueTupleVersion } - }, + } + .Deps(new string[]{null, "netcoreapp1.0"}, + "System.ValueTuple", "System.ComponentModel.TypeConverter", "System.ComponentModel.Primitives", + "System.Runtime.Serialization.Primitives", "System.Xml.XmlDocument") + .ToArray(), Files = coreLibrariesNuSpecContent .Concat(win32CoreLibrariesNuSpecContent).Concat(net45RuntimePlatform) .Concat(netcoreappCoreLibrariesNuSpecContent).Concat(netCoreRuntimePlatform) @@ -231,9 +269,9 @@ public class Packages }, Files = new [] { - new NuSpecContent { Source = "Avalonia.HtmlRenderer.dll", Target = "lib/netstandard1.1" } + new NuSpecContent { Source = "Avalonia.HtmlRenderer.dll", Target = "lib/netstandard1.3" } }, - BasePath = context.Directory("./src/Avalonia.HtmlRenderer/bin/" + parameters.DirSuffix + "/netstandard1.1"), + BasePath = context.Directory("./src/Avalonia.HtmlRenderer/bin/" + parameters.DirSuffix + "/netstandard1.3"), OutputDirectory = parameters.NugetRoot } }; @@ -347,7 +385,7 @@ public class Packages Files = new [] { new NuSpecContent { Source = "Avalonia.Win32/bin/" + parameters.DirSuffix + "/Avalonia.Win32.dll", Target = "lib/net45" }, - new NuSpecContent { Source = "Avalonia.Win32.NetStandard/bin/" + parameters.DirSuffix + "/netstandard1.1/Avalonia.Win32.dll", Target = "lib/netstandard1.1" } + new NuSpecContent { Source = "Avalonia.Win32.NetStandard/bin/" + parameters.DirSuffix + "/netstandard1.3/Avalonia.Win32.dll", Target = "lib/netstandard1.3" } }, BasePath = context.Directory("./src/Windows"), OutputDirectory = parameters.NugetRoot @@ -402,9 +440,9 @@ public class Packages }, Files = new [] { - new NuSpecContent { Source = "Avalonia.Gtk3.dll", Target = "lib/netstandard1.1" } + new NuSpecContent { Source = "Avalonia.Gtk3.dll", Target = "lib/netstandard1.3" } }, - BasePath = context.Directory("./src/Gtk/Avalonia.Gtk3/bin/" + parameters.DirSuffix + "/netstandard1.1"), + BasePath = context.Directory("./src/Gtk/Avalonia.Gtk3/bin/" + parameters.DirSuffix + "/netstandard1.3"), OutputDirectory = parameters.NugetRoot }, /////////////////////////////////////////////////////////////////////////////// @@ -460,9 +498,9 @@ public class Packages new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", TargetFramework="net45", Version = parameters.Version }, new NuSpecDependency() { Id = "Avalonia.Gtk3", TargetFramework="net45", Version = parameters.Version }, //.NET Core - new NuSpecDependency() { Id = "Avalonia.Win32", TargetFramework="netcoreapp1.1", Version = parameters.Version }, - new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", TargetFramework="netcoreapp1.1", Version = parameters.Version }, - new NuSpecDependency() { Id = "Avalonia.Gtk3", TargetFramework="netcoreapp1.1", Version = parameters.Version } + new NuSpecDependency() { Id = "Avalonia.Win32", TargetFramework="netcoreapp1.0", Version = parameters.Version }, + new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", TargetFramework="netcoreapp1.0", Version = parameters.Version }, + new NuSpecDependency() { Id = "Avalonia.Gtk3", TargetFramework="netcoreapp1.0", Version = parameters.Version } }, Files = new NuSpecContent[] { diff --git a/samples/BindingTest/BindingTest.csproj b/samples/BindingTest/BindingTest.csproj index b62f9a54b6..8e78b0c2cd 100644 --- a/samples/BindingTest/BindingTest.csproj +++ b/samples/BindingTest/BindingTest.csproj @@ -9,7 +9,7 @@ Properties BindingTest BindingTest - v4.5 + v4.6.1 512 true diff --git a/samples/BindingTest/MainWindow.xaml b/samples/BindingTest/MainWindow.xaml index 95f671fd84..7d633bcd0c 100644 --- a/samples/BindingTest/MainWindow.xaml +++ b/samples/BindingTest/MainWindow.xaml @@ -44,6 +44,8 @@ + + diff --git a/samples/BindingTest/ViewModels/MainWindowViewModel.cs b/samples/BindingTest/ViewModels/MainWindowViewModel.cs index 4b58bf2279..2ec052c258 100644 --- a/samples/BindingTest/ViewModels/MainWindowViewModel.cs +++ b/samples/BindingTest/ViewModels/MainWindowViewModel.cs @@ -49,6 +49,9 @@ namespace BindingTest.ViewModels Thread.Sleep(1000); } }); + + CurrentTimeObservable = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1)) + .Select(x => DateTimeOffset.Now.ToString()); } public ObservableCollection Items { get; } @@ -85,6 +88,7 @@ namespace BindingTest.ViewModels private set { this.RaiseAndSetIfChanged(ref _currentTime, value); } } + public IObservable CurrentTimeObservable { get; } public ReactiveCommand StringValueCommand { get; } public DataAnnotationsErrorViewModel DataAnnotationsValidation { get; } = new DataAnnotationsErrorViewModel(); diff --git a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj index 59c8c53137..a3940a3a7d 100644 --- a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj +++ b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj @@ -9,7 +9,7 @@ Properties ControlCatalog.Desktop ControlCatalog.Desktop - v4.5 + v4.6.1 512 true diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj index 2a9f8f70de..3f978fa7f4 100644 --- a/samples/ControlCatalog/ControlCatalog.csproj +++ b/samples/ControlCatalog/ControlCatalog.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 False false diff --git a/samples/RenderTest/RenderTest.csproj b/samples/RenderTest/RenderTest.csproj index ed6194e0e1..95f1479b6b 100644 --- a/samples/RenderTest/RenderTest.csproj +++ b/samples/RenderTest/RenderTest.csproj @@ -9,7 +9,7 @@ Properties RenderTest RenderTest - v4.5 + v4.6.1 512 true diff --git a/samples/VirtualizationTest/VirtualizationTest.csproj b/samples/VirtualizationTest/VirtualizationTest.csproj index 89115016bf..327e659966 100644 --- a/samples/VirtualizationTest/VirtualizationTest.csproj +++ b/samples/VirtualizationTest/VirtualizationTest.csproj @@ -9,7 +9,7 @@ Properties VirtualizationTest VirtualizationTest - v4.5 + v4.6.1 512 true diff --git a/samples/interop/GtkInteropDemo/GtkInteropDemo.csproj b/samples/interop/GtkInteropDemo/GtkInteropDemo.csproj index 8cbaf7a627..56fa426f3c 100644 --- a/samples/interop/GtkInteropDemo/GtkInteropDemo.csproj +++ b/samples/interop/GtkInteropDemo/GtkInteropDemo.csproj @@ -9,7 +9,7 @@ Properties GtkInteropDemo GtkInteropDemo - v4.6 + v4.6.1 512 true diff --git a/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj b/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj index 84bd709f8c..2fa3ba30b9 100644 --- a/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj +++ b/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj @@ -9,7 +9,7 @@ Properties WindowsInteropTest WindowsInteropTest - v4.6 + v4.6.1 512 true diff --git a/src/Avalonia.Animation/Avalonia.Animation.csproj b/src/Avalonia.Animation/Avalonia.Animation.csproj index f02ec2f31c..8f832dabcf 100644 --- a/src/Avalonia.Animation/Avalonia.Animation.csproj +++ b/src/Avalonia.Animation/Avalonia.Animation.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 false diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj index cc458545e2..e0d12ce262 100644 --- a/src/Avalonia.Base/Avalonia.Base.csproj +++ b/src/Avalonia.Base/Avalonia.Base.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 false diff --git a/src/Avalonia.Base/Metadata/AmbientAttribute.cs b/src/Avalonia.Base/Metadata/AmbientAttribute.cs new file mode 100644 index 0000000000..db36953300 --- /dev/null +++ b/src/Avalonia.Base/Metadata/AmbientAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Metadata +{ + /// + /// Defines the ambient class/property + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, Inherited = true)] + public class AmbientAttribute : Attribute + { + } +} diff --git a/src/Avalonia.Base/Metadata/TemplateContent.cs b/src/Avalonia.Base/Metadata/TemplateContent.cs new file mode 100644 index 0000000000..ecc16b04a2 --- /dev/null +++ b/src/Avalonia.Base/Metadata/TemplateContent.cs @@ -0,0 +1,15 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Metadata +{ + /// + /// Defines the property that contains the object's content in markup. + /// + [AttributeUsage(AttributeTargets.Property)] + public class TemplateContentAttribute : Attribute + { + } +} diff --git a/src/Avalonia.Controls/Avalonia.Controls.csproj b/src/Avalonia.Controls/Avalonia.Controls.csproj index 37f348340c..037546b186 100644 --- a/src/Avalonia.Controls/Avalonia.Controls.csproj +++ b/src/Avalonia.Controls/Avalonia.Controls.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 false diff --git a/src/Avalonia.Controls/Control.cs b/src/Avalonia.Controls/Control.cs index 83a76cb1a7..eca5967a58 100644 --- a/src/Avalonia.Controls/Control.cs +++ b/src/Avalonia.Controls/Control.cs @@ -355,18 +355,28 @@ namespace Avalonia.Controls if (--_initCount == 0 && _isAttachedToLogicalTree) { - if (!_styled) - { - RegisterWithNameScope(); - ApplyStyling(); - _styled = true; - } + InitializeStylesIfNeeded(); - if (!IsInitialized) - { - IsInitialized = true; - Initialized?.Invoke(this, EventArgs.Empty); - } + InitializeIfNeeded(); + } + } + + private void InitializeStylesIfNeeded(bool force = false) + { + if (_initCount == 0 && (!_styled || force)) + { + RegisterWithNameScope(); + ApplyStyling(); + _styled = true; + } + } + + private void InitializeIfNeeded() + { + if (_initCount == 0 && !IsInitialized) + { + IsInitialized = true; + Initialized?.Invoke(this, EventArgs.Empty); } } @@ -580,11 +590,7 @@ namespace Avalonia.Controls { base.OnAttachedToVisualTreeCore(e); - if (!IsInitialized) - { - IsInitialized = true; - Initialized?.Invoke(this, EventArgs.Empty); - } + InitializeIfNeeded(); } /// @@ -752,12 +758,7 @@ namespace Avalonia.Controls { _isAttachedToLogicalTree = true; - if (_initCount == 0) - { - RegisterWithNameScope(); - ApplyStyling(); - _styled = true; - } + InitializeStylesIfNeeded(true); OnAttachedToLogicalTree(e); } diff --git a/src/Avalonia.Controls/Panel.cs b/src/Avalonia.Controls/Panel.cs index 793399841c..3272d3779b 100644 --- a/src/Avalonia.Controls/Panel.cs +++ b/src/Avalonia.Controls/Panel.cs @@ -64,9 +64,12 @@ namespace Avalonia.Controls { Contract.Requires(value != null); - VisualChildren.Clear(); - _children.Clear(); - _children.AddRange(value); + if (_children != value) + { + VisualChildren.Clear(); + _children.Clear(); + _children.AddRange(value); + } } } diff --git a/src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj b/src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj index be0b98b24c..a68e8760f2 100644 --- a/src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj +++ b/src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 false diff --git a/src/Avalonia.DesignerSupport/DesignerAssist.cs b/src/Avalonia.DesignerSupport/DesignerAssist.cs index 8d30f3cf25..2f5fc79147 100644 --- a/src/Avalonia.DesignerSupport/DesignerAssist.cs +++ b/src/Avalonia.DesignerSupport/DesignerAssist.cs @@ -5,8 +5,6 @@ using System.IO; using System.Linq; using System.Reflection; using System.Text; -using OmniXaml; -using OmniXaml.ObjectAssembler; using Avalonia.Controls; using Avalonia.Controls.Platform; using Avalonia.Markup.Xaml; diff --git a/src/Avalonia.Diagnostics/Avalonia.Diagnostics.csproj b/src/Avalonia.Diagnostics/Avalonia.Diagnostics.csproj index e4752f6662..be3f397283 100644 --- a/src/Avalonia.Diagnostics/Avalonia.Diagnostics.csproj +++ b/src/Avalonia.Diagnostics/Avalonia.Diagnostics.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 false diff --git a/src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj b/src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj index 932afbe0e6..2fbcba40c8 100644 --- a/src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj +++ b/src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj @@ -9,7 +9,7 @@ Properties Avalonia.DotNetFrameworkRuntime Avalonia.DotNetFrameworkRuntime - v4.5 + v4.6.1 512 diff --git a/src/Avalonia.HtmlRenderer/Avalonia.HtmlRenderer.csproj b/src/Avalonia.HtmlRenderer/Avalonia.HtmlRenderer.csproj index b1fc7a4278..f715217e42 100644 --- a/src/Avalonia.HtmlRenderer/Avalonia.HtmlRenderer.csproj +++ b/src/Avalonia.HtmlRenderer/Avalonia.HtmlRenderer.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 False False false diff --git a/src/Avalonia.Input/Avalonia.Input.csproj b/src/Avalonia.Input/Avalonia.Input.csproj index e9e74e24fe..b5482ebce1 100644 --- a/src/Avalonia.Input/Avalonia.Input.csproj +++ b/src/Avalonia.Input/Avalonia.Input.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 false diff --git a/src/Avalonia.Interactivity/Avalonia.Interactivity.csproj b/src/Avalonia.Interactivity/Avalonia.Interactivity.csproj index ab9ab88a37..9d22de86b3 100644 --- a/src/Avalonia.Interactivity/Avalonia.Interactivity.csproj +++ b/src/Avalonia.Interactivity/Avalonia.Interactivity.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 false diff --git a/src/Avalonia.Layout/Avalonia.Layout.csproj b/src/Avalonia.Layout/Avalonia.Layout.csproj index 45a40d2fd4..d0260391d8 100644 --- a/src/Avalonia.Layout/Avalonia.Layout.csproj +++ b/src/Avalonia.Layout/Avalonia.Layout.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 false diff --git a/src/Avalonia.Logging.Serilog/Avalonia.Logging.Serilog.csproj b/src/Avalonia.Logging.Serilog/Avalonia.Logging.Serilog.csproj index 9aa81c19f9..508ede7f7d 100644 --- a/src/Avalonia.Logging.Serilog/Avalonia.Logging.Serilog.csproj +++ b/src/Avalonia.Logging.Serilog/Avalonia.Logging.Serilog.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 false diff --git a/src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj b/src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj index 28522d8849..2d66b62eab 100644 --- a/src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj +++ b/src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 False false diff --git a/src/Avalonia.Styling/Avalonia.Styling.csproj b/src/Avalonia.Styling/Avalonia.Styling.csproj index 5965645391..6bf37b522b 100644 --- a/src/Avalonia.Styling/Avalonia.Styling.csproj +++ b/src/Avalonia.Styling/Avalonia.Styling.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 false diff --git a/src/Avalonia.Styling/Styling/Style.cs b/src/Avalonia.Styling/Styling/Style.cs index c050ff0e75..3dfd9118af 100644 --- a/src/Avalonia.Styling/Styling/Style.cs +++ b/src/Avalonia.Styling/Styling/Style.cs @@ -13,10 +13,10 @@ namespace Avalonia.Styling /// public class Style : IStyle { - private static Dictionary> _applied = + private static Dictionary> _applied = new Dictionary>(); - private Dictionary _resources; + private StyleResources _resources; /// /// Initializes a new instance of the class. @@ -37,13 +37,13 @@ namespace Avalonia.Styling /// /// Gets or sets a dictionary of style resources. /// - public IDictionary Resources + public StyleResources Resources { get { if (_resources == null) { - _resources = new Dictionary(); + _resources = new StyleResources(); } return _resources; @@ -51,11 +51,16 @@ namespace Avalonia.Styling set { + var resources = Resources; - - foreach (var i in value) + if (!Equals(resources, value)) { - resources.Add(i); + foreach (var i in value) + { + resources[i.Key] = i.Value; + //resources.Add(i.Key, i.Value); + //(resources as IDictionary).Add(i); + } } } } @@ -69,7 +74,7 @@ namespace Avalonia.Styling /// Gets or sets the style's setters. /// [Content] - public IEnumerable Setters { get; set; } = new List(); + public IList Setters { get; set; } = new List(); /// /// Attaches the style to a control if the style's selector matches. diff --git a/src/Avalonia.Styling/Styling/StyleResources.cs b/src/Avalonia.Styling/Styling/StyleResources.cs new file mode 100644 index 0000000000..e447c6adfd --- /dev/null +++ b/src/Avalonia.Styling/Styling/StyleResources.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Avalonia.Styling +{ + /// + /// Holds resources for a . + /// + public class StyleResources : IDictionary, IDictionary + { + private Dictionary _inner = new Dictionary(); + + public object this[string key] + { + get { return _inner[key]; } + set { _inner[key] = value; } + } + + public int Count => _inner.Count; + + ICollection IDictionary.Keys => _inner.Keys; + + ICollection IDictionary.Values => _inner.Values; + + bool ICollection>.IsReadOnly => false; + + object IDictionary.this[object key] + { + get { return ((IDictionary)_inner)[key]; } + set { ((IDictionary)_inner)[key] = value; } + } + + ICollection IDictionary.Keys => _inner.Keys; + + ICollection IDictionary.Values => _inner.Values; + + bool ICollection.IsSynchronized => false; + + object ICollection.SyncRoot => ((IDictionary)_inner).SyncRoot; + + bool IDictionary.IsFixedSize => false; + + bool IDictionary.IsReadOnly => false; + + public void Add(string key, object value) => _inner.Add(key, value); + + public void Clear() => _inner.Clear(); + + public bool ContainsKey(string key) => _inner.ContainsKey(key); + + public bool Remove(string key) => _inner.Remove(key); + + public IEnumerator> GetEnumerator() => _inner.GetEnumerator(); + + public bool TryGetValue(string key, out object value) => _inner.TryGetValue(key, out value); + + bool ICollection>.Contains(KeyValuePair item) + { + return ((IDictionary)_inner).Contains(item); + } + + void ICollection>.Add(KeyValuePair item) + { + ((IDictionary)_inner).Add(item); + } + + void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) + { + ((IDictionary)_inner).CopyTo(array, arrayIndex); + } + + bool ICollection>.Remove(KeyValuePair item) + { + return ((IDictionary)_inner).Remove(item); + } + + void ICollection.CopyTo(Array array, int index) => ((IDictionary)_inner).CopyTo(array, index); + + IEnumerator IEnumerable.GetEnumerator() => _inner.GetEnumerator(); + + IDictionaryEnumerator IDictionary.GetEnumerator() => ((IDictionary)_inner).GetEnumerator(); + + void IDictionary.Add(object key, object value) => ((IDictionary)_inner).Add(key, value); + + bool IDictionary.Contains(object key) => ((IDictionary)_inner).Contains(key); + + void IDictionary.Remove(object key) => ((IDictionary)_inner).Remove(key); + } +} diff --git a/src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj b/src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj index be1d798e2d..4e980680d9 100644 --- a/src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj +++ b/src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 false diff --git a/src/Avalonia.Visuals/Avalonia.Visuals.csproj b/src/Avalonia.Visuals/Avalonia.Visuals.csproj index dd9a795937..127760d8ac 100644 --- a/src/Avalonia.Visuals/Avalonia.Visuals.csproj +++ b/src/Avalonia.Visuals/Avalonia.Visuals.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 false Avalonia diff --git a/src/Gtk/Avalonia.Cairo/Avalonia.Cairo.csproj b/src/Gtk/Avalonia.Cairo/Avalonia.Cairo.csproj index 9a59f9e054..d09fd2ddc6 100644 --- a/src/Gtk/Avalonia.Cairo/Avalonia.Cairo.csproj +++ b/src/Gtk/Avalonia.Cairo/Avalonia.Cairo.csproj @@ -9,7 +9,7 @@ Properties Avalonia.Cairo Avalonia.Cairo - v4.5 + v4.6.1 512 diff --git a/src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj b/src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj index 8aa57293f3..b51377f29c 100644 --- a/src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj +++ b/src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj @@ -7,7 +7,7 @@ Library Avalonia.Gtk Avalonia.Gtk - v4.5 + v4.6.1 diff --git a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj b/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj index 1874d92f4d..d292e99b30 100644 --- a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj +++ b/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj @@ -1,6 +1,6 @@  - netstandard1.1 + netstandard1.3 False false diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj index 036639ee54..dbf985fd79 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj +++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj @@ -1,273 +1,98 @@  - netstandard1.1 + netstandard1.3 False false false - + true full false bin\Debug\ - DEBUG;TRACE + TRACE;DEBUG;NETSTANDARD1_3;PCL;NETSTANDARD prompt 4 CS1591 - + pdbonly true bin\Release\ - TRACE + NETSTANDARD1_3;PCL;NETSTANDARD prompt 4 bin\Release\Avalonia.Markup.Xaml.XML CS1591 - - - Properties\SharedAssemblyInfo.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + Properties\SharedAssemblyInfo.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -279,11 +104,6 @@ - - - - - diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs index 7b3d0036ef..3142d954ff 100644 --- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs +++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs @@ -1,225 +1,11 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using System.Text; -using OmniXaml; -using Avalonia.Platform; -using Avalonia.Markup.Xaml.Context; -using Avalonia.Markup.Xaml.Styling; -using OmniXaml.ObjectAssembler; -using Avalonia.Controls; -using Avalonia.Markup.Xaml.Data; - -namespace Avalonia.Markup.Xaml +namespace Avalonia.Markup.Xaml { - /// - /// Loads XAML for a avalonia application. - /// - public class AvaloniaXamlLoader : XmlLoader + public class AvaloniaXamlLoader : AvaloniaXamlLoaderPortableXaml { - private static AvaloniaParserFactory s_parserFactory; - private static IInstanceLifeCycleListener s_lifeCycleListener = new AvaloniaLifeCycleListener(); - private static Stack s_uriStack = new Stack(); - - /// - /// Initializes a new instance of the class. - /// - public AvaloniaXamlLoader() - : this(GetParserFactory()) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The parser factory to use. - public AvaloniaXamlLoader(IParserFactory xamlParserFactory) - : base(xamlParserFactory) - { - } - - /// - /// Gets the URI of the XAML file currently being loaded. - /// - /// - /// TODO: Making this internal for now as I'm not sure that this is the correct - /// thing to do, but its needed by to get the URL of - /// the currently loading XAML file, as we can't use the OmniXAML parsing context - /// there. Maybe we need a way to inject OmniXAML context into the objects its - /// constructing? - /// - internal static Uri UriContext => s_uriStack.Count > 0 ? s_uriStack.Peek() : null; - - /// - /// Loads the XAML into a Avalonia component. - /// - /// The object to load the XAML into. - public static void Load(object obj) - { - Contract.Requires(obj != null); - - var loader = new AvaloniaXamlLoader(); - loader.Load(obj.GetType(), obj); - } - - /// - /// Loads the XAML for a type. - /// - /// The type. - /// - /// The optional instance into which the XAML should be loaded. - /// - /// The loaded object. - public object Load(Type type, object rootInstance = null) - { - Contract.Requires(type != null); - - // HACK: Currently Visual Studio is forcing us to change the extension of xaml files - // in certain situations, so we try to load .xaml and if that's not found we try .xaml. - // Ideally we'd be able to use .xaml everywhere - var assetLocator = AvaloniaLocator.Current.GetService(); - - if (assetLocator == null) - { - throw new InvalidOperationException( - "Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?"); - } - - foreach (var uri in GetUrisFor(type)) - { - if (assetLocator.Exists(uri)) - { - using (var stream = assetLocator.Open(uri)) - { - var initialize = rootInstance as ISupportInitialize; - initialize?.BeginInit(); - return Load(stream, rootInstance, uri); - } - } - } - - throw new FileNotFoundException("Unable to find view for " + type.FullName); - } - - /// - /// Loads XAML from a URI. - /// - /// The URI of the XAML file. - /// - /// A base URI to use if is relative. - /// - /// - /// The optional instance into which the XAML should be loaded. - /// - /// The loaded object. - public object Load(Uri uri, Uri baseUri = null, object rootInstance = null) - { - Contract.Requires(uri != null); - - var assetLocator = AvaloniaLocator.Current.GetService(); - - if (assetLocator == null) - { - throw new InvalidOperationException( - "Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?"); - } - - using (var stream = assetLocator.Open(uri, baseUri)) - { - return Load(stream, rootInstance, uri); - } - } - - /// - /// Loads XAML from a string. - /// - /// The string containing the XAML. - /// - /// The optional instance into which the XAML should be loaded. - /// - /// The loaded object. - public object Load(string xaml, object rootInstance = null) - { - Contract.Requires(xaml != null); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xaml))) - { - return Load(stream, rootInstance); - } - } - - /// - /// Loads XAML from a stream. - /// - /// The stream containing the XAML. - /// - /// The optional instance into which the XAML should be loaded. - /// - /// The URI of the XAML - /// The loaded object. - public object Load(Stream stream, object rootInstance = null, Uri uri = null) - { - try - { - if (uri != null) - { - s_uriStack.Push(uri); - } - - var result = base.Load(stream, new Settings - { - RootInstance = rootInstance, - InstanceLifeCycleListener = s_lifeCycleListener, - ParsingContext = new Dictionary - { - { "Uri", uri } - } - }); - - var topLevel = result as TopLevel; - - if (topLevel != null) - { - DelayedBinding.ApplyBindings(topLevel); - } - - return result; - } - finally - { - if (uri != null) - { - s_uriStack.Pop(); - } - } - } - - private static AvaloniaParserFactory GetParserFactory() - { - if (s_parserFactory == null) - { - s_parserFactory = new AvaloniaParserFactory(); - } - - return s_parserFactory; - } - - /// - /// Gets the URI for a type. - /// - /// The type. - /// The URI. - private static IEnumerable GetUrisFor(Type type) - { - var asm = type.GetTypeInfo().Assembly.GetName().Name; - var typeName = type.FullName; - yield return new Uri("resm:" + typeName + ".xaml?assembly=" + asm); - yield return new Uri("resm:" + typeName + ".paml?assembly=" + asm); + public static object Parse(string xaml) + => new AvaloniaXamlLoader().Load(xaml); - } + public static T Parse(string xaml) + => (T)Parse(xaml); } -} +} \ No newline at end of file diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs new file mode 100644 index 0000000000..c49797f2f8 --- /dev/null +++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs @@ -0,0 +1,215 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using Avalonia.Controls; +using Avalonia.Markup.Xaml.Data; +using Avalonia.Markup.Xaml.PortableXaml; +using Avalonia.Platform; +using Portable.Xaml; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Text; + +namespace Avalonia.Markup.Xaml +{ + /// + /// Loads XAML for a avalonia application. + /// + public class AvaloniaXamlLoaderPortableXaml + { + private readonly AvaloniaXamlSchemaContext _context = GetContext(); + + private static AvaloniaXamlSchemaContext GetContext() + { + var result = AvaloniaLocator.Current.GetService(); + + if (result == null) + { + result = AvaloniaXamlSchemaContext.Create(); + + AvaloniaLocator.CurrentMutable + .Bind() + .ToConstant(result); + } + + return result; + } + + /// + /// Initializes a new instance of the class. + /// + public AvaloniaXamlLoaderPortableXaml() + { + } + + /// + /// Loads the XAML into a Avalonia component. + /// + /// The object to load the XAML into. + public static void Load(object obj) + { + Contract.Requires(obj != null); + + var loader = new AvaloniaXamlLoader(); + loader.Load(obj.GetType(), obj); + } + + /// + /// Loads the XAML for a type. + /// + /// The type. + /// + /// The optional instance into which the XAML should be loaded. + /// + /// The loaded object. + public object Load(Type type, object rootInstance = null) + { + Contract.Requires(type != null); + + // HACK: Currently Visual Studio is forcing us to change the extension of xaml files + // in certain situations, so we try to load .xaml and if that's not found we try .xaml. + // Ideally we'd be able to use .xaml everywhere + var assetLocator = AvaloniaLocator.Current.GetService(); + + if (assetLocator == null) + { + throw new InvalidOperationException( + "Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?"); + } + + foreach (var uri in GetUrisFor(type)) + { + if (assetLocator.Exists(uri)) + { + using (var stream = assetLocator.Open(uri)) + { + var initialize = rootInstance as ISupportInitialize; + initialize?.BeginInit(); + try + { + return Load(stream, rootInstance, uri); + } + finally + { + initialize?.EndInit(); + } + } + } + } + + throw new FileNotFoundException("Unable to find view for " + type.FullName); + } + + /// + /// Loads XAML from a URI. + /// + /// The URI of the XAML file. + /// + /// A base URI to use if is relative. + /// + /// + /// The optional instance into which the XAML should be loaded. + /// + /// The loaded object. + public object Load(Uri uri, Uri baseUri = null, object rootInstance = null) + { + Contract.Requires(uri != null); + + var assetLocator = AvaloniaLocator.Current.GetService(); + + if (assetLocator == null) + { + throw new InvalidOperationException( + "Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?"); + } + + using (var stream = assetLocator.Open(uri, baseUri)) + { + return Load(stream, rootInstance, uri); + } + } + + /// + /// Loads XAML from a string. + /// + /// The string containing the XAML. + /// + /// The optional instance into which the XAML should be loaded. + /// + /// The loaded object. + public object Load(string xaml, object rootInstance = null) + { + Contract.Requires(xaml != null); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xaml))) + { + return Load(stream, rootInstance); + } + } + + /// + /// Loads XAML from a stream. + /// + /// The stream containing the XAML. + /// + /// The optional instance into which the XAML should be loaded. + /// + /// The URI of the XAML + /// The loaded object. + public object Load(Stream stream, object rootInstance = null, Uri uri = null) + { + var readerSettings = new XamlXmlReaderSettings() + { + BaseUri = uri, + LocalAssembly = rootInstance?.GetType().GetTypeInfo().Assembly + }; + + var reader = new XamlXmlReader(stream, _context, readerSettings); + + object result = LoadFromReader( + reader, + AvaloniaXamlContext.For(readerSettings, rootInstance)); + + var topLevel = result as TopLevel; + + if (topLevel != null) + { + DelayedBinding.ApplyBindings(topLevel); + } + + return result; + } + + internal static object LoadFromReader(XamlReader reader, AvaloniaXamlContext context = null) + { + var writer = AvaloniaXamlObjectWriter.Create( + reader.SchemaContext, + context); + + XamlServices.Transform(reader, writer); + + return writer.Result; + } + + internal static object LoadFromReader(XamlReader reader) + { + //return XamlServices.Load(reader); + return LoadFromReader(reader, null); + } + + /// + /// Gets the URI for a type. + /// + /// The type. + /// The URI. + private static IEnumerable GetUrisFor(Type type) + { + var asm = type.GetTypeInfo().Assembly.GetName().Name; + var typeName = type.FullName; + yield return new Uri("resm:" + typeName + ".xaml?assembly=" + asm); + yield return new Uri("resm:" + typeName + ".paml?assembly=" + asm); + } + } +} \ No newline at end of file diff --git a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaAttachableXamlMember.cs b/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaAttachableXamlMember.cs deleted file mode 100644 index be8aa8eb9f..0000000000 --- a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaAttachableXamlMember.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using Avalonia.Markup.Xaml.Data; -using OmniXaml; -using OmniXaml.Typing; -using System.Reflection; - -namespace Avalonia.Markup.Xaml.Context -{ - public class AvaloniaAttachableXamlMember : AttachableMember - { - public AvaloniaAttachableXamlMember(string name, - XamlType owner, - MethodInfo getter, - MethodInfo setter, - ITypeRepository xamlTypeRepository, - ITypeFeatureProvider featureProvider) - : base(name, getter, setter, xamlTypeRepository, featureProvider) - { - } - - public override string ToString() - { - return "Avalonia Attachable XAML Member " + base.ToString(); - } - - protected override IMemberValuePlugin LookupXamlMemberValueConnector() - { - return new AvaloniaMemberValuePlugin(this); - } - } -} \ No newline at end of file diff --git a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaContentPropertyProvider.cs b/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaContentPropertyProvider.cs deleted file mode 100644 index 164d948e10..0000000000 --- a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaContentPropertyProvider.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Glass; -using OmniXaml; -using OmniXaml.Builder; -using Avalonia.Metadata; - -namespace Avalonia.Markup.Xaml.Context -{ - public class AvaloniaContentPropertyProvider : IContentPropertyProvider - { - private readonly Dictionary _values = new Dictionary(); - - public string GetContentPropertyName(Type type) - { - string result; - - if (!_values.TryGetValue(type, out result)) - { - result = LookupContentProperty(type); - _values[type] = result; - } - - return result; - } - - private string LookupContentProperty(Type type) - { - var result = (from member in type.GetRuntimeProperties() - let att = member.GetCustomAttribute() - where att != null - select member).FirstOrDefault(); - - return result?.Name; - } - - void IAdd.Add(ContentPropertyDefinition item) - { - throw new NotImplementedException(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - throw new NotImplementedException(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - throw new NotImplementedException(); - } - } -} diff --git a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaLifeCycleListener.cs b/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaLifeCycleListener.cs deleted file mode 100644 index db5a19b484..0000000000 --- a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaLifeCycleListener.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using OmniXaml; - -namespace Avalonia.Markup.Xaml.Context -{ - public class AvaloniaLifeCycleListener : IInstanceLifeCycleListener - { - public void OnAfterProperties(object instance) - { - } - - public void OnAssociatedToParent(object instance) - { - } - - public void OnBegin(object instance) - { - var isi = instance as ISupportInitialize; - isi?.BeginInit(); - } - - public void OnEnd(object instance) - { - var isi = instance as ISupportInitialize; - isi?.EndInit(); - } - } -} diff --git a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaMemberValuePlugin.cs b/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaMemberValuePlugin.cs deleted file mode 100644 index 0494e9d1fe..0000000000 --- a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaMemberValuePlugin.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using OmniXaml.TypeConversion; -using OmniXaml.Typing; - -namespace Avalonia.Markup.Xaml.Context -{ - public class AvaloniaMemberValuePlugin : MemberValuePlugin - { - private readonly MutableMember _xamlMember; - - public AvaloniaMemberValuePlugin(MutableMember xamlMember) - : base(xamlMember) - { - _xamlMember = xamlMember; - } - - public override void SetValue(object instance, object value, IValueContext valueContext) - { - PropertyAccessor.SetValue(instance, _xamlMember, value, valueContext); - } - } -} diff --git a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaNamespaceRegistry.cs b/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaNamespaceRegistry.cs deleted file mode 100644 index b591654621..0000000000 --- a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaNamespaceRegistry.cs +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using OmniXaml.Builder; -using OmniXaml.Typing; -using Avalonia.Controls; -using Avalonia.Markup.Xaml.Templates; -using Avalonia.Media; -using Avalonia.Metadata; -using Avalonia.Platform; -using Avalonia.Styling; -using Glass.Core; - -namespace Avalonia.Markup.Xaml.Context -{ - public class AvaloniaNamespaceRegistry : INamespaceRegistry - { - private const string ClrNamespace = "clr-namespace:"; - private const string AvaloniaNs = "https://github.com/avaloniaui"; - - private static readonly IEnumerable ForcedAssemblies = new[] - { - typeof(AvaloniaObject).GetTypeInfo().Assembly, - typeof(Control).GetTypeInfo().Assembly, - typeof(Style).GetTypeInfo().Assembly, - typeof(DataTemplate).GetTypeInfo().Assembly, - typeof(SolidColorBrush).GetTypeInfo().Assembly, - typeof(IValueConverter).GetTypeInfo().Assembly, - }; - - private List _clrNamespaces = new List(); - private List _namespaces = new List(); - private Dictionary _prefixes = new Dictionary(); - private List _scanned = new List(); - - public AvaloniaNamespaceRegistry() - { - ScanAssemblies(ForcedAssemblies); - ScanNewAssemblies(); - RegisterPrefix(new PrefixRegistration(string.Empty, AvaloniaNs)); - } - - public IEnumerable RegisteredPrefixes => - _prefixes.Select(x => new PrefixRegistration(x.Key, x.Value)); - - public void AddNamespace(XamlNamespace xamlNamespace) - { - _namespaces.Add(xamlNamespace); - } - - public Namespace GetNamespace(string name) - { - Namespace result; - - if (!IsClrNamespace(name)) - { - ScanNewAssemblies(); - result = _namespaces.FirstOrDefault(x => x.Name == name); - - if (result == null) - { - result = _namespaces.FirstOrDefault(x => x.Name == name); - } - } - else - { - var nsAndAssembly = ParseClrNameSpace(name); - - result = _clrNamespaces.FirstOrDefault(x => - x.Name == nsAndAssembly.Item1 && - x.Assembly.GetName().Name == nsAndAssembly.Item2); - - if (result == null) - { - var clr = CreateClrNamespace(name); - _clrNamespaces.Add(clr); - result = clr; - } - } - - return result; - } - - public Namespace GetNamespaceByPrefix(string prefix) - { - string uri; - - if (_prefixes.TryGetValue(prefix, out uri)) - { - return GetNamespace(uri); - } - - return null; - } - - public void RegisterPrefix(PrefixRegistration prefixRegistration) - { - _prefixes[prefixRegistration.Prefix] = prefixRegistration.Ns; - } - - private static bool IsClrNamespace(string ns) - { - return ns.StartsWith(ClrNamespace); - } - - private static ClrNamespace CreateClrNamespace(string formattedClrString) - { - var nsAndAssembly = ParseClrNameSpace(formattedClrString); - var assembly = GetAssembly(nsAndAssembly.Item2); - - return new ClrNamespace(assembly, nsAndAssembly.Item1); - } - - private static Tuple ParseClrNameSpace(string clrNamespace) - { - var startOfNamespace = clrNamespace.IndexOf(":", StringComparison.Ordinal) + 1; - var endOfNamespace = clrNamespace.IndexOf(";", startOfNamespace, StringComparison.Ordinal); - - if (endOfNamespace < 0) - { - endOfNamespace = clrNamespace.Length - startOfNamespace; - } - - var ns = clrNamespace.Substring(startOfNamespace, endOfNamespace - startOfNamespace); - - var remainingPartStart = startOfNamespace + ns.Length + 1; - var remainingPartLenght = clrNamespace.Length - remainingPartStart; - var assemblyPart = clrNamespace.Substring(remainingPartStart, remainingPartLenght); - - return Tuple.Create(ns, assemblyPart.Dicotomize('=').Item2); - } - - private static Assembly GetAssembly(string assemblyName) - { - return Assembly.Load(new AssemblyName(assemblyName)); - } - - private void ScanAssemblies(IEnumerable assemblies) - { - foreach (var assembly in assemblies) - { - var namespaces = assembly.GetCustomAttributes() - .Select(x => new { x.XmlNamespace, x.ClrNamespace }) - .GroupBy(x => x.XmlNamespace); - - foreach (var nsa in namespaces) - { - var xamlNamespace = _namespaces.FirstOrDefault(x => x.Name == nsa.Key); - - if (xamlNamespace == null) - { - xamlNamespace = new XamlNamespace(nsa.Key); - _namespaces.Add(xamlNamespace); - } - - var clrNamespaces = nsa.Select(x => x.ClrNamespace); - xamlNamespace.Addresses.Add(new ConfiguredAssemblyWithNamespaces(assembly, clrNamespaces)); - } - - _scanned.Add(assembly); - } - } - - private void ScanNewAssemblies() - { - IEnumerable assemblies = AvaloniaLocator.Current - .GetService() - ?.GetLoadedAssemblies(); - - if (assemblies != null) - { - assemblies = assemblies.Except(_scanned); - ScanAssemblies(assemblies); - } - } - } -} diff --git a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaObjectAssembler.cs b/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaObjectAssembler.cs deleted file mode 100644 index 1f5d259fc3..0000000000 --- a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaObjectAssembler.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using OmniXaml; -using OmniXaml.ObjectAssembler; -using OmniXaml.ObjectAssembler.Commands; -using OmniXaml.TypeConversion; -using Avalonia.Markup.Xaml.Templates; -using System.Collections.Generic; -using System.Collections.ObjectModel; - -namespace Avalonia.Markup.Xaml.Context -{ - public class AvaloniaObjectAssembler : IObjectAssembler - { - private readonly TemplateHostingObjectAssembler objectAssembler; - private readonly ObjectAssembler assembler; - - public AvaloniaObjectAssembler( - IRuntimeTypeSource typeSource, - ITopDownValueContext topDownValueContext, - Settings settings = null) - { - var mapping = new DeferredLoaderMapping(); - mapping.Map