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);
}
[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]
public void Removing_Control_From_Panel_Should_Clear_Child_Controls_Parent()
{
@ -54,6 +66,23 @@ namespace Perspex.Controls.UnitTests
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]
public void Child_Control_Should_Appear_In_Panel_Children()
{

5
Perspex.Controls/DataTemplateExtensions.cs

@ -7,7 +7,7 @@
namespace Perspex.Controls
{
using System.Linq;
using Perspex.VisualTree;
using Perspex.LogicalTree;
using Splat;
public static class DataTemplateExtensions
@ -32,8 +32,7 @@ namespace Perspex.Controls
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.GetSelfAndVisualAncestors().OfType<Control>())
foreach (var i in control.GetSelfAndLogicalAncestors().OfType<Control>())
{
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)
{
Control container = this.CreateContainerOverride(item);
container.Parent = this.Owner;
container.TemplatedParent = null;
this.AddInternal(item, container);
result.Add(container);

45
Perspex.Controls/Panel.cs

@ -7,6 +7,7 @@
namespace Perspex.Controls
{
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using Perspex.Collections;
@ -39,6 +40,7 @@ namespace Perspex.Controls
{
if (this.children != null)
{
this.ClearLogicalParent(this.children);
this.children.CollectionChanged -= this.ChildrenChanged;
}
@ -49,50 +51,59 @@ namespace Perspex.Controls
{
this.children.CollectionChanged += this.ChildrenChanged;
this.AddVisualChildren(value);
this.SetLogicalParent(value);
this.InvalidateMeasure();
}
}
}
}
public bool IsLogicalParent { get; set; } = true;
IReadOnlyPerspexList<ILogical> ILogical.LogicalChildren
{
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)
{
case NotifyCollectionChangedAction.Add:
this.AddVisualChildren(e.NewItems.OfType<Visual>());
foreach (var child in e.NewItems.OfType<Control>())
{
child.Parent = logicalParent;
}
this.SetLogicalParent(e.NewItems.OfType<Control>());
break;
case NotifyCollectionChangedAction.Remove:
this.ClearLogicalParent(e.OldItems.OfType<Control>());
this.RemoveVisualChildren(e.OldItems.OfType<Visual>());
foreach (var child in e.OldItems.OfType<Control>())
{
child.Parent = null;
}
break;
case NotifyCollectionChangedAction.Reset:
this.ClearLogicalParent(e.OldItems.OfType<Control>());
this.ClearVisualChildren();
this.AddVisualChildren(this.children);
break;

2
Perspex.Controls/Popup.cs

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

1
Perspex.Controls/Presenters/ItemsPresenter.cs

@ -65,6 +65,7 @@ namespace Perspex.Controls.Presenters
{
this.ClearVisualChildren();
this.panel = this.ItemsPanel.Build();
this.panel.IsLogicalParent = false;
this.AddVisualChild(this.panel);
this.createdPanel = true;
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);
this.AddVisualChild(child);
child.Parent = this;
var templateChildren = this.GetVisualDescendents()
.OfType<Control>()

Loading…
Cancel
Save