From 5cf6662f741cb0b9c1bc5cefc4ebe5f058aa8135 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 13 Jul 2020 17:25:15 +0200 Subject: [PATCH 01/17] Bind ListBox.SelectedItems again. Was removed accidentally. --- samples/ControlCatalog/Pages/ListBoxPage.xaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/samples/ControlCatalog/Pages/ListBoxPage.xaml b/samples/ControlCatalog/Pages/ListBoxPage.xaml index 47b4ce7151..f4d81418ac 100644 --- a/samples/ControlCatalog/Pages/ListBoxPage.xaml +++ b/samples/ControlCatalog/Pages/ListBoxPage.xaml @@ -10,7 +10,13 @@ HorizontalAlignment="Center" Spacing="16"> - + From 73a2637eed83f082be19a7d136aa5a0da164e1aa Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 14 Jul 2020 22:04:47 +0200 Subject: [PATCH 02/17] Added failing test for removing selected item with BeginInit. --- .../Primitives/SelectingItemsControlTests.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs index fe9c7b1261..9ef2750ff3 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs @@ -531,6 +531,7 @@ namespace Avalonia.Controls.UnitTests.Primitives }; target.ApplyTemplate(); + target.Presenter.ApplyTemplate(); target.SelectedIndex = 1; Assert.Equal(items[1], target.SelectedItem); @@ -549,6 +550,45 @@ namespace Avalonia.Controls.UnitTests.Primitives Assert.NotNull(receivedArgs); Assert.Empty(receivedArgs.AddedItems); Assert.Equal(new[] { removed }, receivedArgs.RemovedItems); + Assert.False(items.Single().IsSelected); + } + + [Fact] + public void Removing_Selected_Item_Should_Clear_Selection_With_BeginInit() + { + var items = new AvaloniaList + { + new Item(), + new Item(), + }; + + var target = new SelectingItemsControl(); + target.BeginInit(); + target.Items = items; + target.Template = Template(); + target.EndInit(); + + target.ApplyTemplate(); + target.Presenter.ApplyTemplate(); + target.SelectedIndex = 0; + + Assert.Equal(items[0], target.SelectedItem); + Assert.Equal(0, target.SelectedIndex); + + SelectionChangedEventArgs receivedArgs = null; + + target.SelectionChanged += (_, args) => receivedArgs = args; + + var removed = items[0]; + + items.RemoveAt(0); + + Assert.Null(target.SelectedItem); + Assert.Equal(-1, target.SelectedIndex); + Assert.NotNull(receivedArgs); + Assert.Empty(receivedArgs.AddedItems); + Assert.Equal(new[] { removed }, receivedArgs.RemovedItems); + Assert.False(items.Single().IsSelected); } [Fact] From 6555a51f5ae6986c17ad2da3f767e467712d612a Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 14 Jul 2020 22:37:23 +0200 Subject: [PATCH 03/17] Fix selection after deleting an item. `SelectionModel` needs to subscribe to `CollectionChanged` on the items before `ItemsControl` in order for the selection to be correct when we come to setting the selected state. Because `SelectionModel.Source` isn't subscribed during initialization in `ItemsChanged`, we also need to make sure we don't subscribe `ItemsControl` to the collection changes during initialization. Instead subscribe in `OnInitialized` (this requires a few tests to be rooted in order to be called). Fixes #4293 --- src/Avalonia.Controls/ItemsControl.cs | 11 +++++++++-- tests/Avalonia.Controls.UnitTests/CarouselTests.cs | 3 +++ .../Avalonia.Controls.UnitTests/ItemsControlTests.cs | 4 ++++ .../Primitives/SelectingItemsControlTests.cs | 4 ++++ .../Primitives/SelectingItemsControlTests_Multiple.cs | 4 ++++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index 6e0ad66699..da9f619932 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -70,7 +70,6 @@ namespace Avalonia.Controls public ItemsControl() { PseudoClasses.Add(":empty"); - SubscribeToItems(_items); } /// @@ -265,6 +264,11 @@ namespace Avalonia.Controls { } + protected override void OnInitialized() + { + SubscribeToItems(_items); + } + /// /// Handles directional navigation within the . /// @@ -330,7 +334,10 @@ namespace Avalonia.Controls Presenter.Items = newValue; } - SubscribeToItems(newValue); + if (IsInitialized) + { + SubscribeToItems(newValue); + } } /// diff --git a/tests/Avalonia.Controls.UnitTests/CarouselTests.cs b/tests/Avalonia.Controls.UnitTests/CarouselTests.cs index a292910fae..c6ca0fb2bf 100644 --- a/tests/Avalonia.Controls.UnitTests/CarouselTests.cs +++ b/tests/Avalonia.Controls.UnitTests/CarouselTests.cs @@ -4,6 +4,7 @@ using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.LogicalTree; +using Avalonia.UnitTests; using Avalonia.VisualTree; using Xunit; @@ -155,6 +156,7 @@ namespace Avalonia.Controls.UnitTests IsVirtualized = false }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); @@ -247,6 +249,7 @@ namespace Avalonia.Controls.UnitTests IsVirtualized = false }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); diff --git a/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs index 684486cbae..faaa3ed063 100644 --- a/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs @@ -131,6 +131,7 @@ namespace Avalonia.Controls.UnitTests var child = new Control(); var items = new AvaloniaList(child); + var root = new TestRoot(target); target.Template = GetTemplate(); target.Items = items; items.RemoveAt(0); @@ -283,6 +284,7 @@ namespace Avalonia.Controls.UnitTests var items = new AvaloniaList { "Foo" }; var called = false; + var root = new TestRoot(target); target.Template = GetTemplate(); target.Items = items; target.ApplyTemplate(); @@ -303,6 +305,7 @@ namespace Avalonia.Controls.UnitTests var items = new AvaloniaList { "Foo", "Bar" }; var called = false; + var root = new TestRoot(target); target.Template = GetTemplate(); target.Items = items; target.ApplyTemplate(); @@ -376,6 +379,7 @@ namespace Avalonia.Controls.UnitTests Items = new[] { 1, 2, 3 }, }; + var root = new TestRoot(target); Assert.DoesNotContain(":empty", target.Classes); } diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs index 9ef2750ff3..e43e855ae0 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs @@ -170,6 +170,8 @@ namespace Avalonia.Controls.UnitTests.Primitives SelectionMode = SelectionMode.Single | SelectionMode.AlwaysSelected }; + var root = new TestRoot(listBox); + listBox.BeginInit(); listBox.SelectedIndex = 1; @@ -480,6 +482,7 @@ namespace Avalonia.Controls.UnitTests.Primitives Template = Template(), }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); items.Add(new Item { IsSelected = true }); @@ -919,6 +922,7 @@ namespace Avalonia.Controls.UnitTests.Primitives Items = items, }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs index dcf25beb50..e9ec8d114f 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs @@ -1014,6 +1014,7 @@ namespace Avalonia.Controls.UnitTests.Primitives SelectionMode = SelectionMode.Multiple, }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); @@ -1043,6 +1044,7 @@ namespace Avalonia.Controls.UnitTests.Primitives SelectionMode = SelectionMode.Multiple, }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); @@ -1076,6 +1078,7 @@ namespace Avalonia.Controls.UnitTests.Primitives SelectionMode = SelectionMode.Multiple, }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); @@ -1199,6 +1202,7 @@ namespace Avalonia.Controls.UnitTests.Primitives Template = Template(), }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); items.Add(new ItemContainer { IsSelected = true }); From de87609de1859e1c28fad65af4e233ff5a489bca Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 15 Jul 2020 13:32:06 -0300 Subject: [PATCH 04/17] add failing unit test. --- .../ToolTipTests.cs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/Avalonia.Controls.UnitTests/ToolTipTests.cs b/tests/Avalonia.Controls.UnitTests/ToolTipTests.cs index 34b37e7635..9d7bc6af74 100644 --- a/tests/Avalonia.Controls.UnitTests/ToolTipTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ToolTipTests.cs @@ -30,6 +30,40 @@ namespace Avalonia.Controls.UnitTests Assert.False(ToolTip.GetIsOpen(control)); } + + [Fact] + public void Should_Close_When_Control_Detaches() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var window = new Window(); + + var panel = new Panel(); + + var target = new Decorator() + { + [ToolTip.TipProperty] = "Tip", + [ToolTip.ShowDelayProperty] = 0 + }; + + panel.Children.Add(target); + + window.Content = panel; + + window.ApplyTemplate(); + window.Presenter.ApplyTemplate(); + + Assert.True((target as IVisual).IsAttachedToVisualTree); + + _mouseHelper.Enter(target); + + Assert.True(ToolTip.GetIsOpen(target)); + + panel.Children.Remove(target); + + Assert.False(ToolTip.GetIsOpen(target)); + } + } [Fact] public void Should_Open_On_Pointer_Enter() From a542d8753de026bd786c914b571c2a680a2ce77c Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 15 Jul 2020 13:33:20 -0300 Subject: [PATCH 05/17] ensure tooltips are closed when its parent detaches from visual tree. --- src/Avalonia.Controls/ToolTipService.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Avalonia.Controls/ToolTipService.cs b/src/Avalonia.Controls/ToolTipService.cs index d90729e8a5..569697304f 100644 --- a/src/Avalonia.Controls/ToolTipService.cs +++ b/src/Avalonia.Controls/ToolTipService.cs @@ -28,14 +28,22 @@ namespace Avalonia.Controls { control.PointerEnter -= ControlPointerEnter; control.PointerLeave -= ControlPointerLeave; + control.DetachedFromVisualTree -= ControlDetaching; } if (e.NewValue != null) { control.PointerEnter += ControlPointerEnter; control.PointerLeave += ControlPointerLeave; + control.DetachedFromVisualTree += ControlDetaching; } } + + private void ControlDetaching(object sender, VisualTreeAttachmentEventArgs e) + { + var control = (Control)sender; + Close(control); + } /// /// Called when the pointer enters a control with an attached tooltip. From 6e106fb9e7cdd810f7924e0bac04308cd6a803bc Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 15 Jul 2020 22:09:40 +0200 Subject: [PATCH 06/17] [Win32] only steal input focus if it's currently held by Popup's parent's child --- .../Interop/UnmanagedMethods.cs | 12 ++++++++ src/Windows/Avalonia.Win32/PopupImpl.cs | 29 ++++++++++++------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs index 392ca31282..b7c68c4b95 100644 --- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs @@ -1060,9 +1060,21 @@ namespace Avalonia.Win32.Interop [DllImport("user32.dll")] public static extern bool SetFocus(IntPtr hWnd); [DllImport("user32.dll")] + public static extern IntPtr GetFocus(); + [DllImport("user32.dll")] public static extern bool SetParent(IntPtr hWnd, IntPtr hWndNewParent); [DllImport("user32.dll")] public static extern IntPtr GetParent(IntPtr hWnd); + + public enum GetAncestorFlags + { + GA_PARENT = 1, + GA_ROOT = 2, + GA_ROOTOWNER = 3 + } + + [DllImport("user32.dll")] + public static extern IntPtr GetAncestor(IntPtr hwnd, GetAncestorFlags gaFlags); [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommand nCmdShow); diff --git a/src/Windows/Avalonia.Win32/PopupImpl.cs b/src/Windows/Avalonia.Win32/PopupImpl.cs index cd25b32ed9..525e5e0d52 100644 --- a/src/Windows/Avalonia.Win32/PopupImpl.cs +++ b/src/Windows/Avalonia.Win32/PopupImpl.cs @@ -7,6 +7,7 @@ namespace Avalonia.Win32 { class PopupImpl : WindowImpl, IPopupImpl { + private readonly IWindowBaseImpl _parent; private bool _dropShadowHint = true; private Size? _maxAutoSize; @@ -19,18 +20,25 @@ namespace Avalonia.Win32 public override void Show() { UnmanagedMethods.ShowWindow(Handle.Handle, UnmanagedMethods.ShowWindowCommand.ShowNoActivate); - var parent = UnmanagedMethods.GetParent(Handle.Handle); - if (parent != IntPtr.Zero) - { - IntPtr nextParent = parent; - while (nextParent != IntPtr.Zero) - { - parent = nextParent; - nextParent = UnmanagedMethods.GetParent(parent); - } - UnmanagedMethods.SetFocus(parent); + // We need to steal focus if it's held by a child window of our toplevel window + var parent = _parent; + while(parent != null) + { + if(parent is PopupImpl pi) + parent = pi._parent; + else + break; } + + if(parent == null) + return; + + var focusOwner = UnmanagedMethods.GetFocus(); + if (focusOwner != IntPtr.Zero && + UnmanagedMethods.GetAncestor(focusOwner, UnmanagedMethods.GetAncestorFlags.GA_ROOT) + == parent.Handle.Handle) + UnmanagedMethods.SetFocus(parent.Handle.Handle); } protected override bool ShouldTakeFocusOnClick => false; @@ -118,6 +126,7 @@ namespace Avalonia.Win32 private PopupImpl(IWindowBaseImpl parent, bool dummy) : base() { + _parent = parent; PopupPositioner = new ManagedPopupPositioner(new ManagedPopupPositionerPopupImplHelper(parent, MoveResize)); } From 1c099b6e8ca96b60ab8d7a2de4f81c3f79e547c2 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 15 Jul 2020 19:15:59 -0300 Subject: [PATCH 07/17] add failing unit tests for cases. --- .../RelativePanelTests.cs | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/Avalonia.Controls.UnitTests/RelativePanelTests.cs b/tests/Avalonia.Controls.UnitTests/RelativePanelTests.cs index 7b1f6d07b7..6e171a58e7 100644 --- a/tests/Avalonia.Controls.UnitTests/RelativePanelTests.cs +++ b/tests/Avalonia.Controls.UnitTests/RelativePanelTests.cs @@ -82,5 +82,55 @@ namespace Avalonia.Controls.UnitTests Assert.Equal(new Rect(0, 0, 20, 20), target.Children[0].Bounds); Assert.Equal(new Rect(0, 20, 20, 20), target.Children[1].Bounds); } + + [Fact] + public void LeftOf_Measures_Correctly() + { + var rect1 = new Rectangle { Height = 20, Width = 20 }; + var rect2 = new Rectangle { Height = 20, Width = 20 }; + + var target = new RelativePanel + { + VerticalAlignment = Layout.VerticalAlignment.Center, + HorizontalAlignment = Layout.HorizontalAlignment.Center, + Children = + { + rect1, rect2 + } + }; + + RelativePanel.SetLeftOf(rect2, rect1); + target.Measure(new Size(400, 400)); + target.Arrange(new Rect(target.DesiredSize)); + + Assert.Equal(new Size(20, 20), target.Bounds.Size); + Assert.Equal(new Rect(0, 0, 20, 20), target.Children[0].Bounds); + Assert.Equal(new Rect(-20, 0, 20, 20), target.Children[1].Bounds); + } + + [Fact] + public void Above_Measures_Correctly() + { + var rect1 = new Rectangle { Height = 20, Width = 20 }; + var rect2 = new Rectangle { Height = 20, Width = 20 }; + + var target = new RelativePanel + { + VerticalAlignment = Layout.VerticalAlignment.Center, + HorizontalAlignment = Layout.HorizontalAlignment.Center, + Children = + { + rect1, rect2 + } + }; + + RelativePanel.SetAbove(rect2, rect1); + target.Measure(new Size(400, 400)); + target.Arrange(new Rect(target.DesiredSize)); + + Assert.Equal(new Size(20, 20), target.Bounds.Size); + Assert.Equal(new Rect(0, 0, 20, 20), target.Children[0].Bounds); + Assert.Equal(new Rect(0, -20, 20, 20), target.Children[1].Bounds); + } } } From 3449784b09d529b950dd3ccd1560a08c5e9703de Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 15 Jul 2020 19:16:53 -0300 Subject: [PATCH 08/17] add fixes for relative panel --- src/Avalonia.Controls/RelativePanel.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Avalonia.Controls/RelativePanel.cs b/src/Avalonia.Controls/RelativePanel.cs index a3ad30db76..38b5d9807c 100644 --- a/src/Avalonia.Controls/RelativePanel.cs +++ b/src/Avalonia.Controls/RelativePanel.cs @@ -54,7 +54,7 @@ namespace Avalonia.Controls } _childGraph.Measure(availableSize); - _childGraph.Reset(); + _childGraph.Reset(false); var boundingSize = _childGraph.GetBoundingSize(Width.IsNaN(), Height.IsNaN()); _childGraph.Reset(); _childGraph.Measure(boundingSize); @@ -119,17 +119,22 @@ namespace Avalonia.Controls public void Arrange(Size arrangeSize) => Element.Arrange(new Rect(Left, Top, Math.Max(arrangeSize.Width - Left - Right, 0), Math.Max(arrangeSize.Height - Top - Bottom, 0))); - public void Reset() + public void Reset(bool clearPos) { - Left = double.NaN; - Top = double.NaN; - Right = double.NaN; - Bottom = double.NaN; + if (clearPos) + { + Left = double.NaN; + Top = double.NaN; + Right = double.NaN; + Bottom = double.NaN; + } + Measured = false; } public Size GetBoundingSize() { + if (Left < 0 || Top < 0) return default; if (Measured) return BoundingSize; @@ -209,7 +214,7 @@ namespace Avalonia.Controls _nodeDic.Clear(); } - public void Reset() => _nodeDic.Values.Do(node => node.Reset()); + public void Reset(bool clearPos = true) => _nodeDic.Values.Do(node => node.Reset(clearPos)); public GraphNode? AddLink(GraphNode from, Layoutable? to) { From d7d63e26c4bc46278815ec56aad5795ed2fdb0d7 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 15 Jul 2020 19:17:42 -0300 Subject: [PATCH 09/17] remove chinese comments. --- src/Avalonia.Controls/RelativePanel.cs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/Avalonia.Controls/RelativePanel.cs b/src/Avalonia.Controls/RelativePanel.cs index 38b5d9807c..27f13a3f57 100644 --- a/src/Avalonia.Controls/RelativePanel.cs +++ b/src/Avalonia.Controls/RelativePanel.cs @@ -260,28 +260,21 @@ namespace Avalonia.Controls foreach (var node in nodes) { - /* - * 该节点无任何依赖,所以从这里开始计算元素位置。 - * 因为无任何依赖,所以忽略同级元素 - */ if (!node.Measured && !node.OutgoingNodes.Any()) { MeasureChild(node); continue; } - - // 判断依赖元素是否全部排列完毕 + if (node.OutgoingNodes.All(item => item.Measured)) { MeasureChild(node); continue; } - - // 判断是否有循环 + if (!set.Add(node.Element)) throw new Exception("RelativePanel error: Circular dependency detected. Layout could not complete."); - - // 没有循环,且有依赖,则继续往下 + Measure(node.OutgoingNodes, set); if (!node.Measured) From 281e31a65ce7b65e7d6215b87eb302b5a69ed30b Mon Sep 17 00:00:00 2001 From: Maksym Katsydan Date: Wed, 15 Jul 2020 18:40:08 -0400 Subject: [PATCH 10/17] Add missing fluent resources for default styles on ControlCatalog --- samples/ControlCatalog/App.xaml.cs | 24 ++++++++++++++++++++---- samples/ControlCatalog/MainView.xaml | 1 - 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/samples/ControlCatalog/App.xaml.cs b/samples/ControlCatalog/App.xaml.cs index 0baa6589c6..3f1ec289d1 100644 --- a/samples/ControlCatalog/App.xaml.cs +++ b/samples/ControlCatalog/App.xaml.cs @@ -29,11 +29,19 @@ namespace ControlCatalog { new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) { - Source = new Uri("resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default") + Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/Base.xaml") }, new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) { - Source = new Uri("resm:Avalonia.Themes.Default.DefaultTheme.xaml?assembly=Avalonia.Themes.Default") + Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseLight.xaml") + }, + new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) + { + Source = new Uri("avares://Avalonia.Themes.Default/Accents/BaseLight.xaml") + }, + new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) + { + Source = new Uri("avares://Avalonia.Themes.Default/DefaultTheme.xaml") }, }; @@ -41,11 +49,19 @@ namespace ControlCatalog { new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) { - Source = new Uri("resm:Avalonia.Themes.Default.Accents.BaseDark.xaml?assembly=Avalonia.Themes.Default") + Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/Base.xaml") + }, + new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) + { + Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseDark.xaml") + }, + new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) + { + Source = new Uri("avares://Avalonia.Themes.Default/Accents/BaseDark.xaml") }, new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) { - Source = new Uri("resm:Avalonia.Themes.Default.DefaultTheme.xaml?assembly=Avalonia.Themes.Default") + Source = new Uri("avares://Avalonia.Themes.Default/DefaultTheme.xaml") }, }; diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml index fa4fd7dd07..af95e3c356 100644 --- a/samples/ControlCatalog/MainView.xaml +++ b/samples/ControlCatalog/MainView.xaml @@ -2,7 +2,6 @@ xmlns:pages="clr-namespace:ControlCatalog.Pages" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="ControlCatalog.MainView" - Background="Black" Foreground="{DynamicResource ThemeForegroundBrush}" FontSize="{DynamicResource FontSizeNormal}"> From 7ad6171d13fadf1d9052135cd91eafe474047b8b Mon Sep 17 00:00:00 2001 From: Maksym Katsydan Date: Wed, 15 Jul 2020 19:09:47 -0400 Subject: [PATCH 11/17] RenderDemo: use FluentLight intead of DefaultLight --- samples/RenderDemo/App.xaml | 5 +- samples/RenderDemo/SideBar.xaml | 125 ++++++++++++++++---------------- 2 files changed, 66 insertions(+), 64 deletions(-) diff --git a/samples/RenderDemo/App.xaml b/samples/RenderDemo/App.xaml index ccc3f54cc0..61e4d2385b 100644 --- a/samples/RenderDemo/App.xaml +++ b/samples/RenderDemo/App.xaml @@ -3,8 +3,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="RenderDemo.App"> - - + - \ No newline at end of file + diff --git a/samples/RenderDemo/SideBar.xaml b/samples/RenderDemo/SideBar.xaml index 07fdb91a16..fd23067f61 100644 --- a/samples/RenderDemo/SideBar.xaml +++ b/samples/RenderDemo/SideBar.xaml @@ -1,65 +1,68 @@ - + - - - - - + + + + + + From 41831066c202a24331bde2acbe7740caa953e868 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 16 Jul 2020 10:30:41 +0200 Subject: [PATCH 12/17] Revert "Fix selection after deleting an item." --- samples/ControlCatalog/Pages/ListBoxPage.xaml | 8 +--- src/Avalonia.Controls/ItemsControl.cs | 11 +---- .../CarouselTests.cs | 3 -- .../ItemsControlTests.cs | 4 -- .../Primitives/SelectingItemsControlTests.cs | 44 ------------------- .../SelectingItemsControlTests_Multiple.cs | 4 -- 6 files changed, 3 insertions(+), 71 deletions(-) diff --git a/samples/ControlCatalog/Pages/ListBoxPage.xaml b/samples/ControlCatalog/Pages/ListBoxPage.xaml index f4d81418ac..47b4ce7151 100644 --- a/samples/ControlCatalog/Pages/ListBoxPage.xaml +++ b/samples/ControlCatalog/Pages/ListBoxPage.xaml @@ -10,13 +10,7 @@ HorizontalAlignment="Center" Spacing="16"> - + diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index da9f619932..6e0ad66699 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -70,6 +70,7 @@ namespace Avalonia.Controls public ItemsControl() { PseudoClasses.Add(":empty"); + SubscribeToItems(_items); } /// @@ -264,11 +265,6 @@ namespace Avalonia.Controls { } - protected override void OnInitialized() - { - SubscribeToItems(_items); - } - /// /// Handles directional navigation within the . /// @@ -334,10 +330,7 @@ namespace Avalonia.Controls Presenter.Items = newValue; } - if (IsInitialized) - { - SubscribeToItems(newValue); - } + SubscribeToItems(newValue); } /// diff --git a/tests/Avalonia.Controls.UnitTests/CarouselTests.cs b/tests/Avalonia.Controls.UnitTests/CarouselTests.cs index c6ca0fb2bf..a292910fae 100644 --- a/tests/Avalonia.Controls.UnitTests/CarouselTests.cs +++ b/tests/Avalonia.Controls.UnitTests/CarouselTests.cs @@ -4,7 +4,6 @@ using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.LogicalTree; -using Avalonia.UnitTests; using Avalonia.VisualTree; using Xunit; @@ -156,7 +155,6 @@ namespace Avalonia.Controls.UnitTests IsVirtualized = false }; - var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); @@ -249,7 +247,6 @@ namespace Avalonia.Controls.UnitTests IsVirtualized = false }; - var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); diff --git a/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs index faaa3ed063..684486cbae 100644 --- a/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs @@ -131,7 +131,6 @@ namespace Avalonia.Controls.UnitTests var child = new Control(); var items = new AvaloniaList(child); - var root = new TestRoot(target); target.Template = GetTemplate(); target.Items = items; items.RemoveAt(0); @@ -284,7 +283,6 @@ namespace Avalonia.Controls.UnitTests var items = new AvaloniaList { "Foo" }; var called = false; - var root = new TestRoot(target); target.Template = GetTemplate(); target.Items = items; target.ApplyTemplate(); @@ -305,7 +303,6 @@ namespace Avalonia.Controls.UnitTests var items = new AvaloniaList { "Foo", "Bar" }; var called = false; - var root = new TestRoot(target); target.Template = GetTemplate(); target.Items = items; target.ApplyTemplate(); @@ -379,7 +376,6 @@ namespace Avalonia.Controls.UnitTests Items = new[] { 1, 2, 3 }, }; - var root = new TestRoot(target); Assert.DoesNotContain(":empty", target.Classes); } diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs index e43e855ae0..fe9c7b1261 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs @@ -170,8 +170,6 @@ namespace Avalonia.Controls.UnitTests.Primitives SelectionMode = SelectionMode.Single | SelectionMode.AlwaysSelected }; - var root = new TestRoot(listBox); - listBox.BeginInit(); listBox.SelectedIndex = 1; @@ -482,7 +480,6 @@ namespace Avalonia.Controls.UnitTests.Primitives Template = Template(), }; - var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); items.Add(new Item { IsSelected = true }); @@ -534,7 +531,6 @@ namespace Avalonia.Controls.UnitTests.Primitives }; target.ApplyTemplate(); - target.Presenter.ApplyTemplate(); target.SelectedIndex = 1; Assert.Equal(items[1], target.SelectedItem); @@ -553,45 +549,6 @@ namespace Avalonia.Controls.UnitTests.Primitives Assert.NotNull(receivedArgs); Assert.Empty(receivedArgs.AddedItems); Assert.Equal(new[] { removed }, receivedArgs.RemovedItems); - Assert.False(items.Single().IsSelected); - } - - [Fact] - public void Removing_Selected_Item_Should_Clear_Selection_With_BeginInit() - { - var items = new AvaloniaList - { - new Item(), - new Item(), - }; - - var target = new SelectingItemsControl(); - target.BeginInit(); - target.Items = items; - target.Template = Template(); - target.EndInit(); - - target.ApplyTemplate(); - target.Presenter.ApplyTemplate(); - target.SelectedIndex = 0; - - Assert.Equal(items[0], target.SelectedItem); - Assert.Equal(0, target.SelectedIndex); - - SelectionChangedEventArgs receivedArgs = null; - - target.SelectionChanged += (_, args) => receivedArgs = args; - - var removed = items[0]; - - items.RemoveAt(0); - - Assert.Null(target.SelectedItem); - Assert.Equal(-1, target.SelectedIndex); - Assert.NotNull(receivedArgs); - Assert.Empty(receivedArgs.AddedItems); - Assert.Equal(new[] { removed }, receivedArgs.RemovedItems); - Assert.False(items.Single().IsSelected); } [Fact] @@ -922,7 +879,6 @@ namespace Avalonia.Controls.UnitTests.Primitives Items = items, }; - var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs index e9ec8d114f..dcf25beb50 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs @@ -1014,7 +1014,6 @@ namespace Avalonia.Controls.UnitTests.Primitives SelectionMode = SelectionMode.Multiple, }; - var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); @@ -1044,7 +1043,6 @@ namespace Avalonia.Controls.UnitTests.Primitives SelectionMode = SelectionMode.Multiple, }; - var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); @@ -1078,7 +1076,6 @@ namespace Avalonia.Controls.UnitTests.Primitives SelectionMode = SelectionMode.Multiple, }; - var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); @@ -1202,7 +1199,6 @@ namespace Avalonia.Controls.UnitTests.Primitives Template = Template(), }; - var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); items.Add(new ItemContainer { IsSelected = true }); From 856118f21c6ca84a93bd293f0dba14208084a0a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro?= Date: Fri, 17 Jul 2020 06:57:54 +0100 Subject: [PATCH 13/17] Use TextBox text alignment and wrapping in watermark. --- src/Avalonia.Themes.Default/TextBox.xaml | 2 ++ src/Avalonia.Themes.Fluent/TextBox.xaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Avalonia.Themes.Default/TextBox.xaml b/src/Avalonia.Themes.Default/TextBox.xaml index 4fb3653e89..6a746dda30 100644 --- a/src/Avalonia.Themes.Default/TextBox.xaml +++ b/src/Avalonia.Themes.Default/TextBox.xaml @@ -40,6 +40,8 @@ Date: Fri, 17 Jul 2020 16:33:31 +0300 Subject: [PATCH 14/17] Extracted runtime XAML loader to a separate package --- .gitmodules | 2 +- Avalonia.sln | 27 ++++++ Directory.Build.props | 1 + .../Avalonia.Build.Tasks.csproj | 10 +-- .../DesignWindowLoader.cs | 7 +- .../Remote/FileWatcherTransport.cs | 10 ++- .../HtmlTransport/webapp/package-lock.json | 28 +++++-- .../Remote/RemoteDesignerEntryPoint.cs | 8 +- .../Avalonia.Markup.Xaml.Loader.csproj | 14 ++++ .../AvaloniaRuntimeXamlLoader.cs | 42 ++++++++++ .../AvaloniaXamlIlRuntimeCompiler.cs | 0 .../AvaloniaXamlIlCompiler.cs | 0 .../AvaloniaXamlIlCompilerConfiguration.cs | 0 .../AvaloniaXamlIlLanguage.cs | 0 .../Transformers/AddNameScopeRegistration.cs | 0 .../AvaloniaBindingExtensionTransformer.cs | 0 .../AvaloniaXamlIlAvaloniaPropertyResolver.cs | 0 .../AvaloniaXamlIlBindingPathParser.cs | 0 .../AvaloniaXamlIlBindingPathTransformer.cs | 0 ...iaXamlIlCompiledBindingsMetadataRemover.cs | 0 ...IlConstructorServiceProviderTransformer.cs | 0 ...olTemplateTargetTypeMetadataTransformer.cs | 0 ...valoniaXamlIlDataContextTypeTransformer.cs | 0 ...aloniaXamlIlDesignPropertiesTransformer.cs | 0 .../AvaloniaXamlIlMetadataRemover.cs | 0 .../AvaloniaXamlIlPropertyPathTransformer.cs | 0 ...lIlResolveByNameMarkupExtensionReplacer.cs | 0 ...valoniaXamlIlRootObjectScopeTransformer.cs | 0 .../AvaloniaXamlIlSelectorTransformer.cs | 0 .../AvaloniaXamlIlSetterTransformer.cs | 0 ...mlIlTransformInstanceAttachedProperties.cs | 0 ...ransformSyntheticCompiledBindingMembers.cs | 0 ...amlIlTransitionsTypeMetadataTransformer.cs | 0 .../AvaloniaXamlIlWellKnownTypes.cs | 0 .../IgnoredDirectivesTransformer.cs | 0 .../Transformers/XNameTransformer.cs | 0 .../XamlIlAvaloniaPropertyHelper.cs | 0 .../XamlIlBindingPathHelper.cs | 0 .../XamlIlClrPropertyInfoHelper.cs | 0 ...amlIlPropertyInfoAccessorFactoryEmitter.cs | 0 .../IncludeXamlIlSre.props | 12 +++ .../xamlil.github | 0 .../Avalonia.Markup.Xaml.csproj | 36 -------- .../AvaloniaXamlLoader.cs | 52 +----------- .../MarkupExtensions/ResourceInclude.cs | 3 +- .../Styling/StyleInclude.cs | 3 +- .../Avalonia.Designer.HostApp.csproj | 6 +- .../DesignXamlLoader.cs | 16 ++++ .../Avalonia.Designer.HostApp/Program.cs | 4 +- .../Avalonia.Controls.UnitTests.csproj | 1 + .../ContextMenuTests.cs | 6 +- .../TabControlTests.cs | 4 +- .../Avalonia.Markup.Xaml.UnitTests.csproj | 1 + .../Converters/ConverterTests.cs | 2 +- .../Converters/MultiValueConverterTests.cs | 3 +- .../Converters/NullableConverterTests.cs | 3 +- .../PointsListTypeConverterTests.cs | 3 +- .../Converters/ValueConverterTests.cs | 3 +- .../Data/BindingTests.cs | 9 +- .../Data/BindingTests_Method.cs | 9 +- .../Data/BindingTests_TemplatedParent.cs | 3 +- .../MarkupExtensions/BindingExtensionTests.cs | 9 +- .../CompiledBindingExtensionTests.cs | 69 +++++---------- .../DynamicResourceExtensionTests.cs | 78 ++++++----------- .../MarkupExtensions/ResourceIncludeTests.cs | 6 +- .../StaticResourceExtensionTests.cs | 57 +++++-------- .../StyleIncludeTests.cs | 3 +- .../StyleTests.cs | 3 +- .../Xaml/BasicTests.cs | 83 +++++++++---------- .../Xaml/BindingTests.cs | 47 ++++------- .../Xaml/BindingTests_RelativeSource.cs | 42 ++++------ .../Xaml/ControlBindingTests.cs | 9 +- .../Xaml/DataTemplateTests.cs | 9 +- .../Xaml/EventTests.cs | 9 +- .../Xaml/ResourceDictionaryTests.cs | 6 +- .../Xaml/StyleTests.cs | 44 ++++------ .../Xaml/TreeDataTemplateTests.cs | 3 +- .../Xaml/XamlIlTests.cs | 32 +++---- .../Avalonia.ReactiveUI.UnitTests.csproj | 3 +- .../AvaloniaActivationForViewFetcherTest.cs | 6 +- .../Avalonia.Skia.UnitTests.csproj | 1 + tests/Avalonia.UnitTests/TestServices.cs | 3 +- 82 files changed, 386 insertions(+), 464 deletions(-) create mode 100644 src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj create mode 100644 src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaRuntimeXamlLoader.cs rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/AvaloniaXamlIlRuntimeCompiler.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/AvaloniaXamlIlCompiler.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/AvaloniaXamlIlCompilerConfiguration.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/AvaloniaXamlIlLanguage.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AddNameScopeRegistration.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaBindingExtensionTransformer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlAvaloniaPropertyResolver.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathParser.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlCompiledBindingsMetadataRemover.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlConstructorServiceProviderTransformer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlDesignPropertiesTransformer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlMetadataRemover.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlPropertyPathTransformer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlRootObjectScopeTransformer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlSelectorTransformer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlTransformInstanceAttachedProperties.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlTransformSyntheticCompiledBindingMembers.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlTransitionsTypeMetadataTransformer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/IgnoredDirectivesTransformer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/Transformers/XNameTransformer.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/XamlIlBindingPathHelper.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/XamlIlClrPropertyInfoHelper.cs (100%) rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs (100%) create mode 100644 src/Markup/Avalonia.Markup.Xaml.Loader/IncludeXamlIlSre.props rename src/Markup/{Avalonia.Markup.Xaml/XamlIl => Avalonia.Markup.Xaml.Loader}/xamlil.github (100%) create mode 100644 src/tools/Avalonia.Designer.HostApp/DesignXamlLoader.cs diff --git a/.gitmodules b/.gitmodules index 9dbc50ef61..2d11fdfa9e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,5 +2,5 @@ path = nukebuild/Numerge url = https://github.com/kekekeks/Numerge.git [submodule "src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github"] - path = src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github + path = src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github url = https://github.com/kekekeks/XamlX.git diff --git a/Avalonia.sln b/Avalonia.sln index 4ab647a25e..4954260e12 100644 --- a/Avalonia.sln +++ b/Avalonia.sln @@ -211,6 +211,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Headless", "src\Av EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Headless.Vnc", "src\Avalonia.Headless.Vnc\Avalonia.Headless.Vnc.csproj", "{B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Markup.Xaml.Loader", "src\Markup\Avalonia.Markup.Xaml.Loader\Avalonia.Markup.Xaml.Loader.csproj", "{909A8CBD-7D0E-42FD-B841-022AD8925820}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\Shared\RenderHelpers\RenderHelpers.projitems*{3c4c0cb4-0c0f-4450-a37b-148c84ff905f}*SharedItemsImports = 13 @@ -1998,6 +2000,30 @@ Global {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|iPhone.Build.0 = Release|Any CPU {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.AppStore|iPhone.Build.0 = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Debug|Any CPU.Build.0 = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Debug|iPhone.Build.0 = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|Any CPU.ActiveCfg = Release|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|Any CPU.Build.0 = Release|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhone.ActiveCfg = Release|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhone.Build.0 = Release|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhoneSimulator.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2056,6 +2082,7 @@ Global {AF915D5C-AB00-4EA0-B5E6-001F4AE84E68} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {351337F5-D66F-461B-A957-4EF60BDB4BA6} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {3C84E04B-36CF-4D0D-B965-C26DD649D1F3} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9} + {909A8CBD-7D0E-42FD-B841-022AD8925820} = {8B6A8209-894F-4BA1-B880-965FD453982C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A} diff --git a/Directory.Build.props b/Directory.Build.props index 1f26df9bbc..b41f8c488e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,6 @@ $(MSBuildThisFileDirectory)build-intermediate/nuget + $(MSBuildThisFileDirectory)\src\tools\Avalonia.Designer.HostApp\bin\$(Configuration)\netcoreapp2.0\Avalonia.Designer.HostApp.dll diff --git a/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj b/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj index 7117fd51a2..490364c0d8 100644 --- a/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj +++ b/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj @@ -17,14 +17,14 @@ Shared/AvaloniaResourceXamlInfo.cs - + XamlIlExtensions/%(RecursiveDir)%(FileName)%(Extension) - + XamlIl/%(RecursiveDir)%(FileName)%(Extension) - + XamlIl.Cecil/%(RecursiveDir)%(FileName)%(Extension) @@ -57,8 +57,8 @@ Markup/%(RecursiveDir)%(FileName)%(Extension) - - + + diff --git a/src/Avalonia.DesignerSupport/DesignWindowLoader.cs b/src/Avalonia.DesignerSupport/DesignWindowLoader.cs index f3bb0edce5..d7c6cc3693 100644 --- a/src/Avalonia.DesignerSupport/DesignWindowLoader.cs +++ b/src/Avalonia.DesignerSupport/DesignWindowLoader.cs @@ -12,13 +12,18 @@ namespace Avalonia.DesignerSupport { public class DesignWindowLoader { + public interface IDesignXamlLoader + { + object Load(MemoryStream stream, Assembly localAsm, object o, Uri baseUri); + } + public static Window LoadDesignerWindow(string xaml, string assemblyPath, string xamlFileProjectPath) { Window window; Control control; using (PlatformManager.DesignerMode()) { - var loader = new AvaloniaXamlLoader() {IsDesignMode = true}; + var loader = AvaloniaLocator.Current.GetService(); var stream = new MemoryStream(Encoding.UTF8.GetBytes(xaml)); diff --git a/src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs b/src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs index 0cb71dd217..0448a5c05d 100644 --- a/src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs +++ b/src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs @@ -9,12 +9,14 @@ namespace Avalonia.DesignerSupport.Remote { class FileWatcherTransport : IAvaloniaRemoteTransportConnection, ITransportWithEnforcedMethod { + private readonly string _appPath; private string _path; private string _lastContents; private bool _disposed; - public FileWatcherTransport(Uri file) + public FileWatcherTransport(Uri file, string appPath) { + _appPath = appPath; _path = file.LocalPath; } @@ -73,7 +75,11 @@ namespace Avalonia.DesignerSupport.Remote { Console.WriteLine("Triggering XAML update"); _lastContents = data; - _onMessage?.Invoke(this, new UpdateXamlMessage { Xaml = data }); + _onMessage?.Invoke(this, new UpdateXamlMessage + { + Xaml = data, + AssemblyPath = _appPath + }); } await Task.Delay(100); diff --git a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/package-lock.json b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/package-lock.json index 87536c670f..028027a974 100644 --- a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/package-lock.json +++ b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/package-lock.json @@ -3564,12 +3564,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3584,17 +3586,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3711,7 +3716,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3723,6 +3729,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3737,6 +3744,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3744,12 +3752,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3768,6 +3778,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3848,7 +3859,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3860,6 +3872,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3981,6 +3994,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", diff --git a/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs b/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs index e61fe82c41..3e26ded22d 100644 --- a/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs +++ b/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs @@ -112,8 +112,9 @@ namespace Avalonia.DesignerSupport.Remote return rv; } - static IAvaloniaRemoteTransportConnection CreateTransport(Uri transport) + static IAvaloniaRemoteTransportConnection CreateTransport(CommandLineArgs args) { + var transport = args.Transport; if (transport.Scheme == "tcp-bson") { return new BsonTcpTransport().Connect(IPAddress.Parse(transport.Host), transport.Port).Result; @@ -121,7 +122,7 @@ namespace Avalonia.DesignerSupport.Remote if (transport.Scheme == "file") { - return new FileWatcherTransport(transport); + return new FileWatcherTransport(transport, args.AppPath); } PrintUsage(); return null; @@ -160,7 +161,7 @@ namespace Avalonia.DesignerSupport.Remote public static void Main(string[] cmdline) { var args = ParseCommandLineArgs(cmdline); - var transport = CreateTransport(args.Transport); + var transport = CreateTransport(args); if (transport is ITransportWithEnforcedMethod enforcedMethod) args.Method = enforcedMethod.PreviewerMethod; var asm = Assembly.LoadFile(System.IO.Path.GetFullPath(args.AppPath)); @@ -234,6 +235,7 @@ namespace Avalonia.DesignerSupport.Remote } catch (Exception e) { + Console.Error.WriteLine(e.ToString()); s_transport.Send(new UpdateXamlResultMessage { Error = e.ToString(), diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj b/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj new file mode 100644 index 0000000000..768545eb7e --- /dev/null +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj @@ -0,0 +1,14 @@ + + + + netstandard2.0 + true + + + + + + + + + diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaRuntimeXamlLoader.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaRuntimeXamlLoader.cs new file mode 100644 index 0000000000..4569970d01 --- /dev/null +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaRuntimeXamlLoader.cs @@ -0,0 +1,42 @@ +using System; +using System.IO; +using System.Reflection; +using System.Text; +using Avalonia.Markup.Xaml.XamlIl; +// ReSharper disable CheckNamespace + +namespace Avalonia.Markup.Xaml +{ + public static class AvaloniaRuntimeXamlLoader + { + /// + /// Loads XAML from a string. + /// + /// The string containing the XAML. + /// Default assembly for clr-namespace: + /// + /// The optional instance into which the XAML should be loaded. + /// + /// The loaded object. + public static object Load(string xaml, Assembly localAssembly = null, object rootInstance = null, Uri uri = null, bool designMode = false) + { + Contract.Requires(xaml != null); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xaml))) + { + return Load(stream, localAssembly, rootInstance, uri, designMode); + } + } + + public static object Load(Stream stream, Assembly localAssembly, object rootInstance = null, Uri uri = null, + bool designMode = false) + => AvaloniaXamlIlRuntimeCompiler.Load(stream, localAssembly, rootInstance, uri, designMode); + + public static object Parse(string xaml, Assembly localAssembly = null) + => Load(xaml, localAssembly); + + public static T Parse(string xaml, Assembly localAssembly = null) + => (T)Parse(xaml, localAssembly); + + } +} diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/AvaloniaXamlIlRuntimeCompiler.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/AvaloniaXamlIlRuntimeCompiler.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompilerConfiguration.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompilerConfiguration.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompilerConfiguration.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompilerConfiguration.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlLanguage.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlLanguage.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AddNameScopeRegistration.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AddNameScopeRegistration.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AddNameScopeRegistration.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AddNameScopeRegistration.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaBindingExtensionTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaBindingExtensionTransformer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaBindingExtensionTransformer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaBindingExtensionTransformer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlAvaloniaPropertyResolver.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlAvaloniaPropertyResolver.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlAvaloniaPropertyResolver.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlAvaloniaPropertyResolver.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathParser.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathParser.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathParser.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathParser.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlCompiledBindingsMetadataRemover.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlCompiledBindingsMetadataRemover.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlCompiledBindingsMetadataRemover.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlCompiledBindingsMetadataRemover.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlConstructorServiceProviderTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlConstructorServiceProviderTransformer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlConstructorServiceProviderTransformer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlConstructorServiceProviderTransformer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlDesignPropertiesTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDesignPropertiesTransformer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlDesignPropertiesTransformer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDesignPropertiesTransformer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlMetadataRemover.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlMetadataRemover.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlMetadataRemover.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlMetadataRemover.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlPropertyPathTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlPropertyPathTransformer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlPropertyPathTransformer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlPropertyPathTransformer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlRootObjectScopeTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlRootObjectScopeTransformer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlRootObjectScopeTransformer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlRootObjectScopeTransformer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlSelectorTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSelectorTransformer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlSelectorTransformer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSelectorTransformer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlTransformInstanceAttachedProperties.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlTransformInstanceAttachedProperties.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlTransformInstanceAttachedProperties.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlTransformInstanceAttachedProperties.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlTransformSyntheticCompiledBindingMembers.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlTransformSyntheticCompiledBindingMembers.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlTransformSyntheticCompiledBindingMembers.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlTransformSyntheticCompiledBindingMembers.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlTransitionsTypeMetadataTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlTransitionsTypeMetadataTransformer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlTransitionsTypeMetadataTransformer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlTransitionsTypeMetadataTransformer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/IgnoredDirectivesTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/IgnoredDirectivesTransformer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/IgnoredDirectivesTransformer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/IgnoredDirectivesTransformer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/XNameTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/XNameTransformer.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/XNameTransformer.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/XNameTransformer.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlBindingPathHelper.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlBindingPathHelper.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlClrPropertyInfoHelper.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlClrPropertyInfoHelper.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlClrPropertyInfoHelper.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlClrPropertyInfoHelper.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs rename to src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/IncludeXamlIlSre.props b/src/Markup/Avalonia.Markup.Xaml.Loader/IncludeXamlIlSre.props new file mode 100644 index 0000000000..c902fa956a --- /dev/null +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/IncludeXamlIlSre.props @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github b/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github similarity index 100% rename from src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github rename to src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj index 3979312ce0..24428253aa 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj +++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj @@ -45,44 +45,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -96,8 +62,6 @@ - - diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs index 5c21037924..0e81ca2be8 100644 --- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs +++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs @@ -10,10 +10,8 @@ namespace Avalonia.Markup.Xaml /// /// Loads XAML for a avalonia application. /// - public class AvaloniaXamlLoader + public static class AvaloniaXamlLoader { - public bool IsDesignMode { get; set; } - /// /// Loads the XAML into a Avalonia component. /// @@ -32,7 +30,7 @@ namespace Avalonia.Markup.Xaml /// A base URI to use if is relative. /// /// The loaded object. - public object Load(Uri uri, Uri baseUri = null) + public static object Load(Uri uri, Uri baseUri = null) { Contract.Requires(uri != null); @@ -56,51 +54,9 @@ namespace Avalonia.Markup.Xaml return compiledResult; } - - var asset = assetLocator.OpenAndGetAssembly(uri, baseUri); - using (var stream = asset.stream) - { - var absoluteUri = uri.IsAbsoluteUri ? uri : new Uri(baseUri, uri); - return Load(stream, asset.assembly, null, absoluteUri); - } + throw new XamlLoadException( + $"No precompiled XAML found for {uri} (baseUri: {baseUri}), make sure to specify x:Class and include your XAML file as AvaloniaResource"); } - /// - /// Loads XAML from a string. - /// - /// The string containing the XAML. - /// Default assembly for clr-namespace: - /// - /// The optional instance into which the XAML should be loaded. - /// - /// The loaded object. - public object Load(string xaml, Assembly localAssembly = null, object rootInstance = null) - { - Contract.Requires(xaml != null); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xaml))) - { - return Load(stream, localAssembly, rootInstance); - } - } - - /// - /// Loads XAML from a stream. - /// - /// The stream containing the XAML. - /// Default assembly for clr-namespace - /// - /// The optional instance into which the XAML should be loaded. - /// - /// The URI of the XAML - /// The loaded object. - public object Load(Stream stream, Assembly localAssembly, object rootInstance = null, Uri uri = null) - => AvaloniaXamlIlRuntimeCompiler.Load(stream, localAssembly, rootInstance, uri, IsDesignMode); - - public static object Parse(string xaml, Assembly localAssembly = null) - => new AvaloniaXamlLoader().Load(xaml, localAssembly); - - public static T Parse(string xaml, Assembly localAssembly = null) - => (T)Parse(xaml, localAssembly); } } diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs index 0cedf4f364..b6137aa89f 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs @@ -25,8 +25,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions if (_loaded == null) { _isLoading = true; - var loader = new AvaloniaXamlLoader(); - _loaded = (IResourceDictionary)loader.Load(Source, _baseUri); + _loaded = (IResourceDictionary)AvaloniaXamlLoader.Load(Source, _baseUri); _isLoading = false; } diff --git a/src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs b/src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs index ea9042f779..607b552c28 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs @@ -51,8 +51,7 @@ namespace Avalonia.Markup.Xaml.Styling if (_loaded == null) { _isLoading = true; - var loader = new AvaloniaXamlLoader(); - var loaded = (IStyle)loader.Load(Source, _baseUri); + var loaded = (IStyle)AvaloniaXamlLoader.Load(Source, _baseUri); _loaded = new[] { loaded }; _isLoading = false; } diff --git a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj index 1c7077870a..aa40f1d75a 100644 --- a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj +++ b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj @@ -18,6 +18,10 @@ - + + + + + diff --git a/src/tools/Avalonia.Designer.HostApp/DesignXamlLoader.cs b/src/tools/Avalonia.Designer.HostApp/DesignXamlLoader.cs new file mode 100644 index 0000000000..b873027765 --- /dev/null +++ b/src/tools/Avalonia.Designer.HostApp/DesignXamlLoader.cs @@ -0,0 +1,16 @@ +using System; +using System.IO; +using System.Reflection; +using Avalonia.DesignerSupport; +using Avalonia.Markup.Xaml.XamlIl; + +namespace Avalonia.Designer.HostApp +{ + class DesignXamlLoader : DesignWindowLoader.IDesignXamlLoader + { + public object Load(MemoryStream stream, Assembly localAsm, object o, Uri baseUri) + { + return AvaloniaXamlIlRuntimeCompiler.Load(stream, localAsm, o, baseUri, true); + } + } +} diff --git a/src/tools/Avalonia.Designer.HostApp/Program.cs b/src/tools/Avalonia.Designer.HostApp/Program.cs index 3163e1fbc3..7469f946a4 100644 --- a/src/tools/Avalonia.Designer.HostApp/Program.cs +++ b/src/tools/Avalonia.Designer.HostApp/Program.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Reflection; +using Avalonia.DesignerSupport; namespace Avalonia.Designer.HostApp { @@ -40,8 +41,9 @@ namespace Avalonia.Designer.HostApp public static void Main(string[] args) #endif { + AvaloniaLocator.CurrentMutable.Bind() + .ToConstant(new DesignXamlLoader()); Avalonia.DesignerSupport.Remote.RemoteDesignerEntryPoint.Main(args); } - } } diff --git a/tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj b/tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj index 2ca93dcf56..19c4454d3d 100644 --- a/tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj +++ b/tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj @@ -13,6 +13,7 @@ + diff --git a/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs b/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs index 9a81d19bb9..cf8f7c266a 100644 --- a/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs @@ -191,8 +191,7 @@ namespace Avalonia.Controls.UnitTests "; - var loader = new AvaloniaXamlLoader(); - var window = (Window)loader.Load(xaml); + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var target1 = window.Find("target1"); var target2 = window.Find("target2"); var mouse = new MouseTestHelper(); @@ -235,8 +234,7 @@ namespace Avalonia.Controls.UnitTests "; - var loader = new AvaloniaXamlLoader(); - var window = (Window)loader.Load(xaml); + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var target1 = window.Find("target1"); var target2 = window.Find("target2"); var mouse = new MouseTestHelper(); diff --git a/tests/Avalonia.Controls.UnitTests/TabControlTests.cs b/tests/Avalonia.Controls.UnitTests/TabControlTests.cs index db9211ac3c..fd52aeb9af 100644 --- a/tests/Avalonia.Controls.UnitTests/TabControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TabControlTests.cs @@ -8,6 +8,7 @@ using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Controls.Utils; using Avalonia.LogicalTree; +using Avalonia.Markup.Xaml; using Avalonia.Styling; using Avalonia.UnitTests; using Xunit; @@ -338,8 +339,7 @@ namespace Avalonia.Controls.UnitTests xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.Xaml;assembly=Avalonia.Markup.Xaml.UnitTests'> "; - var loader = new Markup.Xaml.AvaloniaXamlLoader(); - var window = (Window)loader.Load(xaml); + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var tabControl = window.FindControl("tabs"); tabControl.DataContext = new { Tabs = new List() }; diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj b/tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj index e8c4daa7bc..ad3592294d 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj @@ -11,6 +11,7 @@ + diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Converters/ConverterTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Converters/ConverterTests.cs index b424003ed6..c9420f1696 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Converters/ConverterTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Converters/ConverterTests.cs @@ -9,7 +9,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Converters public void Bug_2228_Relative_Uris_Should_Be_Correctly_Parsed() { var testClass = typeof(TestClassWithUri); - var parsed = AvaloniaXamlLoader.Parse( + var parsed = AvaloniaRuntimeXamlLoader.Parse( $"<{testClass.Name} xmlns='clr-namespace:{testClass.Namespace}' Uri='/test'/>", testClass.Assembly); Assert.False(parsed.Uri.IsAbsoluteUri); diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Converters/MultiValueConverterTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Converters/MultiValueConverterTests.cs index a77723afe1..466ae1bf7c 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Converters/MultiValueConverterTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Converters/MultiValueConverterTests.cs @@ -29,8 +29,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Converters "; - var loader = new AvaloniaXamlLoader(); - var window = (Window)loader.Load(xaml); + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var textBlock = window.FindControl("textBlock"); window.ApplyTemplate(); diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Converters/NullableConverterTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Converters/NullableConverterTests.cs index cdd40ed80f..eb8851c80b 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Converters/NullableConverterTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Converters/NullableConverterTests.cs @@ -22,8 +22,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Converters xmlns='clr-namespace:Avalonia.Markup.Xaml.UnitTests.Converters' Thickness = '5' Orientation='Vertical' >"; - var loader = new AvaloniaXamlLoader(); - var data = (ClassWithNullableProperties)loader.Load(xaml, typeof(ClassWithNullableProperties).Assembly); + var data = (ClassWithNullableProperties)AvaloniaRuntimeXamlLoader.Load(xaml, typeof(ClassWithNullableProperties).Assembly); Assert.Equal(new Thickness(5), data.Thickness); Assert.Equal(Orientation.Vertical, data.Orientation); } diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Converters/PointsListTypeConverterTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Converters/PointsListTypeConverterTests.cs index b060905f38..3b729e9cd8 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Converters/PointsListTypeConverterTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Converters/PointsListTypeConverterTests.cs @@ -31,8 +31,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Converters public void Should_Parse_Points_in_Xaml(string input) { var xaml = $""; - var loader = new AvaloniaXamlLoader(); - var polygon = (Polygon)loader.Load(xaml); + var polygon = (Polygon)AvaloniaRuntimeXamlLoader.Load(xaml); var points = polygon.Points; diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Converters/ValueConverterTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Converters/ValueConverterTests.cs index 5e698117c3..4d5983e276 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Converters/ValueConverterTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Converters/ValueConverterTests.cs @@ -21,8 +21,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Converters xmlns:c='clr-namespace:Avalonia.Markup.Xaml.UnitTests.Converters;assembly=Avalonia.Markup.Xaml.UnitTests'> "; - var loader = new AvaloniaXamlLoader(); - var window = (Window)loader.Load(xaml); + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var textBlock = window.FindControl("textBlock"); window.ApplyTemplate(); diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests.cs index 6730e3134d..afc4a36fea 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests.cs @@ -24,8 +24,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'> "; - var loader = new AvaloniaXamlLoader(); - var window = (Window)loader.Load(xaml); + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var textBlock = window.FindControl("textBlock"); window.DataContext = "foo"; @@ -45,8 +44,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'> "; - var loader = new AvaloniaXamlLoader(); - var window = (Window)loader.Load(xaml); + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var textBlock = window.FindControl("textBlock"); window.ApplyTemplate(); @@ -86,8 +84,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data "; - var loader = new AvaloniaXamlLoader(); - var window = (Window)loader.Load(xaml); + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var textBox = window.FindControl("textBox"); window.ApplyTemplate(); diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_Method.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_Method.cs index b2b4c4da1a..a7a004bd49 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_Method.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_Method.cs @@ -20,8 +20,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.Xaml;assembly=Avalonia.Markup.Xaml.UnitTests'> "; - var loader = new AvaloniaXamlLoader(); - var window = (Window)loader.Load(xaml); + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var button = window.FindControl "; - var control = AvaloniaXamlLoader.Parse(xaml); + var control = AvaloniaRuntimeXamlLoader.Parse(xaml); var button = control.FindControl "; - var control = AvaloniaXamlLoader.Parse(xaml); + var control = AvaloniaRuntimeXamlLoader.Parse(xaml); var button = control.FindControl public static class AvaloniaXamlLoader { + public interface IRuntimeXamlLoader + { + object Load(Stream stream, Assembly localAsm, object o, Uri baseUri, bool designMode); + } + /// /// Loads the XAML into a Avalonia component. /// @@ -53,7 +58,19 @@ namespace Avalonia.Markup.Xaml if (compiledResult != null) return compiledResult; } - + + // This is intended for unit-tests only + var runtimeLoader = AvaloniaLocator.Current.GetService(); + if (runtimeLoader != null) + { + var asset = assetLocator.OpenAndGetAssembly(uri, baseUri); + using (var stream = asset.stream) + { + var absoluteUri = uri.IsAbsoluteUri ? uri : new Uri(baseUri, uri); + return runtimeLoader.Load(stream, asset.assembly, null, absoluteUri, false); + } + } + throw new XamlLoadException( $"No precompiled XAML found for {uri} (baseUri: {baseUri}), make sure to specify x:Class and include your XAML file as AvaloniaResource"); } diff --git a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj index aa40f1d75a..51d18e55d1 100644 --- a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj +++ b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj @@ -20,8 +20,8 @@ - - + + diff --git a/src/tools/Avalonia.Designer.HostApp/DesignXamlLoader.cs b/src/tools/Avalonia.Designer.HostApp/DesignXamlLoader.cs index b873027765..7af29a56a1 100644 --- a/src/tools/Avalonia.Designer.HostApp/DesignXamlLoader.cs +++ b/src/tools/Avalonia.Designer.HostApp/DesignXamlLoader.cs @@ -1,16 +1,16 @@ using System; using System.IO; using System.Reflection; -using Avalonia.DesignerSupport; +using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml.XamlIl; namespace Avalonia.Designer.HostApp { - class DesignXamlLoader : DesignWindowLoader.IDesignXamlLoader + class DesignXamlLoader : AvaloniaXamlLoader.IRuntimeXamlLoader { - public object Load(MemoryStream stream, Assembly localAsm, object o, Uri baseUri) + public object Load(Stream stream, Assembly localAsm, object o, Uri baseUri, bool designMode) { - return AvaloniaXamlIlRuntimeCompiler.Load(stream, localAsm, o, baseUri, true); + return AvaloniaXamlIlRuntimeCompiler.Load(stream, localAsm, o, baseUri, designMode); } } } diff --git a/src/tools/Avalonia.Designer.HostApp/Program.cs b/src/tools/Avalonia.Designer.HostApp/Program.cs index 7469f946a4..4472dac4e3 100644 --- a/src/tools/Avalonia.Designer.HostApp/Program.cs +++ b/src/tools/Avalonia.Designer.HostApp/Program.cs @@ -2,6 +2,7 @@ using System.IO; using System.Reflection; using Avalonia.DesignerSupport; +using Avalonia.Markup.Xaml; namespace Avalonia.Designer.HostApp { @@ -41,7 +42,7 @@ namespace Avalonia.Designer.HostApp public static void Main(string[] args) #endif { - AvaloniaLocator.CurrentMutable.Bind() + AvaloniaLocator.CurrentMutable.Bind() .ToConstant(new DesignXamlLoader()); Avalonia.DesignerSupport.Remote.RemoteDesignerEntryPoint.Main(args); } diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/ResourceIncludeTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/ResourceIncludeTests.cs index d9505ba3ed..54e89ae37e 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/ResourceIncludeTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/ResourceIncludeTests.cs @@ -7,7 +7,7 @@ using Xunit; namespace Avalonia.Markup.Xaml.UnitTests.MakrupExtensions { - public class ResourceIncludeTests + public class ResourceIncludeTests : XamlTestBase { public class StaticResourceExtensionTests : XamlTestBase { diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/XamlTestBase.cs b/tests/Avalonia.Markup.Xaml.UnitTests/XamlTestBase.cs index 5172b2e830..2bc82d1353 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/XamlTestBase.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/XamlTestBase.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.IO; +using System.Reflection; using System.Text; using Avalonia.Data; @@ -11,6 +13,15 @@ namespace Avalonia.Markup.Xaml.UnitTests { // Ensure necessary assemblies are loaded. var _ = typeof(TemplateBinding); + if (AvaloniaLocator.Current.GetService() == null) + AvaloniaLocator.CurrentMutable.Bind() + .ToConstant(new TestXamlLoaderShim()); + } + + class TestXamlLoaderShim : AvaloniaXamlLoader.IRuntimeXamlLoader + { + public object Load(Stream stream, Assembly localAsm, object o, Uri baseUri, bool designMode) + => AvaloniaRuntimeXamlLoader.Load(stream, localAsm, o, baseUri, designMode); } } } From 835aed07a5155d111d9bf9d9fd1e005784016f11 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Fri, 17 Jul 2020 17:13:24 +0300 Subject: [PATCH 17/17] Whoopsie --- src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs b/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs index 3e26ded22d..764fc7b332 100644 --- a/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs +++ b/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs @@ -235,7 +235,6 @@ namespace Avalonia.DesignerSupport.Remote } catch (Exception e) { - Console.Error.WriteLine(e.ToString()); s_transport.Send(new UpdateXamlResultMessage { Error = e.ToString(),