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)
{
var templatedParent = Parent.TemplatedParent;
if (control.TemplatedParent == null)
if (control != 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)
{
foreach (IControl child in control.GetVisualChildren())
if (!(control is IPresenter) && control.TemplatedParent == templatedParent)
{
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.
using System;
using System.Linq;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.LogicalTree;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
using Xunit;
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()
{
var result = new PopupRoot
{
Template = new FuncControlTemplate<PopupRoot>(_ =>
Template = new FuncControlTemplate<PopupRoot>(parent =>
new ContentPresenter
{
Name = "PART_ContentPresenter",
[!ContentPresenter.ContentProperty] = parent[!PopupRoot.ContentProperty],
}),
};
@ -105,5 +126,33 @@ namespace Avalonia.Controls.UnitTests.Primitives
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