// ----------------------------------------------------------------------- // // Copyright 2014 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex.Controls { using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using Perspex.Collections; /// /// Base class for controls that can contain multiple children. /// public class Panel : Control, ILogical { private Controls children; public Controls Children { get { if (this.children == null) { this.children = new Controls(); this.children.CollectionChanged += this.ChildrenChanged; } return this.children; } set { Contract.Requires(value != null); if (this.children != value) { if (this.children != null) { this.ClearLogicalParent(this.children); this.children.CollectionChanged -= this.ChildrenChanged; } this.children = value; this.ClearVisualChildren(); if (this.children != null) { this.children.CollectionChanged += this.ChildrenChanged; this.AddVisualChildren(value); this.SetLogicalParent(value); this.InvalidateMeasure(); } } } } public bool IsLogicalParent { get; set; } = true; IReadOnlyPerspexList ILogical.LogicalChildren { get { return this.children; } } private void ClearLogicalParent(IEnumerable controls) { if (this.IsLogicalParent) { foreach (var control in controls) { control.Parent = null; } } } private void SetLogicalParent(IEnumerable controls) { if (this.IsLogicalParent) { foreach (var control in controls) { control.Parent = this; } } } private void ChildrenChanged(object sender, NotifyCollectionChangedEventArgs e) { // TODO: Handle Replace. switch (e.Action) { case NotifyCollectionChangedAction.Add: this.AddVisualChildren(e.NewItems.OfType()); this.SetLogicalParent(e.NewItems.OfType()); break; case NotifyCollectionChangedAction.Remove: this.ClearLogicalParent(e.OldItems.OfType()); this.RemoveVisualChildren(e.OldItems.OfType()); break; case NotifyCollectionChangedAction.Reset: this.ClearLogicalParent(e.OldItems.OfType()); this.ClearVisualChildren(); this.AddVisualChildren(this.children); break; } this.InvalidateMeasure(); } } }