Browse Source

Search logical tree for DataTemplates.

pull/39/head
Steven Kirk 11 years ago
parent
commit
fc5ff22d8e
  1. 29
      Perspex.Controls.UnitTests/PanelTests.cs
  2. 5
      Perspex.Controls/DataTemplateExtensions.cs
  3. 1
      Perspex.Controls/Generators/ItemContainerGenerator.cs
  4. 45
      Perspex.Controls/Panel.cs
  5. 2
      Perspex.Controls/Popup.cs
  6. 1
      Perspex.Controls/Presenters/ItemsPresenter.cs
  7. 1
      Perspex.Controls/Primitives/TemplatedControl.cs

29
Perspex.Controls.UnitTests/PanelTests.cs

@ -24,6 +24,18 @@ namespace Perspex.Controls.UnitTests
Assert.AreEqual(((ILogical)child).LogicalParent, panel); Assert.AreEqual(((ILogical)child).LogicalParent, panel);
} }
[TestMethod]
public void Setting_Controls_Should_Set_Child_Controls_Parent()
{
var panel = new Panel();
var child = new Control();
panel.Children = new Controls { child };
Assert.AreEqual(child.Parent, panel);
Assert.AreEqual(((ILogical)child).LogicalParent, panel);
}
[TestMethod] [TestMethod]
public void Removing_Control_From_Panel_Should_Clear_Child_Controls_Parent() public void Removing_Control_From_Panel_Should_Clear_Child_Controls_Parent()
{ {
@ -54,6 +66,23 @@ namespace Perspex.Controls.UnitTests
Assert.IsNull(((ILogical)child2).LogicalParent); Assert.IsNull(((ILogical)child2).LogicalParent);
} }
[TestMethod]
public void Resetting_Panel_Children_Should_Clear_Child_Controls_Parent()
{
var panel = new Panel();
var child1 = new Control();
var child2 = new Control();
panel.Children.Add(child1);
panel.Children.Add(child2);
panel.Children = new Controls();
Assert.IsNull(child1.Parent);
Assert.IsNull(((ILogical)child1).LogicalParent);
Assert.IsNull(child2.Parent);
Assert.IsNull(((ILogical)child2).LogicalParent);
}
[TestMethod] [TestMethod]
public void Child_Control_Should_Appear_In_Panel_Children() public void Child_Control_Should_Appear_In_Panel_Children()
{ {

5
Perspex.Controls/DataTemplateExtensions.cs

@ -7,7 +7,7 @@
namespace Perspex.Controls namespace Perspex.Controls
{ {
using System.Linq; using System.Linq;
using Perspex.VisualTree; using Perspex.LogicalTree;
using Splat; using Splat;
public static class DataTemplateExtensions public static class DataTemplateExtensions
@ -32,8 +32,7 @@ namespace Perspex.Controls
public static IDataTemplate FindDataTemplate(this Control control, object data) public static IDataTemplate FindDataTemplate(this Control control, object data)
{ {
// TODO: This needs to traverse the logical tree, not the visual. foreach (var i in control.GetSelfAndLogicalAncestors().OfType<Control>())
foreach (var i in control.GetSelfAndVisualAncestors().OfType<Control>())
{ {
foreach (IDataTemplate dt in i.DataTemplates.Reverse()) foreach (IDataTemplate dt in i.DataTemplates.Reverse())
{ {

1
Perspex.Controls/Generators/ItemContainerGenerator.cs

@ -83,6 +83,7 @@ namespace Perspex.Controls.Generators
foreach (object item in items) foreach (object item in items)
{ {
Control container = this.CreateContainerOverride(item); Control container = this.CreateContainerOverride(item);
container.Parent = this.Owner;
container.TemplatedParent = null; container.TemplatedParent = null;
this.AddInternal(item, container); this.AddInternal(item, container);
result.Add(container); result.Add(container);

45
Perspex.Controls/Panel.cs

@ -7,6 +7,7 @@
namespace Perspex.Controls namespace Perspex.Controls
{ {
using System; using System;
using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Linq; using System.Linq;
using Perspex.Collections; using Perspex.Collections;
@ -39,6 +40,7 @@ namespace Perspex.Controls
{ {
if (this.children != null) if (this.children != null)
{ {
this.ClearLogicalParent(this.children);
this.children.CollectionChanged -= this.ChildrenChanged; this.children.CollectionChanged -= this.ChildrenChanged;
} }
@ -49,50 +51,59 @@ namespace Perspex.Controls
{ {
this.children.CollectionChanged += this.ChildrenChanged; this.children.CollectionChanged += this.ChildrenChanged;
this.AddVisualChildren(value); this.AddVisualChildren(value);
this.SetLogicalParent(value);
this.InvalidateMeasure(); this.InvalidateMeasure();
} }
} }
} }
} }
public bool IsLogicalParent { get; set; } = true;
IReadOnlyPerspexList<ILogical> ILogical.LogicalChildren IReadOnlyPerspexList<ILogical> ILogical.LogicalChildren
{ {
get { return this.children; } get { return this.children; }
} }
private void ChildrenChanged(object sender, NotifyCollectionChangedEventArgs e) private void ClearLogicalParent(IEnumerable<Control> controls)
{ {
var logicalParent = (Control)this; if (this.IsLogicalParent)
{
foreach (var control in controls)
{
control.Parent = null;
}
}
}
while (logicalParent.TemplatedParent != null) private void SetLogicalParent(IEnumerable<Control> controls)
{
if (this.IsLogicalParent)
{ {
logicalParent = (Control)logicalParent.TemplatedParent; foreach (var control in controls)
{
control.Parent = this;
}
} }
}
// TODO: Handle Move and Replace. private void ChildrenChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// TODO: Handle Replace.
switch (e.Action) switch (e.Action)
{ {
case NotifyCollectionChangedAction.Add: case NotifyCollectionChangedAction.Add:
this.AddVisualChildren(e.NewItems.OfType<Visual>()); this.AddVisualChildren(e.NewItems.OfType<Visual>());
this.SetLogicalParent(e.NewItems.OfType<Control>());
foreach (var child in e.NewItems.OfType<Control>())
{
child.Parent = logicalParent;
}
break; break;
case NotifyCollectionChangedAction.Remove: case NotifyCollectionChangedAction.Remove:
this.ClearLogicalParent(e.OldItems.OfType<Control>());
this.RemoveVisualChildren(e.OldItems.OfType<Visual>()); this.RemoveVisualChildren(e.OldItems.OfType<Visual>());
foreach (var child in e.OldItems.OfType<Control>())
{
child.Parent = null;
}
break; break;
case NotifyCollectionChangedAction.Reset: case NotifyCollectionChangedAction.Reset:
this.ClearLogicalParent(e.OldItems.OfType<Control>());
this.ClearVisualChildren(); this.ClearVisualChildren();
this.AddVisualChildren(this.children); this.AddVisualChildren(this.children);
break; break;

2
Perspex.Controls/Popup.cs

@ -44,7 +44,6 @@ namespace Perspex.Controls
} }
}); });
} }
public Control Child public Control Child
{ {
get { return this.GetValue(ChildProperty); } get { return this.GetValue(ChildProperty); }
@ -68,6 +67,7 @@ namespace Perspex.Controls
if (this.root == null) if (this.root == null)
{ {
this.root = new PopupRoot(); this.root = new PopupRoot();
this.root.Parent = this;
this.root[~PopupRoot.ContentProperty] = this[~ChildProperty]; this.root[~PopupRoot.ContentProperty] = this[~ChildProperty];
} }

1
Perspex.Controls/Presenters/ItemsPresenter.cs

@ -65,6 +65,7 @@ namespace Perspex.Controls.Presenters
{ {
this.ClearVisualChildren(); this.ClearVisualChildren();
this.panel = this.ItemsPanel.Build(); this.panel = this.ItemsPanel.Build();
this.panel.IsLogicalParent = false;
this.AddVisualChild(this.panel); this.AddVisualChild(this.panel);
this.createdPanel = true; this.createdPanel = true;
this.ItemsChanged(Tuple.Create(default(IEnumerable), this.Items)); this.ItemsChanged(Tuple.Create(default(IEnumerable), this.Items));

1
Perspex.Controls/Primitives/TemplatedControl.cs

@ -118,6 +118,7 @@ namespace Perspex.Controls.Primitives
var child = this.Template.Build(this); var child = this.Template.Build(this);
this.AddVisualChild(child); this.AddVisualChild(child);
child.Parent = this;
var templateChildren = this.GetVisualDescendents() var templateChildren = this.GetVisualDescendents()
.OfType<Control>() .OfType<Control>()

Loading…
Cancel
Save