From dc60d4bfb37d5bac4459b3ccea7477ff66fe1638 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 8 Jul 2016 17:15:34 +0200 Subject: [PATCH] Allow overriding ContentPresenter control creation. --- .../Presenters/ContentPresenter.cs | 81 +++++++++++-------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/src/Avalonia.Controls/Presenters/ContentPresenter.cs b/src/Avalonia.Controls/Presenters/ContentPresenter.cs index 4c5a488003..c17b11a374 100644 --- a/src/Avalonia.Controls/Presenters/ContentPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ContentPresenter.cs @@ -219,40 +219,7 @@ namespace Avalonia.Controls.Presenters { var content = Content; var oldChild = Child; - var newChild = content as IControl; - - if (content != null && newChild == null) - { - // We have content and it isn't a control, so first try to recycle the existing - // child control to display the new data by querying if the template that created - // the child can recycle items and that it also matches the new data. - if (oldChild != null && - _dataTemplate != null && - _dataTemplate.SupportsRecycling && - _dataTemplate.Match(content)) - { - newChild = oldChild; - } - else - { - // We couldn't recycle an existing control so find a data template for the data - // and use it to create a control. - _dataTemplate = this.FindDataTemplate(content, ContentTemplate) ?? FuncDataTemplate.Default; - newChild = _dataTemplate.Build(content); - - // Try to give the new control its own name scope. - var controlResult = newChild as Control; - - if (controlResult != null) - { - NameScope.SetNameScope(controlResult, new NameScope()); - } - } - } - else - { - _dataTemplate = null; - } + var newChild = CreateChild(); // Remove the old child if we're not recycling it. if (oldChild != null && newChild != oldChild) @@ -330,6 +297,52 @@ namespace Avalonia.Controls.Presenters } } + /// + /// Creates the child control. + /// + /// The child control or null. + protected virtual IControl CreateChild() + { + var content = Content; + var oldChild = Child; + var newChild = content as IControl; + + if (content != null && newChild == null) + { + // We have content and it isn't a control, so first try to recycle the existing + // child control to display the new data by querying if the template that created + // the child can recycle items and that it also matches the new data. + if (oldChild != null && + _dataTemplate != null && + _dataTemplate.SupportsRecycling && + _dataTemplate.Match(content)) + { + newChild = oldChild; + } + else + { + // We couldn't recycle an existing control so find a data template for the data + // and use it to create a control. + _dataTemplate = this.FindDataTemplate(content, ContentTemplate) ?? FuncDataTemplate.Default; + newChild = _dataTemplate.Build(content); + + // Try to give the new control its own name scope. + var controlResult = newChild as Control; + + if (controlResult != null) + { + NameScope.SetNameScope(controlResult, new NameScope()); + } + } + } + else + { + _dataTemplate = null; + } + + return newChild; + } + /// protected override Size MeasureOverride(Size availableSize) {