|
|
@ -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; |
|
|
|