Browse Source

Merge pull request #1295 from AvaloniaUI/fixes/1247-data-validation-popup-crash

Handle `PopupRoot.Content` being set to null.
pull/1281/merge
Jeremy Koritzinsky 9 years ago
committed by GitHub
parent
commit
b61356c3da
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 23
      src/Avalonia.Controls/Primitives/PopupRoot.cs
  2. 51
      tests/Avalonia.Controls.UnitTests/Primitives/PopupRootTests.cs

23
src/Avalonia.Controls/Primitives/PopupRoot.cs

@ -90,20 +90,23 @@ namespace Avalonia.Controls.Primitives
private void SetTemplatedParentAndApplyChildTemplates(IControl control) private void SetTemplatedParentAndApplyChildTemplates(IControl control)
{ {
var templatedParent = Parent.TemplatedParent; if (control != null)
if (control.TemplatedParent == null)
{ {
control.SetValue(TemplatedParentProperty, templatedParent); var templatedParent = Parent.TemplatedParent;
}
if (control.TemplatedParent == null)
{
control.SetValue(TemplatedParentProperty, templatedParent);
}
control.ApplyTemplate(); control.ApplyTemplate();
if (!(control is IPresenter) && control.TemplatedParent == templatedParent) if (!(control is IPresenter) && control.TemplatedParent == templatedParent)
{
foreach (IControl child in control.GetVisualChildren())
{ {
SetTemplatedParentAndApplyChildTemplates(child); foreach (IControl child in control.GetVisualChildren())
{
SetTemplatedParentAndApplyChildTemplates(child);
}
} }
} }
} }

51
tests/Avalonia.Controls.UnitTests/Primitives/PopupRootTests.cs

@ -2,11 +2,13 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information. // Licensed under the MIT license. See licence.md file in the project root for full license information.
using System; using System;
using System.Linq;
using Avalonia.Controls.Presenters; using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
using Avalonia.UnitTests; using Avalonia.UnitTests;
using Avalonia.VisualTree;
using Xunit; using Xunit;
namespace Avalonia.Controls.UnitTests.Primitives namespace Avalonia.Controls.UnitTests.Primitives
@ -90,14 +92,33 @@ namespace Avalonia.Controls.UnitTests.Primitives
} }
} }
[Fact]
public void Clearing_Content_Of_Popup_In_ControlTemplate_Doesnt_Crash()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var target = new TemplatedControlWithPopup
{
PopupContent = new Canvas(),
};
var root = new TestRoot { Child = target };
target.ApplyTemplate();
target.Popup.Open();
target.PopupContent = null;
}
}
private PopupRoot CreateTarget() private PopupRoot CreateTarget()
{ {
var result = new PopupRoot var result = new PopupRoot
{ {
Template = new FuncControlTemplate<PopupRoot>(_ => Template = new FuncControlTemplate<PopupRoot>(parent =>
new ContentPresenter new ContentPresenter
{ {
Name = "PART_ContentPresenter", Name = "PART_ContentPresenter",
[!ContentPresenter.ContentProperty] = parent[!PopupRoot.ContentProperty],
}), }),
}; };
@ -105,5 +126,33 @@ namespace Avalonia.Controls.UnitTests.Primitives
return result; return result;
} }
private class TemplatedControlWithPopup : TemplatedControl
{
public static readonly AvaloniaProperty<Control> PopupContentProperty =
AvaloniaProperty.Register<TemplatedControlWithPopup, Control>(nameof(PopupContent));
public TemplatedControlWithPopup()
{
Template = new FuncControlTemplate<TemplatedControlWithPopup>(parent =>
new Popup
{
[!Popup.ChildProperty] = parent[!TemplatedControlWithPopup.PopupContentProperty],
});
}
public Popup Popup { get; private set; }
public Control PopupContent
{
get => GetValue(PopupContentProperty);
set => SetValue(PopupContentProperty, value);
}
protected override void OnTemplateApplied(TemplateAppliedEventArgs e)
{
Popup = (Popup)this.GetVisualChildren().Single();
}
}
} }
} }

Loading…
Cancel
Save