Browse Source

Revert "Revert "Set ContentPresenter.DataContext in UpdateChild.""

This reverts commit bf02ae41a9.
pull/545/head
Steven Kirk 10 years ago
parent
commit
7b3e25949e
  1. 92
      src/Avalonia.Controls/Presenters/ContentPresenter.cs
  2. 1
      tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs
  3. 4
      tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests.cs
  4. 1
      tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests.cs

92
src/Avalonia.Controls/Presenters/ContentPresenter.cs

@ -96,10 +96,6 @@ namespace Avalonia.Controls.Presenters
/// </summary> /// </summary>
public ContentPresenter() public ContentPresenter()
{ {
var dataContext = this.GetObservable(ContentProperty)
.Select(x => x is IControl ? AvaloniaProperty.UnsetValue : x);
Bind(Control.DataContextProperty, dataContext);
} }
/// <summary> /// <summary>
@ -221,39 +217,36 @@ namespace Avalonia.Controls.Presenters
/// </remarks> /// </remarks>
public void UpdateChild() public void UpdateChild()
{ {
var old = Child;
var content = Content; var content = Content;
var result = content as IControl; var oldChild = Child;
var newChild = content as IControl;
if (result == null) if (content != null && newChild == null)
{ {
DataContext = content; // 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
if (content != null) // the child can recycle items and that it also matches the new data.
if (oldChild != null &&
_dataTemplate != null &&
_dataTemplate.SupportsRecycling &&
_dataTemplate.Match(content))
{ {
if (old != null && newChild = oldChild;
_dataTemplate != null &&
_dataTemplate.SupportsRecycling &&
_dataTemplate.Match(content))
{
result = old;
}
else
{
_dataTemplate = this.FindDataTemplate(content, ContentTemplate) ?? FuncDataTemplate.Default;
result = _dataTemplate.Build(content);
var controlResult = result as Control;
if (controlResult != null)
{
NameScope.SetNameScope(controlResult, new NameScope());
}
}
} }
else else
{ {
_dataTemplate = null; // 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 else
@ -261,30 +254,35 @@ namespace Avalonia.Controls.Presenters
_dataTemplate = null; _dataTemplate = null;
} }
if (result != old) // Remove the old child if we're not recycling it.
if (oldChild != null && newChild != oldChild)
{ {
if (old != null) VisualChildren.Remove(oldChild);
{ }
VisualChildren.Remove(old);
}
if (result != null) // Set the DataContext if the data isn't a control.
{ if (!(content is IControl))
((ISetInheritanceParent)result).SetParent(this); {
DataContext = content;
}
Child = result; // Update the Child.
if (newChild == null)
{
Child = null;
}
else if (newChild != oldChild)
{
((ISetInheritanceParent)newChild).SetParent(this);
if (result.Parent == null) Child = newChild;
{
((ISetLogicalParent)result).SetParent((ILogical)this.TemplatedParent ?? this);
}
VisualChildren.Add(result); if (newChild.Parent == null)
}
else
{ {
Child = null; ((ISetLogicalParent)newChild).SetParent((ILogical)this.TemplatedParent ?? this);
} }
VisualChildren.Add(newChild);
} }
_createdChild = true; _createdChild = true;

1
tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs

@ -370,6 +370,7 @@ namespace Avalonia.Controls.UnitTests
target.Presenter.ApplyTemplate(); target.Presenter.ApplyTemplate();
var dataContexts = target.Presenter.Panel.Children var dataContexts = target.Presenter.Panel.Children
.Do(x => (x as ContentPresenter)?.UpdateChild())
.Cast<Control>() .Cast<Control>()
.Select(x => x.DataContext) .Select(x => x.DataContext)
.ToList(); .ToList();

4
tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests.cs

@ -143,13 +143,15 @@ namespace Avalonia.Controls.UnitTests.Presenters
} }
[Fact] [Fact]
public void Assigning_NonControl_To_Content_Should_Set_DataContext() public void Assigning_NonControl_To_Content_Should_Set_DataContext_On_UpdateChild()
{ {
var target = new ContentPresenter var target = new ContentPresenter
{ {
Content = "foo", Content = "foo",
}; };
target.UpdateChild();
Assert.Equal("foo", target.DataContext); Assert.Equal("foo", target.DataContext);
} }

1
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests.cs

@ -312,6 +312,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
var dataContexts = target.Panel.Children var dataContexts = target.Panel.Children
.Cast<ContentPresenter>() .Cast<ContentPresenter>()
.Do(x => x.UpdateChild())
.Select(x => x.DataContext) .Select(x => x.DataContext)
.ToList(); .ToList();

Loading…
Cancel
Save