// The Nova Project by Ken Beckett.
// Copyright (C) 2007-2012 Inevitable Software, all rights reserved.
// Released under the Common Development and Distribution License, CDDL-1.0: http://opensource.org/licenses/cddl1.php
using System.Collections.Generic;
namespace Nova.UI
{
/// <summary>
/// Used to manage collections of child <see cref="CodeObjectVM"/>s, setting the Parent of
/// each child object added to the collection.
/// </summary>
/// <typeparam name="T">The specific type of objects in the collection (must be <see cref="CodeObjectVM"/> or a derived type).</typeparam>
public class ChildListVM<T> : List<T> where T : CodeObjectVM
{
#region /* FIELDS */
protected CodeObjectVM ParentVM;
#endregion
#region /* CONSTRUCTORS */
/// <summary>
/// Create a <see cref="ChildListVM{T}"/>, optionally using a specified parent <see cref="CodeObjectVM"/> object.
/// </summary>
public ChildListVM(CodeObjectVM parentVM)
{
ParentVM = parentVM;
}
#endregion
#region /* PROPERTIES */
/// <summary>
/// The Parent object of the collection.
/// </summary>
public CodeObjectVM Parent
{
get { return ParentVM; }
}
/// <summary>
/// Get the last item in the collection.
/// </summary>
public T Last
{
get { return (Count > 0 ? this[Count - 1] : null); }
}
#endregion
#region /* METHODS */
/// <summary>
/// Add an item to the collection, setting its Parent.
/// </summary>
public new void Add(T item)
{
if (item != null)
{
//// If any added items already have a parent, and it's not the same as the parent of this collection,
//// clone them so that we don't end up changing their Parent. Otherwise, this could happen in many cases,
//// such as adding an evaluated TypeRef as a type argument, etc. If code objects are moved (such as drag/drop),
//// they will be removed first, which will null the Parent reference, then added, avoiding the clone.
//if (item.Parent != null && item.Parent != ParentVM)
// item = (T)item.Clone();
item.ParentVM = ParentVM;
}
base.Add(item);
}
/// <summary>
/// Add a collection of items to the collection, setting their Parents.
/// </summary>
public new void AddRange(IEnumerable<T> collection)
{
if (collection != null)
{
foreach (T item in collection)
Add(item);
}
}
/// <summary>
/// Insert an item into the collection, setting its Parent.
/// </summary>
public new void Insert(int index, T item)
{
base.Insert(index, item);
if (item != null)
item.ParentVM = ParentVM;
}
#endregion
}
#region /* STATIC HELPER METHODS */
/// <summary>
/// Static helper methods for ChildList - used in these cases so that the collection itself can be
/// checked for being null inside the call.
/// </summary>
public static class ChildListHelpers
{
/// <summary>
/// Return the first object in the collection, or null if the collection is null or empty.
/// </summary>
public static T First<T>(ChildListVM<T> thisChildList) where T : CodeObjectVM
{
return ((thisChildList != null && thisChildList.Count > 0) ? thisChildList[0] : null);
}
public static void UnRender<T>(ChildListVM<T> thisChildList) where T : CodeObjectVM
{
if (thisChildList != null)
{
foreach (T codeObjectVM in thisChildList)
{
if (codeObjectVM != null)
codeObjectVM.UnRender();
}
}
}
}
#endregion
}