Browse Source

Clear TemplatedParent of ex-template children.

This prevents them still being bound to their ex-TemplatedParent. Fixes
#435.
pull/447/head
Steven Kirk 11 years ago
parent
commit
d0efd0c6d4
  1. 15
      src/Perspex.Controls/Primitives/TemplatedControl.cs
  2. 33
      tests/Perspex.Controls.UnitTests/Primitives/TemplatedControlTests.cs

15
src/Perspex.Controls/Primitives/TemplatedControl.cs

@ -251,7 +251,15 @@ namespace Perspex.Controls.Primitives
{ {
if (!_templateApplied) if (!_templateApplied)
{ {
VisualChildren.Clear(); if (VisualChildren.Count > 0)
{
foreach (var child in this.GetTemplateChildren())
{
child.SetValue(TemplatedParentProperty, null);
}
VisualChildren.Clear();
}
if (Template != null) if (Template != null)
{ {
@ -318,6 +326,11 @@ namespace Perspex.Controls.Primitives
/// <param name="e">The event args.</param> /// <param name="e">The event args.</param>
protected virtual void OnTemplateChanged(PerspexPropertyChangedEventArgs e) protected virtual void OnTemplateChanged(PerspexPropertyChangedEventArgs e)
{ {
if (_templateApplied && VisualChildren.Count > 0)
{
_templateApplied = false;
}
_templateApplied = false; _templateApplied = false;
InvalidateMeasure(); InvalidateMeasure();
} }

33
tests/Perspex.Controls.UnitTests/Primitives/TemplatedControlTests.cs

@ -311,6 +311,39 @@ namespace Perspex.Controls.UnitTests.Primitives
Assert.True(raised); Assert.True(raised);
} }
[Fact]
public void Applying_New_Template_Clears_TemplatedParent_Of_Old_Template_Children()
{
var target = new TestTemplatedControl
{
Template = new FuncControlTemplate(_ => new Decorator
{
Child = new Border(),
})
};
target.ApplyTemplate();
var decorator = (Decorator)target.GetVisualChildren().Single();
var border = (Border)decorator.Child;
Assert.Equal(target, decorator.TemplatedParent);
Assert.Equal(target, border.TemplatedParent);
target.Template = new FuncControlTemplate(_ => new Canvas());
// Templated children should not be removed here: the control may be re-added
// somewhere with the same template, so they could still be of use.
Assert.Same(decorator, target.GetVisualChildren().Single());
Assert.Equal(target, decorator.TemplatedParent);
Assert.Equal(target, border.TemplatedParent);
target.ApplyTemplate();
Assert.Null(decorator.TemplatedParent);
Assert.Null(border.TemplatedParent);
}
private static IControl ScrollingContentControlTemplate(ContentControl control) private static IControl ScrollingContentControlTemplate(ContentControl control)
{ {
return new Border return new Border

Loading…
Cancel
Save