|
using System;
using System.Collections;
namespace System.Windows.Forms
{
/// <summary>
/// Collection of TreeListView item
/// </summary>
public class TreeListViewItemCollection : CollectionBase
{
/// <summary>
/// Comparer for TreeListViewItem
/// </summary>
public class TreeListViewItemCollectionComparer : ITreeListViewItemComparer
{
#region Order Property
private SortOrder _sortorder = SortOrder.Ascending;
/// <summary>
/// Sort order
/// </summary>
public SortOrder SortOrder
{
get{return(_sortorder);}
set{_sortorder = value;}
}
private int _column;
/// <summary>
/// Column for the comparison
/// </summary>
public int Column
{
get{return(_column);}
set{_column = value;}
}
#endregion
#region Constructor
/// <summary>
/// Create a new instance of Comparer
/// </summary>
public TreeListViewItemCollectionComparer() : this(SortOrder.Ascending, 0)
{}
/// <summary>
/// Create a new instance of Comparer
/// </summary>
/// <param name="order"></param>
public TreeListViewItemCollectionComparer(SortOrder order) : this(order, 0)
{
SortOrder = order;
}
/// <summary>
/// Create a new instance of Comparer
/// </summary>
/// <param name="order"></param>
/// <param name="column"></param>
public TreeListViewItemCollectionComparer(SortOrder order, int column)
{
SortOrder = order;
_column = column;
}
#endregion
#region Compare
/// <summary>
/// Compare two TreeListViewItems
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public int Compare(object x, object y)
{
TreeListViewItem a = (TreeListViewItem) x;
TreeListViewItem b = (TreeListViewItem) y;
int res = 1;
try
{
res = string.CompareOrdinal(a.SubItems[Column].Text.ToUpper(), b.SubItems[Column].Text.ToUpper());
}
catch
{}
switch(SortOrder)
{
case SortOrder.Ascending:
return(res);
case SortOrder.Descending:
return(-res);
default:
return(1);
}
}
#endregion
}
#region Properties
/// <summary>
/// Transforms the collection to an array
/// </summary>
public TreeListViewItem[] Array
{
get
{
if(TreeListView != null)
{
if(!ReadWriteLock.AcquireReaderLock(TreeListView.TimeOutChoice))
throw(new Exception("Error in Array of TreeListViewItemColleciton"));
}
else
ReadWriteLock.AcquireReaderLock(-1);
int size = this.Count;
TreeListViewItem[] eltsArray = new TreeListViewItem[size];
for(int i = 0 ; i < size ; i++)
eltsArray[i] = this[i];
ReadWriteLock.ReleaseReaderLock();
return(eltsArray);
}
}
/// <summary>
/// Get or set the new sortorder (apply automatically the sort function
/// if the sortorder value is changed)
/// </summary>
public SortOrder SortOrder
{
get{return(Comparer.SortOrder);}
set{Comparer.SortOrder = value;
Sort(false);}
}
private ITreeListViewItemComparer _comparer = new TreeListViewItemCollectionComparer(SortOrder.Ascending);
/// <summary>
/// Gets the comparer used in the Sort and Add functions
/// </summary>
public ITreeListViewItemComparer Comparer
{
get{return(_comparer);}
set{_comparer = value;}
}
/// <summary>
/// Set the new sortorder (apply automatically the sort function
/// if the sortorder value is changed) for each collection recursively
/// </summary>
public SortOrder SortOrderRecursively
{
set{SortOrder = value;
if(TreeListView != null)
{
if(!ReadWriteLock.AcquireReaderLock(TreeListView.TimeOutChoice))
throw(new Exception("Error in Array of TreeListViewItemColleciton"));
}
else
ReadWriteLock.AcquireReaderLock(-1);
foreach(TreeListViewItem item in this) item.Items.SortOrderRecursively = value;
ReadWriteLock.ReleaseReaderLock();}
}
internal SortOrder SortOrderRecursivelyWithoutSort
{
set{Comparer.SortOrder = value;
if(TreeListView != null)
{
if(!ReadWriteLock.AcquireReaderLock(TreeListView.TimeOutChoice))
throw(new Exception("Error in SortOrderRecursivelyWithoutSort of TreeListViewItemColleciton"));
}
else
ReadWriteLock.AcquireReaderLock(-1);
foreach(TreeListViewItem item in this) item.Items.SortOrderRecursivelyWithoutSort = value;
ReadWriteLock.ReleaseReaderLock();}
}
private MyReaderWriterLock _readwritelock =
new MyReaderWriterLock();
/// <summary>
/// ReaderWriterLock
/// </summary>
public MyReaderWriterLock ReadWriteLock
{get{return(_readwritelock);}}
private TreeListView _owner;
/// <summary>
/// TreeListView control that directly contains this collection
/// </summary>
public TreeListView Owner{get{return(_owner);}}
private TreeListViewItem _parent;
/// <summary>
/// TreeListViewItem that contains this collection
/// </summary>
public TreeListViewItem Parent{get{return(_parent);}}
/// <summary>
/// Returns the TreeListView set in Owner or in Parent
/// </summary>
private TreeListView TreeListView
{
get
{
if(Owner != null) return(Owner);
if(Parent != null) return(Parent.ListView);
return(null);
}
}
/// <summary>
/// Get an item in the collection
/// </summary>
public virtual TreeListViewItem this[int index]
{
get
{
return((TreeListViewItem) this.List[index]);}
}
#endregion
#region Constructors
/// <summary>
/// Create a collection in the root of a TreeListView (first level items)
/// </summary>
/// <param name="owner"></param>
public TreeListViewItemCollection(TreeListView owner)
{
_owner = owner;
}
/// <summary>
/// Create a collection within a TreeListViewItem
/// </summary>
/// <param name="parent"></param>
public TreeListViewItemCollection(TreeListViewItem parent)
{
_parent = parent;
}
/// <summary>
/// Create a free TreeListViewItemCollection (items will not be
/// displayed in a TreeListView
/// </summary>
public TreeListViewItemCollection()
{
}
#endregion
#region Sort Functions
/// <summary>
/// Sort the items in this collection (recursively or not)
/// </summary>
/// <param name="recursively">Recursively</param>
public void Sort(bool recursively)
{
if(TreeListView != null)
{
if(!ReadWriteLock.AcquireWriterLock(TreeListView.TimeOutChoice))
throw(new Exception("Error in Sort of TreeListViewItemColleciton"));
}
else
ReadWriteLock.AcquireWriterLock(-1);
// Gets an array of the items
TreeListViewItem[] thisarray = Array;
// System.Array.Sort(thisarray, new TreeListViewItemCollectionComparer(order));
// Removes the items
this.Clear();
// Adds the items
foreach(TreeListViewItem item in thisarray)
this.Add(item);
if(recursively)
foreach(TreeListViewItem item in thisarray)
item.Items.Sort(true);
ReadWriteLock.ReleaseWriterLock();
}
#endregion
#region Add Function
/// <summary>
/// Returns true if this collection contains an item
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool Contains(TreeListViewItem item)
{
bool res = false;
if(TreeListView != null)
{
if(!ReadWriteLock.AcquireReaderLock(TreeListView.TimeOutChoice))
throw(new Exception("Error in Contains of TreeListViewItemColleciton"));
}
else
ReadWriteLock.AcquireReaderLock(-1);
foreach(TreeListViewItem elt in this)
if(item.Text.ToUpper() == elt.Text.ToUpper())
{
res = true;
break;
}
ReadWriteLock.ReleaseReaderLock();
return(res);
}
internal delegate ListViewItem InsertListViewItem(int index, ListViewItem item);
/// <summary>
/// Adds an item in the collection and in the TreeListView
/// </summary>
/// <param name="item"></param>
/// <returns>Index of the item in the collection</returns>
public virtual int Add(TreeListViewItem item)
{
// Do not add the item if the collection owns a TreeListView recursively
// and the item already owns a TreeListView
if(TreeListView != null && item.ListView != null)
throw(new Exception("The Item is already in a TreeListView"));
int index = GetInsertCollectionIndex(item);
if(index == -1) return(-1);
if(Parent != null) item.SetParent(Parent);
item.Items.Comparer = this.Comparer;
if(TreeListView != null)
{
if(!ReadWriteLock.AcquireWriterLock(TreeListView.TimeOutChoice))
throw(new Exception("Error in Add of TreeListViewItemColleciton"));
}
else
ReadWriteLock.AcquireWriterLock(-1);
int treelistviewindex = GetInsertTreeListViewIndex(item, index);
// Insert in the ListView
if(treelistviewindex > -1)
{
ListView listview = (ListView) TreeListView;
InsertListViewItem insert = new InsertListViewItem(listview.Items.Insert);
if(listview.InvokeRequired)
listview.Invoke(insert, new object[] {treelistviewindex, (ListViewItem) item});
else
listview.Items.Insert(treelistviewindex, (ListViewItem) item);
if(item.IsExpanded) item.Expand();
item.SetIndentation();
}
// Insert in this collection
if(index > -1)
List.Insert(index, item);
ReadWriteLock.ReleaseWriterLock();
return(index);
}
/// <summary>
/// Adds an item in the collection and in the TreeListView
/// </summary>
/// <param name="value"></param>
/// <param name="imageindex"></param>
/// <returns></returns>
public virtual TreeListViewItem Add(string value, int imageindex)
{
TreeListViewItem item = new TreeListViewItem(value, imageindex);
this.Add(item);
return(item);
}
/// <summary>
/// Adds an item in the collection and in the TreeListView
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public virtual TreeListViewItem Add(string value)
{
TreeListViewItem item = new TreeListViewItem(value);
this.Add(item);
return(item);
}
/// <summary>
/// Adds a collection to this collection
/// </summary>
/// <param name="collection"></param>
public void AddRange(TreeListViewItemCollection collection)
{
foreach(TreeListViewItem item in collection)
Add(item);
}
#endregion
#region Remove & Clear Functions
/// <summary>
/// Removes each node of the collection
/// </summary>
public new void Clear()
{
if(TreeListView != null)
{
if(!ReadWriteLock.AcquireWriterLock(TreeListView.TimeOutChoice))
throw(new Exception("Error in Clear of TreeListViewItemColleciton"));
}
else
ReadWriteLock.AcquireWriterLock(-1);
while(this.Count > 0) this[0].Remove();
ReadWriteLock.ReleaseWriterLock();
}
/// <summary>
/// Remove an item from the collection and the TreeListView
/// </summary>
/// <param name="item"></param>
public virtual void Remove(TreeListViewItem item)
{
if(TreeListView != null)
{
if(!ReadWriteLock.AcquireWriterLock(TreeListView.TimeOutChoice))
throw(new Exception("Error in Remove of TreeListViewItemColleciton"));
}
else
ReadWriteLock.AcquireWriterLock(-1);
int index = GetIndexOf(item);
if(index == -1) return;
RemoveAt(index);
ReadWriteLock.ReleaseWriterLock();
}
/// <summary>
/// Gets the index of an item in the collection
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public int GetIndexOf(TreeListViewItem item)
{
int index = -1;
if(TreeListView != null)
{
if(!ReadWriteLock.AcquireReaderLock(TreeListView.TimeOutChoice))
throw(new Exception("Error in GetIndexOf of TreeListViewItemColleciton"));
}
else
ReadWriteLock.AcquireReaderLock(-1);
for(int i = 0 ; i < this.Count ; i++)
if(this[i] == item) {index = i; break;}
ReadWriteLock.ReleaseReaderLock();
return(index);
}
/// <summary>
/// Remove an item from the collection and the TreeListView
/// </summary>
/// <param name="index"></param>
public new void RemoveAt(int index)
{
if(TreeListView != null)
{
if(!ReadWriteLock.AcquireWriterLock(TreeListView.TimeOutChoice))
throw(new Exception("Error in RemoveAt of TreeListViewItemColleciton"));
}
else
ReadWriteLock.AcquireWriterLock(-1);
TreeListViewItem item = this[index];
if(this[index].Visible && this.TreeListView != null) item.Hide();
List.RemoveAt(index);
item.SetParent(null);
ReadWriteLock.ReleaseWriterLock();
}
#endregion
#region Internal Functions
private int GetInsertTreeListViewIndex(TreeListViewItem item, int collectionindex)
{
if(TreeListView == null) return(-1);
if(TreeListView != null)
{
if(!ReadWriteLock.AcquireReaderLock(TreeListView.TimeOutChoice))
throw(new Exception("Error in GetInsertTreeListViewIndex of TreeListViewItemColleciton"));
}
else
ReadWriteLock.AcquireReaderLock(-1);
if(Owner != null)
{
int a = 0;
a++;
}
int index = -1;
// First level item (no parent)
if(Owner != null && collectionindex != -1)
{
if(collectionindex == 0) index = 0;
else index =
this[collectionindex - 1].LastChildIndexInListView + 1;
}
else if(Parent != null && collectionindex != -1)
{
if(!Parent.Visible || !Parent.IsExpanded) index = -1;
else
{
if(collectionindex == 0) index = Parent.Index + 1;
else index =
Parent.Items[collectionindex - 1].LastChildIndexInListView + 1;
}
}
ReadWriteLock.ReleaseReaderLock();
return(index);
}
private int GetInsertCollectionIndex(TreeListViewItem item)
{
int index = -1;
if(TreeListView != null)
{
if(!ReadWriteLock.AcquireReaderLock(TreeListView.TimeOutChoice))
throw(new Exception("Error in Clear of TreeListViewItemColleciton"));
}
else
ReadWriteLock.AcquireReaderLock(-1);
if(!this.Contains(item))
switch(SortOrder)
{
// No sortorder -> at the end of the collection
case System.Windows.Forms.SortOrder.None:
index = this.Count;
break;
default:
for(int i = 0 ; i < this.Count ; i++)
{
// Change the index for the compare if the order is descending
int indexcompare = i;
// SortOrder == System.Windows.Forms.SortOrder.Ascending ?
// i : this.Count - (1 + i);
int comp = Comparer.Compare(item, this[indexcompare]);
if(comp <= 0)
{
index = indexcompare;
break;
}
}
index = index == -1 ? this.Count : index;
break;
}
ReadWriteLock.ReleaseReaderLock();
return(index);
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.