using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing.Design;
namespace DevComponents.DotNetBar.SuperGrid
{
///
/// Defines the collection of grid columns
///
[Editor("DevComponents.SuperGrid.Design.GridColumnCollectionEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))]
public class GridColumnCollection : CollectionBase
{
#region Events
///
/// Occurs when the collection has changed
///
[Description("Occurs when collection has changed.")]
public CollectionChangeEventHandler CollectionChanged;
#endregion
#region Private Variables
private GridElement _ParentItem;
private int[] _DisplayIndexMap;
private bool _IsDisplayIndexValid;
#endregion
#region Public properties
#region FirstSelectableColumn
///
/// Gets reference to first selectable column
/// or null if there is no first selectable column.
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridColumn FirstSelectableColumn
{
get
{
int[] displayMap = DisplayIndexMap;
for (int i = 0; i < displayMap.Length; i++)
{
GridColumn column = this[displayMap[i]];
if (column.Visible == true && column.AllowSelection == true)
return (column);
}
return (null);
}
}
#endregion
#region FirstVisibleColumn
///
/// Gets reference to first visible column
/// or null if there is no first visible column.
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridColumn FirstVisibleColumn
{
get
{
int[] displayMap = DisplayIndexMap;
for (int i = 0; i < displayMap.Length; i++)
{
if (this[displayMap[i]].Visible)
return (this[displayMap[i]]);
}
return (null);
}
}
#endregion
#region Index indexer
///
/// Returns reference to the object in collection based on it's index.
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridColumn this[int index]
{
get { return (GridColumn)(List[index]); }
set { List[index] = value; }
}
#endregion
#region Name indexer
///
/// Name indexer
///
///
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridColumn this[string name]
{
get
{
int index = FindIndexByName(name);
return (index >= 0 ? this[index] : null);
}
set
{
int index = FindIndexByName(name);
if (index < 0)
throw new Exception("Column Name not defined (" + name + ").");
List[index] = value;
}
}
#region FindIndexByName
private int FindIndexByName(string name)
{
for (int i=0; i
/// Gets reference to last selectable column
/// or null if there is no last selectable column.
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridColumn LastSelectableColumn
{
get
{
int[] displayMap = DisplayIndexMap;
for (int i = displayMap.Length - 1; i >= 0; i--)
{
GridColumn column = this[displayMap[i]];
if (column.Visible == true && column.AllowSelection == true)
return (column);
}
return (null);
}
}
#endregion
#region LastVisibleColumn
///
/// Gets reference to last visible column
/// or null if there is no last visible column.
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridColumn LastVisibleColumn
{
get
{
int[] displayMap = DisplayIndexMap;
for (int i = displayMap.Length - 1; i >= 0; i--)
{
if (this[displayMap[i]].Visible)
return (this[displayMap[i]]);
}
return (null);
}
}
#endregion
#region ParentItem
///
/// Gets or sets the node this collection is associated with.
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridElement ParentItem
{
get { return _ParentItem; }
internal set
{
_ParentItem = value;
OnParentItemChanged();
}
}
private void OnParentItemChanged()
{
}
#endregion
#endregion
#region Add
///
/// Adds new object to the collection.
///
/// Object to add.
/// Index of newly added object.
public int Add(GridColumn value)
{
value.ColumnIndex = List.Add(value);
return (value.ColumnIndex);
}
#endregion
#region Insert
///
/// Inserts new object into the collection.
///
/// Position of the object.
/// Object to insert.
public void Insert(int index, GridColumn value)
{
List.Insert(index, value);
for (int i = 0; i < Count; i++)
((GridColumn)List[i]).ColumnIndex = i;
}
#endregion
#region IndexOf
///
/// Returns index of the object inside of the collection.
///
/// Reference to the object.
/// Index of the object.
public int IndexOf(GridColumn value)
{
return (List.IndexOf(value));
}
#endregion
#region Contains
///
/// Returns whether collection contains specified object.
///
/// Object to look for.
/// true if object is part of the collection, otherwise false.
public bool Contains(GridColumn value)
{
return (List.Contains(value));
}
///
/// Returns whether collection contains specified object.
///
/// Name of the object to look for.
/// true if object is part of the collection, otherwise false.
public bool Contains(string name)
{
foreach (GridColumn column in List)
{
if (column.Name.Equals(name) == true)
return (true);
}
return (false);
}
#endregion
#region Remove
///
/// Removes specified object from the collection.
///
///
public void Remove(GridColumn value)
{
List.Remove(value);
for (int i = 0; i < Count; i++)
((GridColumn)List[i]).ColumnIndex = i;
}
#endregion
#region OnRemoveComplete
///
/// Called when remove of an item is completed.
///
/// Index of removed item
/// Removed item.
protected override void OnRemoveComplete(int index, object value)
{
if (value is GridColumn)
{
GridColumn column = (GridColumn)value;
GridPanel panel = column.GridPanel;
ResetColumn(panel, column);
}
OnCollectionChanged(CollectionChangeAction.Remove, value);
base.OnRemoveComplete(index, value);
}
#endregion
#region Clear
///
/// Clears all objects from the collection.
///
public new void Clear()
{
foreach (GridColumn column in this)
ResetColumn(column.GridPanel, column);
List.Clear();
}
#endregion
#region OnClearComplete
///
/// OnClearComplete
///
protected override void OnClearComplete()
{
InvalidateDisplayIndexes();
InvalidateLayout();
base.OnClearComplete();
}
#endregion
#region ResetColumn
private void ResetColumn(GridPanel panel, GridColumn column)
{
column.DisplayIndexChanged -= ColumnDisplayIndexChanged;
if (panel.DataSource != null)
panel.DataBinder.DataResetCount++;
GridCell cell = column.SuperGrid.ActiveElement as GridCell;
if (cell != null)
{
if (cell.ColumnIndex == column.ColumnIndex)
column.SuperGrid.ActiveElement = null;
}
if (panel.SortColumns.Contains(column))
panel.SortColumns.Remove(column);
if (panel.GroupColumns.Contains(column))
panel.GroupColumns.Remove(column);
FilterPanel fp = column.SuperGrid.ActiveFilterPanel;
if (fp != null && fp.GridColumn == column)
fp.EndEdit();
}
#endregion
#region OnInsertComplete
///
/// Called when insertion of an item is completed.
///
/// Insert index.
/// Inserted item.
protected override void OnInsertComplete(int index, object value)
{
if (value is GridColumn)
{
GridColumn column = (GridColumn)value;
if (column.Parent != null && column.Parent != _ParentItem)
throw new Exception("Column is already a member of another Column collection.");
column.DisplayIndexChanged += ColumnDisplayIndexChanged;
column.Parent = _ParentItem;
}
OnCollectionChanged(CollectionChangeAction.Add, value);
base.OnInsertComplete(index, value);
}
#endregion
#region OnCollectionChanged
private void OnCollectionChanged(
CollectionChangeAction action, object value)
{
for (int i = 0; i < Count; i++)
((GridColumn)List[i]).ColumnIndex = i;
if (action == CollectionChangeAction.Remove)
{
GridColumn rcol = (GridColumn)value;
GridPanel panel = rcol.GridPanel;
if (rcol.DisplayIndex >= 0)
{
foreach (GridColumn col in panel.Columns)
{
if (col.DisplayIndex > rcol.DisplayIndex)
col.DisplayIndex--;
}
}
}
InvalidateDisplayIndexes();
InvalidateLayout();
if (CollectionChanged != null)
{
CollectionChangeEventArgs e = new
CollectionChangeEventArgs(action, value);
CollectionChanged(this, e);
}
}
#endregion
#region ColumnDisplayIndexChanged
private void ColumnDisplayIndexChanged(object sender, EventArgs e)
{
InvalidateDisplayIndexes();
InvalidateLayout();
}
#endregion
#region InvalidateDisplayIndexes
///
/// Invalidates the display indexes and
/// causes them to be re-evaluated on next layout.
///
public void InvalidateDisplayIndexes()
{
_IsDisplayIndexValid = false;
}
#endregion
#region InvalidateLayout
private void InvalidateLayout()
{
if (_ParentItem != null)
{
_ParentItem.InvalidateLayout();
if (_ParentItem.SuperGrid != null)
{
_ParentItem.SuperGrid.NeedMergeLayout = true;
_ParentItem.SuperGrid.DisplayedMergeLayoutCount++;
}
}
}
#endregion
#region CopyTo
///
/// Copies collection into the specified array.
///
/// Array to copy collection to.
/// Starting index.
public void CopyTo(GridColumn[] array, int index)
{
List.CopyTo(array, index);
}
///
/// Copies contained items to the ColumnHeader array.
///
/// Array to copy to.
internal void CopyTo(GridColumn[] array)
{
List.CopyTo(array, 0);
}
#endregion
#region OnClear
///
/// Called when collection is cleared.
///
protected override void OnClear()
{
if (Count > 0)
{
GridPanel panel = this[0].Parent as GridPanel;
if (panel != null)
{
panel.SuperGrid.ActiveElement = null;
foreach (GridElement item in panel.Rows)
{
GridRow row = item as GridRow;
if (row != null)
{
foreach (GridCell cell in row.Cells)
{
cell.EditControl = null;
cell.RenderControl = null;
}
}
}
}
}
foreach (GridColumn item in this)
{
item.EditControl = null;
item.RenderControl = null;
}
base.OnClear();
}
#endregion
#region DisplayIndexMap
///
/// A map of display index (key) to index in the column collection
/// (value). Used to quickly find a column from its display index.
///
internal int[] DisplayIndexMap
{
get
{
if (!_IsDisplayIndexValid)
UpdateDisplayIndexMap();
return (_DisplayIndexMap);
}
}
#endregion
#region GetDisplayIndex
///
/// Gets the display index for specified column.
///
/// Column that is part of ColumnHeaderCollection
/// Display index or -1 column is not part of this collection.
public int GetDisplayIndex(GridColumn column)
{
return (GetDisplayIndex(IndexOf(column)));
}
///
/// Gets the display index for specified column.
///
///Column index
///Display index or -1 column is not part of this collection.
public int GetDisplayIndex(int index)
{
UpdateDisplayIndexMap();
for (int i = 0; i < _DisplayIndexMap.Length; i++)
{
if (_DisplayIndexMap[i] == index)
return (i);
}
return (-1);
}
#endregion
#region ColumnAtDisplayIndex
///
/// Returns the column that is displayed at specified display index.
///
/// 0 based display index.
/// ColumnHeader
public GridColumn ColumnAtDisplayIndex(int displayIndex)
{
UpdateDisplayIndexMap();
return (this[_DisplayIndexMap[displayIndex]]);
}
#endregion
#region UpdateDisplayIndexMap
private void UpdateDisplayIndexMap()
{
if (_IsDisplayIndexValid == false)
{
_IsDisplayIndexValid = true;
_DisplayIndexMap = new int[Count];
for (int i = 0; i < Count; i++)
_DisplayIndexMap[i] = -1;
for (int i = 0; i < Count; i++)
{
int di = this[i].DisplayIndex;
if (di != -1)
AddIndexToMap(i, di);
}
int n = 0;
for (int i = 0; i < Count; i++)
{
int di = this[i].DisplayIndex;
if (di == -1)
AddIndexToMap(i, n++);
}
}
}
private void AddIndexToMap(int i, int di)
{
for (int j = 0; j < Count; j++)
{
int n = (di + j) % Count;
if (_DisplayIndexMap[n] == -1)
{
_DisplayIndexMap[n] = i;
break;
}
}
}
#endregion
#region GetNextVisibleColumn
///
/// Gets reference to next visible column
/// or null if there is no next visible column
///
public GridColumn GetNextVisibleColumn(GridColumn column)
{
return (GetNextVisibleColumn(GetDisplayIndex(column)));
}
internal GridColumn GetNextVisibleColumn(int displayIndex)
{
int[] displayMap = DisplayIndexMap;
while (++displayIndex < Count)
{
if (this[displayMap[displayIndex]].Visible)
return (this[displayMap[displayIndex]]);
}
return (null);
}
#endregion
#region GetPrevVisibleColumn
///
/// Gets reference to previous visible column
/// or null if there is no last visible previous column
///
public GridColumn GetPrevVisibleColumn(GridColumn column)
{
return (GetPrevVisibleColumn(GetDisplayIndex(column)));
}
internal GridColumn GetPrevVisibleColumn(int displayIndex)
{
int[] displayMap = DisplayIndexMap;
while (--displayIndex >= 0)
{
if (this[displayMap[displayIndex]].Visible)
return (this[displayMap[displayIndex]]);
}
return (null);
}
#endregion
#region GetLastVisibleFrozenColumn
///
/// Gets reference to the last visible frozen column
/// or null if there is none
///
public GridColumn GetLastVisibleFrozenColumn()
{
int[] displayMap = DisplayIndexMap;
if (displayMap.Length > 0)
{
GridPanel panel = this[displayMap[0]].GridPanel;
if (panel != null &&
panel.FrozenColumnCount > 0 && panel.IsSubPanel == false)
{
for (int i = displayMap.Length - 1; i >= 0; i--)
{
GridColumn column = this[displayMap[i]];
if (column.Visible == true)
{
if (column.IsHFrozen == true)
return (column);
}
}
}
}
return (null);
}
#endregion
}
}