diff --git a/src/Avalonia.Controls/ContextMenu.cs b/src/Avalonia.Controls/ContextMenu.cs index 9bb4cc4816..c4df5c1815 100644 --- a/src/Avalonia.Controls/ContextMenu.cs +++ b/src/Avalonia.Controls/ContextMenu.cs @@ -279,6 +279,11 @@ namespace Avalonia.Controls ((ISetLogicalParent)_popup).SetParent(control); } + if (PlacementTarget is null && _popup.PlacementTarget != control) + { + _popup.PlacementTarget = control; + } + _popup.Child = this; IsOpen = true; _popup.IsOpen = true; diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index af6058d197..8840dcacef 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -88,7 +88,7 @@ namespace Avalonia.Win32 .Bind().ToConstant(s_instance) .Bind().ToConstant(s_instance) .Bind().ToConstant(new RenderLoop()) - .Bind().ToConstant(new DefaultRenderTimer(60)) + .Bind().ToConstant(new UiThreadRenderTimer(60)) .Bind().ToSingleton() .Bind().ToConstant(s_instance) .Bind().ToSingleton() diff --git a/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs b/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs index 7a2109e5a7..c179aef9ac 100644 --- a/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs @@ -1,5 +1,6 @@ using System; using Avalonia.Input; +using Avalonia.LogicalTree; using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml.MarkupExtensions; using Avalonia.Platform; @@ -132,6 +133,44 @@ namespace Avalonia.Controls.UnitTests popupImpl.Verify(x => x.Show(), Times.Exactly(2)); } } + + [Fact] + public void Context_Menu_Can_Be_Shared_Between_Controls_Even_After_A_Control_Is_Removed_From_Visual_Tree() + { + using (Application()) + { + var sut = new ContextMenu(); + var target1 = new Panel + { + ContextMenu = sut + }; + + var target2 = new Panel + { + ContextMenu = sut + }; + + var sp = new StackPanel { Children = { target1, target2 } }; + var window = new Window { Content = sp }; + + window.ApplyTemplate(); + window.Presenter.ApplyTemplate(); + + _mouse.Click(target1, MouseButton.Right); + + Assert.True(sut.IsOpen); + + _mouse.Click(target2, MouseButton.Left); + + Assert.False(sut.IsOpen); + + sp.Children.Remove(target1); + + _mouse.Click(target2, MouseButton.Right); + + Assert.True(sut.IsOpen); + } + } [Fact] public void Cancelling_Opening_Does_Not_Show_ContextMenu()