7 changed files with 230 additions and 18 deletions
@ -0,0 +1,86 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="LogicalChildren.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls |
||||
|
{ |
||||
|
using System.Collections.Generic; |
||||
|
using System.Collections.ObjectModel; |
||||
|
using System.Collections.Specialized; |
||||
|
using System.Linq; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Manages parenting for a collection of logical child controls.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of the controls.</typeparam>
|
||||
|
/// <remarks>
|
||||
|
/// Unfortunately, because of ObservableCollection's handling of clear (the cleared items
|
||||
|
/// aren't passed to the CollectionChanged event) we have to hold two lists of child controls:
|
||||
|
/// the ones in Panel.Children and the ones here - held in case the ObservableCollection
|
||||
|
/// gets cleared. It's either that or write a proper PerspexList which is too much work
|
||||
|
/// for now.
|
||||
|
/// </remarks>
|
||||
|
internal class LogicalChildren<T> where T : class, ILogical, IVisual |
||||
|
{ |
||||
|
private T parent; |
||||
|
|
||||
|
private List<T> inner = new List<T>(); |
||||
|
|
||||
|
public LogicalChildren(T parent, INotifyCollectionChanged childrenCollection) |
||||
|
{ |
||||
|
this.parent = parent; |
||||
|
childrenCollection.CollectionChanged += CollectionChanged; |
||||
|
} |
||||
|
|
||||
|
private void Add(IEnumerable<T> items) |
||||
|
{ |
||||
|
foreach (T item in items) |
||||
|
{ |
||||
|
this.inner.Add(item); |
||||
|
item.LogicalParent = this.parent; |
||||
|
item.VisualParent = this.parent; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void Remove(IEnumerable<T> items) |
||||
|
{ |
||||
|
foreach (T item in items) |
||||
|
{ |
||||
|
this.inner.Remove(item); |
||||
|
item.LogicalParent = null; |
||||
|
item.VisualParent = null; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void Reset(IEnumerable<T> newState) |
||||
|
{ |
||||
|
this.Add(newState.Except(this.inner)); |
||||
|
this.Remove(this.inner.Except(newState)); |
||||
|
} |
||||
|
|
||||
|
private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) |
||||
|
{ |
||||
|
switch (e.Action) |
||||
|
{ |
||||
|
case NotifyCollectionChangedAction.Add: |
||||
|
this.Add(e.NewItems.Cast<T>()); |
||||
|
break; |
||||
|
|
||||
|
case NotifyCollectionChangedAction.Remove: |
||||
|
this.Remove(e.OldItems.Cast<T>()); |
||||
|
break; |
||||
|
|
||||
|
case NotifyCollectionChangedAction.Replace: |
||||
|
this.Remove(e.OldItems.Cast<T>()); |
||||
|
this.Add(e.NewItems.Cast<T>()); |
||||
|
break; |
||||
|
|
||||
|
case NotifyCollectionChangedAction.Reset: |
||||
|
this.Reset((IEnumerable<T>)sender); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,36 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="Panel.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Collections.ObjectModel; |
||||
|
using System.Collections.Specialized; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Base class for controls that can contain multiple children.
|
||||
|
/// </summary>
|
||||
|
public class Panel : Control |
||||
|
{ |
||||
|
private LogicalChildren<Control> logicalChildren; |
||||
|
|
||||
|
public Panel() |
||||
|
{ |
||||
|
this.Children = new ObservableCollection<Control>(); |
||||
|
this.logicalChildren = new LogicalChildren<Control>(this, this.Children); |
||||
|
} |
||||
|
|
||||
|
public ObservableCollection<Control> Children |
||||
|
{ |
||||
|
get; |
||||
|
private set; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue