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

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

@ -311,6 +311,39 @@ namespace Perspex.Controls.UnitTests.Primitives
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)
{
return new Border

Loading…
Cancel
Save