4019 lines
109 KiB
C#
Raw Permalink Blame History

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Media;
using System.Windows.Forms;
using DevComponents.DotNetBar.SuperGrid.Style;
namespace DevComponents.DotNetBar.SuperGrid
{
/// <summary>
/// Defines Grid element with Items collection
/// </summary>
public abstract class GridContainer : GridElement, IDisposable
{
#region Private variables
private GridItemsCollection _Rows;
private Cs _States;
private int _Index;
private int _FullIndex;
private int _RowIndex;
private int _GridIndex;
private int _IndentLevel;
private Rectangle _CheckBoxBounds;
private Rectangle _ContainerBounds;
private GridElement _MouseOverElement;
private int _FixedRowHeight;
private int _FixedHeaderHeight;
private int _FirstOnScreenRowIndex;
private ushort _DeleteUpdateCount;
private ushort _ExpandedUpdateCount;
private ushort _SelectionUpdateCount;
private ushort _SelectionClearCount;
private ushort _StyleUpdateCount;
private ushort _MergeUpdateCount = 1;
private RowVisualStyles _RowStyles;
private RowVisualStyles _EffectiveRowStyles;
private CellVisualStyles _CellVisualStyles;
private string _RowHeaderText = "";
private List<CellRange> _DisplayedCellRanges;
private CellRange _LastCellRange;
private int _DisplayedMergeLayoutCount;
private bool _NeedMergeLayout;
private MergeScan _MergeScan;
private CellRange _SuspendedRange;
#endregion
#region Abstract methods
/// <summary>
/// Creates the GridItemsCollection that hosts the items.
/// </summary>
/// <returns>New instance of GridItemsCollection.</returns>
protected abstract GridItemsCollection CreateItemsCollection();
/// <summary>
/// Disposes of the GridItemsCollection that hosts the items.
/// </summary>
protected abstract void DisposeItemsCollection(GridItemsCollection items);
#endregion
#region Public properties
#region Bounds
///<summary>
/// Gets the scroll adjusted bounds
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override Rectangle Bounds
{
get
{
Rectangle r = BoundsRelative;
r.X -= HScrollOffset;
if (IsVFrozen == false)
r.Y -= VScrollOffset;
return (r);
}
}
#endregion
#region CellStyles
/// <summary>
/// Gets or sets the default Cell visual styles
/// </summary>
[Category("Style")]
[Description("Indicates the default Cell visual styles.")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public CellVisualStyles CellStyles
{
get
{
if (_CellVisualStyles == null)
{
_CellVisualStyles = new CellVisualStyles();
UpdateChangeHandler(null, _CellVisualStyles);
}
return (_CellVisualStyles);
}
set
{
if (_CellVisualStyles != value)
{
CellVisualStyles oldValue = _CellVisualStyles;
_CellVisualStyles = value;
OnStyleChanged("CellVisualStyles", oldValue, value);
if (oldValue != null)
oldValue.Dispose();
}
}
}
#endregion
#region Checked
///<summary>
/// Gets or sets the row CheckBox checked state
///</summary>
[DefaultValue(false), Category("Appearance")]
[Description("Indicates the row CheckBox checked state.")]
public virtual bool Checked
{
get { return (TestState(Cs.Checked)); }
set
{
if (Checked != value)
{
SetState(Cs.Checked, value);
OnCheckedChanged();
}
}
}
#region OnCheckedChanged
private void OnCheckedChanged()
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (HasCheckBox == true)
{
Rectangle r = _CheckBoxBounds;
if (panel.IsSubPanel == true ||
(panel.PrimaryColumn != null && panel.PrimaryColumn.IsHFrozen == false))
{
r.X -= HScrollOffset;
}
if (IsVFrozen == false)
r.Y -= VScrollOffset;
InvalidateRender(r);
}
OnPropertyChanged("Checked");
SuperGrid.DoAfterCheckEvent(panel, this);
}
}
#endregion
#endregion
#region DisplayedRowCount
///<summary>
/// Gets the count of visible rows on screen
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int DisplayedRowCount
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
GridContainer frow = FirstOnScreenRow;
GridContainer lrow = LastOnScreenRow;
if (frow != null && lrow != null)
return (lrow.GridIndex - frow.GridIndex + 1);
}
return (0);
}
}
#endregion
#region Expanded
///<summary>
/// Gets or sets whether the row is
/// expanded, permitting its child rows to be visible
///</summary>
[DefaultValue(false), Category("Appearance")]
[Description("Indicates whether the row is expanded, permitting its child rows to be visible.")]
public bool Expanded
{
get { return (TestState(Cs.Expanded)); }
set
{
if (Expanded != value)
{
SetExpanded(value, ExpandSource.Expand);
OnPropertyChangedEx("Expanded", VisualChangeType.Layout);
}
}
}
#endregion
#region FirstOnScreenRow
///<summary>
/// Gets the first visible row on screen
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridContainer FirstOnScreenRow
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
int index = FirstOnScreenRowIndex;
if (panel.VirtualMode == true)
{
if (index < panel.VirtualRowCountEx)
return (panel.VirtualRows[index]);
}
else
{
if ((uint)index < Rows.Count)
{
GridContainer row = panel.Rows[index] as GridContainer;
if (row != null && row.Visible == true)
{
if (row.Expanded == true && row.Rows.Count > 0)
{
GridContainer roe =
GetFirstOnScreenRow(row.Rows, SuperGrid.ViewRect);
if (roe != null)
return (roe);
}
return (row);
}
}
}
}
return (null);
}
set
{
if (value != null)
value.ScrollToTop();
}
}
#endregion
#region FirstOnScreenRowIndex
///<summary>
/// Gets the first visible on screen row index
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int FirstOnScreenRowIndex
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
if ((VScrollOffset == 0 && panel.IsFiltered == false && panel.DeletedRowCount == 0) ||
(Parent != null && IsVFrozen == true))
{
_FirstOnScreenRowIndex = 0;
}
else
{
Rectangle r = SuperGrid.ViewRect;
_FirstOnScreenRowIndex = (panel.VirtualMode == true)
? GetFirstOnScreenVirtualRowIndex(panel)
: GetFirstOnScreenRealRowIndex(r);
}
}
if (panel.VirtualMode == true)
{
if (_FirstOnScreenRowIndex >= panel.VirtualRowCount)
_FirstOnScreenRowIndex = 0;
}
else
{
if (_FirstOnScreenRowIndex >= Rows.Count)
_FirstOnScreenRowIndex = 0;
}
return (_FirstOnScreenRowIndex);
}
set
{
GridPanel panel = GridPanel;
if (panel.VirtualMode == true)
{
if ((uint)value < panel.VirtualRowCount)
FirstOnScreenRow = panel.VirtualRows[value];
}
else
{
if ((uint)value < Rows.Count)
FirstOnScreenRow = Rows[value] as GridContainer;
}
}
}
#region GetFirstOnScreenVirtualRow
private int GetFirstOnScreenVirtualRowIndex(GridPanel panel)
{
Rectangle r = BoundsRelative;
int vrh = Dpi.Height(panel.VirtualRowHeight);
r.Y += (FixedRowHeight - panel.FrozenRowCount * vrh);
int y = VScrollOffset;
if (Parent == null)
y += (panel.FrozenRowCount * vrh);
else
y = (y - r.Y) + SuperGrid.PrimaryGrid.FixedRowHeight;
int n = y / vrh - 0;
return (n > 0 ? n : 0);
}
#endregion
#region GetFirstOnScreenRealRowIndex
private int GetFirstOnScreenRealRowIndex(Rectangle r)
{
int lo = 0;
int hi = Rows.Count - 1;
while (lo < hi)
{
int mid = (lo + hi) / 2;
GridElement item = Rows[mid];
Rectangle t = item is GridPanel ? ((GridPanel)item).ContainerBounds : item.BoundsRelative;
if (item.IsVFrozen == false)
t.Y -= VScrollOffset;
if (t.Bottom > r.Y)
{
if (t.Y <= r.Y)
{
if (item.Visible == true)
return (mid);
}
hi = mid - 1;
}
else
{
lo = mid + 1;
}
}
while (lo < Rows.Count)
{
if (Rows[lo].Visible == true)
break;
lo++;
}
return (lo);
}
#endregion
#endregion
#region GetFirstOnScreenRow
private GridContainer
GetFirstOnScreenRow(GridItemsCollection items, Rectangle t)
{
for (int i = 0; i < items.Count; i++)
{
GridContainer item = items[i] as GridContainer;
if (item != null)
{
Rectangle r = item.BoundsRelative;
if (item.IsVFrozen == false)
r.Y -= VScrollOffset;
if (r.Bottom > t.Top)
{
if (item.Expanded == true && item.Rows.Count > 0)
{
GridContainer row = GetFirstOnScreenRow(item.Rows, t);
return (row ?? item);
}
return (item);
}
}
}
return (null);
}
#endregion
#region FirstSelectableRow
///<summary>
/// Gets the first selectable row
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridContainer FirstSelectableRow
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (panel.VirtualMode == true)
{
if (panel.VirtualRowCountEx > 0)
return (panel.VirtualRows[0]);
}
else
{
foreach (GridContainer row in panel.Rows)
{
if (row.Visible == true && row.AllowSelection == true)
return (row);
}
}
}
return (null);
}
}
#endregion
#region FirstVisibleRow
///<summary>
/// Gets the first visible row
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridContainer FirstVisibleRow
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (panel.VirtualMode == true)
{
if (panel.VirtualRowCountEx > 0)
return (panel.VirtualRows[0]);
}
else
{
foreach (GridContainer row in panel.Rows)
{
if (row.Visible == true)
return (row);
}
}
}
return (null);
}
}
#endregion
#region FullIndex
///<summary>
/// Gets the sequential index for the row
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int FullIndex
{
get
{
CheckIndicees();
return (_FullIndex);
}
internal set { _FullIndex = value; }
}
#endregion
#region GridIndex
///<summary>
/// Gets the sequential index for the visible, expanded row
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int GridIndex
{
get
{
CheckIndicees();
return (_GridIndex);
}
internal set { _GridIndex = value; }
}
#endregion
#region Index
///<summary>
/// Gets the sequential, visible, local container index for the item
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int Index
{
get
{
CheckIndicees();
return (_Index);
}
internal set { _Index = value; }
}
#endregion
#region IsActive
///<summary>
/// Gets whether the item is Active
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsActive
{
get { return (this == SuperGrid.ActiveRow); }
}
#endregion
#region IsDeleted
///<summary>
/// Gets whether the item is deleted
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual bool IsDeleted
{
get
{
GridPanel panel = GetParentPanel();
if (panel != null)
{
if (_DeleteUpdateCount != panel.DeleteUpdateCount)
{
SetState(Cs.Deleted, panel.IsRowDeleted(this));
_DeleteUpdateCount = panel.DeleteUpdateCount;
}
}
return (TestState(Cs.Deleted));
}
set
{
SetState(Cs.Deleted, value);
GridPanel panel = GetParentPanel();
if (panel != null)
{
if (panel.SetDeleted(this, value) == true)
_DeleteUpdateCount = panel.DeleteUpdateCount;
}
}
}
#endregion
#region IsExpandedVisible
///<summary>
/// Gets whether the item is visible
/// and its parental hierarchy is expanded
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsExpandedVisible
{
get
{
if (Visible == false)
return (false);
GridContainer row = Parent as GridContainer;
while (row != null)
{
if (row.Visible == false)
return (false);
if (row is GridPanel == false)
{
if (row.Expanded == false)
return (false);
}
row = row.Parent as GridContainer;
}
return (true);
}
}
#endregion
#region IsOnScreen
///<summary>
/// Gets whether the item is visible on screen
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsOnScreen
{
get
{
if (Visible == true)
{
GridPanel panel = GridPanel;
if (panel != null)
{
Rectangle t = SViewRect;
Rectangle bounds = Bounds;
bounds.Width = panel.ColumnHeader.BoundsRelative.Width;
return (t.IntersectsWith(bounds));
}
}
return (false);
}
}
#endregion
#region IsSelectable
///<summary>
/// Gets whether the row can be selected by the user.
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsSelectable
{
get { return (AllowSelection == true); }
}
#endregion
#region IsSelected
///<summary>
/// Gets or sets whether the item is selected
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsSelected
{
get
{
if (AllowSelection == true)
{
GridPanel panel = GetParentPanel();
if (panel != null)
{
if ((_SelectionUpdateCount != panel.SelectionUpdateCount) ||
(_ExpandedUpdateCount != panel.ExpandedUpdateCount))
{
if (ExpandedVisible(panel) == true)
Selected = panel.IsItemSelectedEx(this);
_SelectionUpdateCount = panel.SelectionUpdateCount;
}
return (Selected);
}
}
return (false);
}
set
{
GridPanel panel = GetParentPanel();
if (panel != null)
{
if (Selected != value)
{
Selected = value;
if (ExpandedVisible(panel) == true)
panel.SetSelectedEx(this, value);
_SelectionUpdateCount = panel.SelectionUpdateCount;
Rectangle r = ContainerBounds;
r.X -= HScrollOffset;
if (IsVFrozen == false)
r.Y -= VScrollOffset;
InvalidateRender(r);
}
}
}
}
#region ExpandedVisible
internal bool ExpandedVisible(GridPanel panel)
{
if (_ExpandedUpdateCount != panel.ExpandedUpdateCount)
{
_ExpandedUpdateCount = panel.ExpandedUpdateCount;
SetState(Cs.ExpandedVisible, IsExpandedVisible);
}
return (TestState(Cs.ExpandedVisible));
}
#endregion
#endregion
#region LastOnScreenRow
///<summary>
/// Gets the last visible on screen row
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridContainer LastOnScreenRow
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (panel.VirtualMode == true)
{
int index = LastOnScreenRowIndex;
if (index < panel.VirtualRowCountEx)
return (panel.VirtualRows[index]);
}
else
{
if (IsExpandedVisible == true)
return (GetLastOnScreenRow(panel.Rows, SuperGrid.ViewRect));
}
}
return (null);
}
set
{
if (value != null)
value.ScrollToBottom();
}
}
#region GetLastOnScreenRow
private GridContainer
GetLastOnScreenRow(GridItemsCollection items, Rectangle t)
{
GridContainer lrow = null;
for (int i = 0; i < items.Count; i++)
{
GridContainer item = items[i] as GridContainer;
if (item != null && item.Visible == true)
{
lrow = item;
Rectangle r = item.BoundsRelative;
if (item.IsVFrozen == false)
r.Y -= VScrollOffset;
if (r.Bottom >= t.Bottom || i == items.Count - 1)
{
if (item.Expanded == true && item.Rows.Count > 0)
{
GridContainer row = GetLastOnScreenRow(item.Rows, t);
return (row ?? item);
}
return (item);
}
}
}
return (lrow);
}
#endregion
#endregion
#region LastOnScreenRowIndex
///<summary>
/// Gets the last visible on screen row index
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int LastOnScreenRowIndex
{
get
{
if (IsExpandedVisible == true)
{
GridPanel panel = GridPanel;
if (panel != null)
{
Rectangle t = SuperGrid.ViewRect;
return (panel.VirtualMode == true)
? (GetLastOnScreenVirtualRowIndex(panel, t))
: (GetLastOnScreenRealRowIndex(panel, t));
}
}
return (0);
}
set
{
GridPanel panel = GridPanel;
if (panel.VirtualMode == true)
{
if ((uint)value < panel.VirtualRowCount)
LastOnScreenRow = panel.VirtualRows[value];
}
else
{
if ((uint)value < Rows.Count)
LastOnScreenRow = Rows[value] as GridContainer;
}
}
}
#region GetLastOnScreenVirtualRowIndex
private int GetLastOnScreenVirtualRowIndex(
GridPanel panel, Rectangle t)
{
int index = FirstOnScreenRowIndex;
GridRow row = panel.VirtualRows[index];
int vrh = Dpi.Height(panel.VirtualRowHeight);
Rectangle r = row.BoundsRelative;
r.Y -= VScrollOffset;
int n = (t.Bottom - r.Top + vrh - 1) / vrh;
return (Math.Min(panel.VisibleRowCount - 1, index + n - 1));
}
#endregion
#region GetLastOnScreenRealRowIndex
private int GetLastOnScreenRealRowIndex(GridPanel panel, Rectangle t)
{
int index = FirstOnScreenRowIndex;
while (index + 1 < Rows.Count)
{
index++;
GridContainer item = (GridContainer)panel.Rows[index];
Rectangle r = item.BoundsRelative;
if (item.IsVFrozen == false)
r.Y -= VScrollOffset;
if (r.Bottom >= t.Bottom)
return (index);
}
return (index);
}
#endregion
#endregion
#region LastSelectableRow
///<summary>
/// Gets the last user selectable row
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridContainer LastSelectableRow
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (panel.VirtualMode == true)
{
if (panel.VirtualRowCountEx > 0)
return (panel.VirtualRows[panel.VirtualRowCountEx - 1]);
}
else
{
return (GetLastSelectableRow(panel.Rows));
}
}
return (null);
}
}
#region GetLastSelectableRow
private GridContainer GetLastSelectableRow(GridItemsCollection rows)
{
for (int i = rows.Count - 1; i >= 0; i--)
{
GridContainer row = rows[i] as GridContainer;
if (row != null)
{
if (row.Visible == true && row.AllowSelection == true)
{
if (row.Rows.Count > 0 && row.Expanded == true)
{
GridContainer srow = GetLastSelectableRow(row.Rows);
if (srow != null)
row = srow;
}
return (row);
}
}
}
return (null);
}
#endregion
#endregion
#region LastVisibleRow
///<summary>
/// Gets the last visible row
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridContainer LastVisibleRow
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (panel.VirtualMode == true)
{
if (panel.VirtualRowCountEx > 0)
return (panel.VirtualRows[panel.VirtualRowCountEx - 1]);
}
else
{
for (int i = panel.Rows.Count - 1; i >= 0; i--)
{
GridContainer row = panel.Rows[i] as GridContainer;
if (row != null)
{
if (row.Visible == true)
return (row);
}
}
}
}
return (null);
}
}
#endregion
#region NextVisibleRow
///<summary>
/// Gets the next visible row, or null if no
/// subsequent rows are defined
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridContainer NextVisibleRow
{
get
{
GridPanel panel = GetParentPanel();
if (panel != null)
{
int index = GridIndex + 1;
GridElement item = panel.GetRowFromIndex(index);
while (item != null)
{
if (ItemIsSelectable(panel, item) == true)
return ((GridContainer) item);
item = panel.GetRowFromIndex(++index);
}
}
return (null);
}
}
private bool ItemIsSelectable(GridPanel panel, GridElement item)
{
if (item.Visible == false)
return (false);
if (item is GridGroup && panel.GroupHeaderKeyBehavior != GroupHeaderKeyBehavior.Select)
return (false);
return (item is GridContainer);
}
#endregion
#region PrevVisibleRow
///<summary>
/// Gets the previous visible row, or null if
/// no previous rows are defined
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridContainer PrevVisibleRow
{
get
{
GridPanel panel = GetParentPanel();
if (panel != null)
{
int index = GridIndex;
while (--index >= 0)
{
GridElement item = panel.GetRowFromIndex(index);
if (item == null)
break;
if (ItemIsSelectable(panel, item) == true)
return ((GridContainer)item);
}
}
return (null);
}
}
#endregion
#region ReadOnly
/// <summary>
/// Gets or sets whether the user can change the row contents
/// </summary>
[DefaultValue(false), Category("Behavior")]
[Description("Indicates whether the user can change the row contents.")]
public bool ReadOnly
{
get { return (TestState(Cs.ReadOnly)); }
set
{
if (value != ReadOnly)
{
SetState(Cs.ReadOnly, value);
OnPropertyChangedEx("ReadOnly", VisualChangeType.Render);
}
}
}
#endregion
#region RowHeaderText
///<summary>
/// Gets or sets the associated row header text.
///</summary>
[DefaultValue(""), Category("Appearance")]
[Description("Indicates the associated row header text.).")]
public string RowHeaderText
{
get { return (_RowHeaderText); }
set
{
if (_RowHeaderText != value)
{
_RowHeaderText = value;
NeedsMeasured = true;
OnPropertyChangedEx("RowHeaderText", VisualChangeType.Render);
}
}
}
#endregion
#region RowIndex
///<summary>
/// Gets the sequential, parental index of the item
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int RowIndex
{
get
{
CheckIndicees();
return (_RowIndex);
}
internal set { _RowIndex = value; }
}
#region CheckIndicees
private void CheckIndicees()
{
GridPanel panel = GridPanel;
if (panel != null)
panel.UpdateIndicees(panel, panel.Rows, true);
}
#endregion
#endregion
#region Rows
/// <summary>
/// Gets the reference to the Rows collection
/// </summary>
[DefaultValue(null), Category("Data")]
[Description("Indicates the reference to the Rows collection.")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public virtual GridItemsCollection Rows
{
get
{
if (_Rows == null)
_Rows = CreateItemsCollection();
return (_Rows);
}
set
{
if (_Rows != null)
DisposeItemsCollection(_Rows);
_Rows = value;
}
}
#endregion
#region RowsUnresolved
///<summary>
/// Gets or sets whether the rows collection is unknown and has not
/// been resolved (presumes there are rows until set to false)
///</summary>
[DefaultValue(false), Category("Data")]
[Description("Indicates whether the rows collection is unresolved (presumes there are rows until set to false).")]
public bool RowsUnresolved
{
get { return (TestState(Cs.RowsUnresolved)); }
set
{
if (RowsUnresolved != value)
{
SetState(Cs.RowsUnresolved, value);
OnPropertyChangedEx("RowsUnresolved", VisualChangeType.Layout);
}
}
}
#endregion
#region RowStyles
/// <summary>
/// Gets or sets the visual styles assigned to the row elements
/// </summary>
[Category("Style")]
[Description("Indicates visual style assigned to the row elements")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public RowVisualStyles RowStyles
{
get
{
if (_RowStyles == null)
{
_RowStyles = new RowVisualStyles();
UpdateChangeHandler(null, _RowStyles);
}
return (_RowStyles);
}
set
{
if (_RowStyles != value)
{
RowVisualStyles oldValue = _RowStyles;
_RowStyles = value;
OnStyleChanged("RowStyles", oldValue, value);
if (oldValue != null)
oldValue.Dispose();
}
}
}
#endregion
#region ShowCheckBox
/// <summary>
/// Get or sets whether the row CheckBox is shown (Panel.CheckBoxes must also be true)
/// </summary>
[DefaultValue(true), Category("Appearance")]
[Description("Indicates whether the row CheckBox is shown (Panel.CheckBoxes must also be true).")]
public bool ShowCheckBox
{
get { return (TestState(Cs.ShowCheckBox)); }
set
{
if (ShowCheckBox != value)
{
SetState(Cs.ShowCheckBox, value);
NeedsMeasured = true;
OnPropertyChangedEx("ShowCheckBox", VisualChangeType.Layout);
}
}
}
#endregion
#region ShowTreeButton
/// <summary>
/// Gets or sets whether expand / collapse
/// buttons are shown if the row contains nested items
/// </summary>
[DefaultValue(true), Category("Appearance")]
[Description("Indicates whether Tree expand / collapse buttons are shown if the row contains nested items.")]
public bool ShowTreeButton
{
get { return (TestState(Cs.ShowTreeButton)); }
set
{
if (ShowTreeButton != value)
{
SetState(Cs.ShowTreeButton, value);
OnPropertyChangedEx("ShowTreeButton", VisualChangeType.Layout);
}
}
}
#endregion
#endregion
#region Constructors
/// <summary>
/// GridContainer
/// </summary>
protected GridContainer()
{
SetState(Cs.ShowCheckBox, true);
SetState(Cs.ShowTreeButton, true);
}
#endregion
#region Internal properties
#region CanModify
internal virtual bool CanModify
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (panel.ReadOnly == true)
return (false);
}
return (ReadOnly == false && IsDeleted == false);
}
}
#endregion
#region CheckBoxBounds
internal Rectangle CheckBoxBounds
{
get { return (_CheckBoxBounds); }
set { _CheckBoxBounds = value; }
}
#endregion
#region ContainerBounds
internal Rectangle ContainerBounds
{
get { return (_ContainerBounds); }
set { _ContainerBounds = value; }
}
#endregion
#region DisplayedCellRanges
internal List<CellRange> DisplayedCellRanges
{
get { return (_DisplayedCellRanges); }
set { _DisplayedCellRanges = value; }
}
#endregion
#region DisplayedMergeLayoutCount
internal int DisplayedMergeLayoutCount
{
get { return (_DisplayedMergeLayoutCount); }
set { _DisplayedMergeLayoutCount = value; }
}
#endregion
#region FixedHeaderHeight
/// <summary>
/// Get or sets the FixedHeaderHeight
/// </summary>
internal int FixedHeaderHeight
{
get { return (_FixedHeaderHeight); }
set { _FixedHeaderHeight = value; }
}
#endregion
#region FixedRowHeight
/// <summary>
/// Get or sets the FixedRowHeight
/// </summary>
internal int FixedRowHeight
{
get { return (_FixedRowHeight); }
set { _FixedRowHeight = value; }
}
#endregion
#region HasCheckBox
internal bool HasCheckBox
{
get
{
GridPanel ppanel = GetParentPanel();
if (ppanel != null)
{
if (ppanel.CheckBoxes != true)
return (false);
}
return (ShowCheckBox);
}
}
#endregion
#region HasVisibleItems
internal bool HasVisibleItems
{
get { return (TestState(Cs.HasVisibleItems)); }
set { SetState(Cs.HasVisibleItems, value); }
}
#endregion
#region IndentLevel
/// <summary>
/// Get or sets the panel indent level
/// </summary>
internal int IndentLevel
{
get { return (_IndentLevel); }
set { _IndentLevel = value; }
}
#endregion
#region IsActiveRow
internal bool IsActiveRow
{
get
{
GridPanel panel = GridPanel;
return (panel.ActiveRow != null &&
panel.ActiveRow.GridIndex == GridIndex);
}
}
#endregion
#region IsDeletedEx
internal bool IsDeletedEx
{
get { return (TestState(Cs.Deleted)); }
set { IsDeleted = value; }
}
#endregion
#region IsMergeSuspended
internal bool IsMergeSuspended
{
get { return (_SuspendedRange != null); }
}
#endregion
#region MaxRowIndex
internal int MaxRowIndex
{
get
{
GridPanel panel = this as GridPanel;
if (panel != null && panel.VirtualMode == true)
return (panel.VirtualRowCountEx - 1);
return (Rows.Count - 1);
}
}
#endregion
#region MergeUpdateCount
internal ushort MergeUpdateCount
{
get { return (_MergeUpdateCount); }
set { _MergeUpdateCount = value; }
}
#endregion
#region MergeScan
internal MergeScan MergeScan
{
get
{
if (_MergeScan == null)
_MergeScan = new MergeScan(this);
return (_MergeScan);
}
set { _MergeScan = value; }
}
#endregion
#region MouseOverElement
internal GridElement MouseOverElement
{
get { return (_MouseOverElement); }
}
#endregion
#region NeedMergeLayout
internal bool NeedMergeLayout
{
get { return (_NeedMergeLayout); }
set { _NeedMergeLayout = value; }
}
#endregion
#region Selected
internal bool Selected
{
get
{
if (AllowSelection == false)
return (false);
GridPanel panel = GetParentPanel();
if (panel != null)
{
if (_SelectionClearCount != panel.SelectionClearCount)
{
_SelectionClearCount = panel.SelectionClearCount;
Selected = false;
if (ExpandedVisible(panel) == true)
panel.SetSelectedEx(this, false);
InvalidateRender();
}
}
return (TestState(Cs.Selected));
}
set
{
SetState(Cs.Selected, value);
GridPanel panel = GetParentPanel();
if (panel != null)
_SelectionClearCount = panel.SelectionClearCount;
}
}
#endregion
#region SelectionClearCount
internal ushort SelectionClearCount
{
get { return (_SelectionClearCount); }
set { _SelectionClearCount = value; }
}
#endregion
#region SuspendedRange
/// <summary>
/// Get or sets the current suspended range
/// </summary>
internal CellRange SuspendedRange
{
get { return (_SuspendedRange); }
set { _SuspendedRange = value; }
}
#endregion
#endregion
#region TestState
private bool TestState(Cs state)
{
return ((_States & state) == state);
}
#endregion
#region SetState
private void SetState(Cs state, bool value)
{
if (value == true)
_States |= state;
else
_States &= ~state;
}
#endregion
#region GetVisibleItemCount
internal int GetVisibleItemCount()
{
int n = 0;
if (Expanded == true)
{
foreach (GridElement item in Rows)
{
if (item.Visible == true)
{
n++;
GridContainer row = item as GridContainer;
if (row != null)
{
if (row.Rows.Count > 0 && row.Expanded == true)
n += row.GetVisibleItemCount();
}
}
}
}
return (n);
}
#endregion
#region GetNextItem
internal GridContainer GetNextItem()
{
GridContainer container = Parent as GridContainer;
if (container != null)
{
GridPanel panel = container as GridPanel;
if (panel != null && panel.VirtualMode == true)
{
GridRow row = this as GridRow;
if (row != null)
{
int n = row.GridIndex + 1;
if (n < panel.VirtualRowCountEx)
return (panel.VirtualRows[n]);
}
}
else
{
int index = RowIndex;
if (index >= 0)
{
for (int i = index + 1; i < container.Rows.Count; i++)
{
GridContainer item = container.Rows[i] as GridContainer;
if (item != null && item.Visible == true)
return (item);
}
}
}
}
return (null);
}
#endregion
#region GetPrevItem
internal GridContainer GetPrevItem()
{
GridContainer container = Parent as GridContainer;
if (container != null)
{
GridPanel panel = container as GridPanel;
if (panel != null && panel.VirtualMode == true)
{
GridRow row = this as GridRow;
if (row != null)
{
int n = row.GridIndex - 1;
if (n >= 0)
return (panel.VirtualRows[n]);
}
}
else
{
for (int i = Index - 1; i >= 0; i--)
{
GridContainer item = container.Rows[i] as GridContainer;
if (item != null && item.Visible == true)
return (item);
}
}
}
return (null);
}
#endregion
#region FindGridPanel
///<summary>
/// Finds the GridPanel with the given Name.
/// Only the root Rows collection is searched.
///</summary>
///<returns>GridPanel, or null if not found.</returns>
public GridPanel FindGridPanel(string name)
{
return (FindGridPanel(name, false));
}
///<summary>
/// Finds the GridPanel with the given Name.
/// Nested Rows are searched if 'includeNested' is true.
///</summary>
///<param name="name">Name to search</param>
///<param name="includeNested">Whether to include nested rows in the search.</param>
///<returns>GridPanel, or null if not found.</returns>
public GridPanel FindGridPanel(string name, bool includeNested)
{
GridItemsCollection items = Rows;
foreach (GridElement item in items)
{
GridPanel panel = item as GridPanel;
if (panel != null)
{
if (panel.Name != null && panel.Name.Equals(name))
return (panel);
}
}
if (includeNested == true)
{
foreach (GridElement item in items)
{
GridContainer container = item as GridContainer;
if (container != null)
{
GridPanel panel = container.FindGridPanel(name, true);
if (panel != null)
return (panel);
}
}
}
return (null);
}
#endregion
#region SetExpanded
private void SetExpanded(bool value, ExpandSource source)
{
GridPanel panel = GridPanel;
if (panel != null)
{
panel.FlushActiveRow();
if (Expanded == false)
{
bool dynanic = RowsUnresolved;
if (SuperGrid == null ||
SuperGrid.DoBeforeExpandEvent(panel, this, source) == false)
{
ProcessExpandChange(panel, value);
if (dynanic == true && RowsUnresolved == false)
{
if (panel.SortColumns.Count > 0)
panel.NeedsSorted = true;
}
if (SuperGrid != null)
SuperGrid.DoAfterExpandEvent(panel, this, source);
}
}
else
{
if (SuperGrid == null ||
SuperGrid.DoBeforeCollapseEvent(panel, this, source) == false)
{
ProcessExpandChange(panel, value);
if (SuperGrid != null)
SuperGrid.DoAfterCollapseEvent(panel, this, source);
}
}
}
else
{
SetState(Cs.Expanded, value);
}
}
#region ProcessExpandChange
private void ProcessExpandChange(GridPanel panel, bool value)
{
if (value == true)
SetState(Cs.Expanded, true);
//if (SuperGrid.IsUpdateSuspended == false)
{
int index = GridIndex;
int count = GetVisibleItemCount();
panel.ExpandSelectedAtIndex(index + 1, count, value);
if (value == false)
SetState(Cs.Expanded, false);
if (Parent is GridContainer)
((GridContainer)Parent).InvalidateMerge();
}
//else
//{
// if (value == false)
// SetState(Cs.Expanded, false);
//}
panel.ExpandedUpdateCount++;
}
#endregion
#endregion
#region ExpandItemTree
/// <summary>
/// Expands the entire tree, as necessary, to display the given row.
/// </summary>
/// <returns>'true' if any expanding was actually performed</returns>
public bool ExpandItemTree()
{
GridContainer row = Parent as GridContainer;
bool expandChanged = false;
while (row != null)
{
if (row is GridRow || row is GridGroup)
{
if (row.Expanded == false)
{
if (row.Rows.Count > 0 || row.RowsUnresolved == true)
{
row.Expanded = true;
expandChanged = true;
}
}
}
row = row.Parent as GridContainer;
}
return (expandChanged);
}
#endregion
#region ExpandAll
///<summary>
/// Expands all rows in the Rows collection.
///</summary>
public void ExpandAll()
{
ExpandAll(-1, true);
}
///<summary>
/// Expands all rows in the Rows collection to the provided depth.
///
/// If a depth is provided, then rows will be expanded only to the given depth.
/// In other words, to expand only the first level of rows in the container, you would
/// call ExpandAll(0). To expand the first level <20> as well as 2 levels under it,
/// you would call ExpandAll(2).
///</summary>
public void ExpandAll(int depth)
{
ExpandAll(depth, true);
}
private void ExpandAll(int depth, bool expand)
{
if (Rows.Count > 0)
{
SuperGrid.BeginUpdate();
foreach (GridElement item in Rows)
{
GridContainer row = item as GridContainer;
if (row != null)
{
if (row.Expanded != expand)
row.SetExpanded(expand, ExpandSource.ExpandAll);
if (depth != 0)
row.ExpandAll(depth - 1, expand);
}
}
SuperGrid.EndUpdate();
InvalidateLayout();
GridPanel.InvalidateMerge();
}
}
#endregion
#region CollapseAll
///<summary>
/// Collapses all expanded rows.
///</summary>
public void CollapseAll()
{
ExpandAll(-1, false);
}
///<summary>
/// Collapses all rows in the Rows collection to the provided depth.
///
/// If a depth is provided, then rows will be collapsed only to the given depth.
/// In other words, to collapse only the first level of rows in the container, you would
/// call CollapseAll(0). To collapse the first level <20> as well as 2 levels under it,
/// you would call CollapseAll(2).
///</summary>
public void CollapseAll(int depth)
{
ExpandAll(depth, false);
}
#endregion
#region SetActive
///<summary>
/// Makes the given row active
///</summary>
///<returns>true, if successful</returns>
public bool SetActive()
{
return (SetActive(false));
}
///<summary>
/// Makes the given row active and
/// optionally selects the given row
///</summary>
///<returns>true, if successful</returns>
public bool SetActive(bool select)
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (panel.SetActiveRow(this) == true)
{
if (select == true)
{
GridPanel.ClearAll();
IsSelected = true;
if (panel.SelectionRowAnchor == null)
panel.SelectionRowAnchor = this;
}
return (true);
}
}
return (false);
}
#endregion
#region EnsureVisible
///<summary>
/// This routine will ensure that the row is visible on
/// the screen. If the row is not visible on screen, the
/// view window will be scrolled to make it visible.
///</summary>
///<param name="center">If 'true', the row will be centered on screen</param>
public override void EnsureVisible(bool center)
{
if (Visible == true)
{
GridPanel panel = GridPanel;
if (ExpandItemTree() == true || FixedRowHeight <= 0 || panel.IsLayoutValid == false)
SuperGrid.ArrangeGrid();
Rectangle t = SViewRect;
Rectangle bounds = BoundsRelative;
int fixedHeight = FixedRowHeight;
if (panel.VirtualMode == true)
{
int vrh = Dpi.Height(panel.VirtualRowHeight);
bounds = panel.BoundsRelative;
bounds.Y += (panel.FixedRowHeight - (panel.FrozenRowCount * vrh));
bounds.Y += (GridIndex * vrh);
fixedHeight = (this is GridRow) ? vrh : 0;
}
if (fixedHeight >= t.Height || bounds.Y - VScrollOffset < t.Y)
{
int n = bounds.Y - t.Y;
if (center == false || fixedHeight >= t.Height)
SuperGrid.SetVScrollValue(n);
else
SuperGrid.SetVScrollValue(n - (t.Height - fixedHeight) / 2);
}
else if (bounds.Y - VScrollOffset > t.Bottom - fixedHeight)
{
int n = bounds.Y - (t.Bottom - fixedHeight);
if (center == false)
SuperGrid.SetVScrollValue(n);
else
SuperGrid.SetVScrollValue(n + (t.Height - fixedHeight) / 2);
}
}
}
#endregion
#region ScrollToTop
/// <summary>
/// Scrolls the row to the 'logical' top of the grid display.
/// </summary>
public void ScrollToTop()
{
if (Visible == true)
{
if (IsVFrozen == false)
{
if (ExpandItemTree() == true)
SuperGrid.ArrangeGrid();
Rectangle t = SViewRect;
Rectangle bounds = BoundsRelative;
GridPanel panel = GridPanel;
if (panel.VirtualMode == true)
{
int vrh = Dpi.Height(panel.VirtualRowHeight);
bounds = panel.BoundsRelative;
bounds.Y += (panel.FixedRowHeight - (panel.FrozenRowCount * vrh));
bounds.Y += (GridIndex * vrh);
}
int n = bounds.Y - t.Y;
SuperGrid.SetVScrollValue(n);
}
}
}
#endregion
#region ScrollToBottom
/// <summary>
/// Scrolls the row to the 'logical' bottom of the grid display.
/// </summary>
public void ScrollToBottom()
{
if (Visible == true)
{
if (IsVFrozen == false)
{
ExpandItemTree();
SuperGrid.ArrangeGrid();
Rectangle t = SViewRect;
Rectangle bounds = BoundsRelative;
GridPanel panel = GridPanel;
if (panel.VirtualMode == true)
{
int vrh = Dpi.Height(panel.VirtualRowHeight);
bounds = panel.BoundsRelative;
bounds.Y += (panel.FixedRowHeight - (panel.FrozenRowCount * vrh));
bounds.Y += (GridIndex * vrh);
}
int n = bounds.Y - (t.Bottom) + FixedRowHeight;
SuperGrid.SetVScrollValue(n);
}
}
}
#endregion
#region ExtendSelection
internal void ExtendSelection(
GridPanel panel, GridContainer endItem, bool extend)
{
if (panel.SelectionRowAnchor != null)
{
int startIndex = panel.SelectionRowAnchor.GridIndex;
int endIndex = endItem.GridIndex;
panel.NormalizeIndices(false, 0, ref startIndex, ref endIndex);
if (panel.OnlyRowsSelected(startIndex, endIndex) == false)
{
if (extend == false)
panel.ClearAllSelected();
else
panel.ClearAll(false);
panel.SetSelectedRows(startIndex, endIndex - startIndex + 1, true);
GridContainer row = GetLastProcessedRow(panel);
if (extend == true && row != null)
{
if (panel.SelectionRowAnchor.GridIndex < endItem.GridIndex)
startIndex = row.GridIndex;
else
endIndex = row.GridIndex;
}
InvalidateRows(panel, startIndex, endIndex, extend);
}
}
}
#region GetLastProcessedRow
private GridContainer GetLastProcessedRow(GridPanel panel)
{
if (panel.LastProcessedItem is GridContainer)
return ((GridContainer)panel.LastProcessedItem);
if (panel.LastProcessedItem is GridCell)
return (((GridCell)panel.LastProcessedItem).GridRow);
return (null);
}
#endregion
#endregion
#region InvalidateRows
internal void InvalidateRows(GridPanel panel, int start, int end, bool extend)
{
if (start > end)
{
int temp = start;
start = end;
end = temp;
}
start = Math.Max(0, start);
if (extend == false && panel.FrozenRowCount > 0)
InvalidateRowRange(panel, 0, panel.FirstOnScreenRowIndex);
InvalidateRowRange(panel, start, end);
}
#region InvalidateRowRange
private void InvalidateRowRange(GridPanel panel, int start, int end)
{
Rectangle t = SuperGrid.ClientRectangle;
GridContainer rs = panel.GetRowFromIndex(start);
GridContainer re = panel.GetRowFromIndex(end);
if (rs != null && re != null)
{
Rectangle rsRect = rs.Bounds;
Rectangle reRect = re.Bounds;
if (rs is GridPanel)
rsRect = GetScrollBounds(rs.ContainerBounds);
if (re is GridPanel)
reRect = GetScrollBounds(re.ContainerBounds);
Rectangle r = new Rectangle(rsRect.X, rsRect.Y,
reRect.Width, reRect.Bottom - rsRect.Y);
if (r.IntersectsWith(t) == true)
panel.InvalidateRender(r);
if (rs is GridRow)
rs.InvalidateRender();
if (re != rs && re is GridRow)
re.InvalidateRender();
}
}
#region GetScrollBounds
private Rectangle GetScrollBounds(Rectangle r)
{
r.X -= HScrollOffset;
if (IsVFrozen == false)
r.Y -= VScrollOffset;
return (r);
}
#endregion
#endregion
#endregion
#region MeasureSubItems
/// <summary>
/// MeasureSubItems
/// </summary>
/// <param name="layoutInfo"></param>
/// <param name="stateInfo"></param>
/// <param name="constraintSize"></param>
/// <returns></returns>
protected Size MeasureSubItems(
GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize)
{
Size sizeNeeded = Size.Empty;
GridPanel panel = stateInfo.GridPanel;
HasVisibleItems = false;
GridItemsCollection items = Rows;
foreach (GridElement item in items)
{
if (item.Visible == true)
{
Size size;
GridPanel ipanel = item as GridPanel;
if (ipanel != null)
{
int n = GetRowIndent(panel, ipanel);
Rectangle r = layoutInfo.ClientBounds;
r.Inflate((panel.ShowDropShadow ? -5 : 0) - n, 0);
GridLayoutInfo itemLayoutInfo = new GridLayoutInfo(layoutInfo.Graphics, r);
GridLayoutStateInfo itemStateInfo = new GridLayoutStateInfo(ipanel, 0);
item.Measure(itemLayoutInfo, itemStateInfo, Size.Empty);
size = item.Size;
size.Width += n;
size.Height += Dpi.Height(panel.LevelIndentSize.Height * 2);
}
else
{
item.Measure(layoutInfo, stateInfo, constraintSize);
size = item.Size;
}
sizeNeeded.Width = Math.Max(sizeNeeded.Width, size.Width);
sizeNeeded.Height += size.Height;
HasVisibleItems = true;
}
}
return (sizeNeeded);
}
#endregion
#region ArrangeSubItems
/// <summary>
/// ArrangeSubItems
/// </summary>
/// <param name="layoutInfo"></param>
/// <param name="stateInfo"></param>
/// <param name="layoutBounds"></param>
protected void ArrangeSubItems(GridLayoutInfo layoutInfo,
GridLayoutStateInfo stateInfo, Rectangle layoutBounds)
{
Rectangle bounds = layoutBounds;
GridPanel panel = stateInfo.GridPanel;
int indentLevel = stateInfo.IndentLevel;
GridItemsCollection items = Rows;
foreach (GridElement item in items)
{
if (item.Visible == true)
{
bounds.Height = item.Size.Height;
GridPanel ipanel = item as GridPanel;
if (ipanel != null)
{
ipanel.IndentLevel = indentLevel;
Rectangle r = layoutBounds;
r.Y = bounds.Y;
r.Height = bounds.Height + Dpi.Height(panel.LevelIndentSize.Height * 2);
ipanel.ContainerBounds = r;
int n = GetRowIndent(panel, ipanel);
r.X = layoutBounds.X + n;
r.Y += Dpi.Height(panel.LevelIndentSize.Height);
if (ipanel.ShowDropShadow == true)
r.Y--;
r.Width = ipanel.BoundsRelative.Width;
r.Height -= Dpi.Height(panel.LevelIndentSize.Height * 2);
ArrangeCheckBox(panel, ipanel, r);
stateInfo.GridPanel = ipanel;
stateInfo.IndentLevel = 0;
item.Arrange(layoutInfo, stateInfo, r);
bounds.Y += Dpi.Height(panel.LevelIndentSize.Height * 2);
}
else
{
stateInfo.GridPanel = panel;
stateInfo.IndentLevel = indentLevel;
item.Arrange(layoutInfo, stateInfo, bounds);
}
bounds.Y += item.Size.Height;
}
else
{
item.BoundsRelative = bounds;
}
}
}
#region ArrangeCheckBox
private void ArrangeCheckBox(
GridPanel panel, GridPanel ipanel, Rectangle r)
{
if (ipanel.HasCheckBox == true)
{
int k = Math.Max(
Dpi.Width(panel.CheckBoxSize.Width + 3),
Dpi.Height(panel.CheckBoxSize.Height+ 3));
r.X -= k;
r.Width = Dpi.Width(panel.CheckBoxSize.Width);
r.Y += (r.Height - Dpi.Height(panel.CheckBoxSize.Height)) / 2;
r.Height = Dpi.Height(panel.CheckBoxSize.Height);
ipanel.CheckBoxBounds = r;
}
else
{
ipanel.CheckBoxBounds = Rectangle.Empty;
}
}
#endregion
#endregion
#region GetRowIndent
/// <summary>
/// GetRowIndent
/// </summary>
/// <param name="panel"></param>
/// <param name="ipanel"></param>
/// <returns></returns>
protected int GetRowIndent(GridPanel panel, GridPanel ipanel)
{
int indentLevel = 0;
GridContainer container = ipanel.Parent as GridContainer;
if (container != null)
indentLevel = container.IndentLevel + 1;
int n = 0;
if (panel.ShowRowHeaders == true)
n += panel.RowHeaderWidthEx;
if (panel.CheckBoxes == true)
{
n += Math.Max(
Dpi.Width(ipanel.CheckBoxSize.Width + 3),
Dpi.Height(ipanel.CheckBoxSize.Height + 3));
}
if (panel.PrimaryColumn != null &&
panel.PrimaryColumn.Visible == true)
{
if (panel.ShowTreeButtons == true || panel.ShowTreeLines == true)
n += panel.TreeButtonIndent;
n += Dpi.Width(panel.LevelIndentSize.Width * indentLevel);
GridColumnCollection columns = panel.Columns;
int[] map = columns.DisplayIndexMap;
for (int i = 0; i < map.Length; i++)
{
int index = map[i];
GridColumn column = columns[index];
if (index == panel.PrimaryColumnIndex)
break;
if (column.Visible == true)
n += column.Size.Width;
}
}
else
{
n += 3;
}
return (n);
}
#endregion
#region GetParentPanel
///<summary>
/// Gets the Parent GridPanel for the item.
///</summary>
///<returns>GridPanel or null</returns>
public GridPanel GetParentPanel()
{
GridElement parent = Parent;
while (parent != null)
{
if (parent is GridPanel)
return ((GridPanel)parent);
parent = parent.Parent;
}
return (null);
}
#endregion
#region InvalidateRowHeader
internal void InvalidateRowHeader()
{
InvalidateRowHeader(this);
}
internal void InvalidateRowHeader(GridContainer row)
{
if (row != null)
{
GridPanel panel = row.GetParentPanel();
if (panel != null)
{
if (panel.ShowRowHeaders == true)
{
Rectangle bounds = panel.BoundsRelative;
if (panel.IsSubPanel == true)
bounds.X -= HScrollOffset;
bounds.Y = row.ContainerBounds.Y;
if (row.IsVFrozen == false)
bounds.Y -= VScrollOffset;
bounds.Width = panel.RowHeaderWidthEx;
bounds.Height = row.ContainerBounds.Height;
InvalidateRender(bounds);
}
}
}
}
#endregion
#region InvalidateMerge
/// <summary>
/// Invalidates the merge state of the container.
/// </summary>
public void InvalidateMerge()
{
MergeUpdateCount++;
NeedMergeLayout = true;
ResumeMerge();
InvalidateLayout();
}
#endregion
#region Mouse Handling
#region InternalMouseLeave
/// <summary>
/// Called by top-level control to pass message into the grid
/// element. To handle it override corresponding On - virtual method.
/// </summary>
/// <param name="e"></param>
internal override void InternalMouseLeave(EventArgs e)
{
GridElement mouseOverElement = _MouseOverElement;
if (mouseOverElement != null)
{
mouseOverElement.InternalMouseLeave(e);
_MouseOverElement = null;
}
base.InternalMouseLeave(e);
}
#endregion
#region InternalMouseMove
/// <summary>
/// Called by top-level control to pass message into the grid
/// element. To handle it override corresponding On - virtual method.
/// </summary>
/// <param name="e"></param>
internal override void InternalMouseMove(MouseEventArgs e)
{
GridElement element = GetElementAt(e);
if (element != _MouseOverElement)
{
GridElement mouseOverElement = _MouseOverElement;
if (mouseOverElement != null)
mouseOverElement.InternalMouseLeave(e);
if (element != null)
element.InternalMouseEnter(e);
_MouseOverElement = element;
}
if (element != null)
element.InternalMouseMove(e);
base.InternalMouseMove(e);
}
#endregion
#region InternalMouseHover
/// <summary>
/// Called by top-level control to pass message into the grid
/// element. To handle it override corresponding On - virtual method.
/// </summary>
/// <param name="e"></param>
internal override void InternalMouseHover(EventArgs e)
{
GridElement mouseOverElement = _MouseOverElement;
if (mouseOverElement != null)
mouseOverElement.InternalMouseHover(e);
base.InternalMouseHover(e);
}
#endregion
#region InternalMouseClick
/// <summary>
/// Called by top-level control to pass message into the grid
/// element. To handle it override corresponding On - virtual method.
/// </summary>
/// <param name="e"></param>
internal override void InternalMouseClick(MouseEventArgs e)
{
GridElement mouseOverElement = _MouseOverElement;
if (mouseOverElement == null)
InternalMouseMove(e);
mouseOverElement = _MouseOverElement;
if (mouseOverElement != null)
mouseOverElement.InternalMouseClick(e);
base.InternalMouseClick(e);
}
#endregion
#region InternalMouseDoubleClick
/// <summary>
/// Called by top-level control to pass message into the grid
/// element. To handle it override corresponding On - virtual method.
/// </summary>
/// <param name="e"></param>
internal override void InternalMouseDoubleClick(MouseEventArgs e)
{
GridElement mouseOverElement = _MouseOverElement;
if (mouseOverElement != null)
mouseOverElement.InternalMouseDoubleClick(e);
base.InternalMouseDoubleClick(e);
}
#endregion
#region InternalMouseDown
/// <summary>
/// Called by top-level control to pass message into the grid
/// element. To handle it override corresponding On - virtual method.
/// </summary>
/// <param name="e"></param>
internal override void InternalMouseDown(MouseEventArgs e)
{
GridElement mouseOverElement = _MouseOverElement;
if (mouseOverElement == null)
{
MouseEventArgs e2 = new
MouseEventArgs(MouseButtons.None, 0, e.X, e.Y, e.Delta);
InternalMouseMove(e2);
mouseOverElement = _MouseOverElement;
}
if (mouseOverElement != null)
mouseOverElement.InternalMouseDown(e);
base.InternalMouseDown(e);
}
#endregion
#region InternalMouseUp
/// <summary>
/// Called by top-level control to pass message into the grid
/// element. To handle it override corresponding On - virtual method.
/// </summary>
/// <param name="e"></param>
internal override void InternalMouseUp(MouseEventArgs e)
{
GridElement mouseOverElement = _MouseOverElement;
if (mouseOverElement != null)
mouseOverElement.InternalMouseUp(e);
base.InternalMouseUp(e);
}
#endregion
#endregion
#region GetElementAt
/// <summary>
/// Returns element at specified mouse coordinates.
/// </summary>
/// <param name="e">Mouse event arguments</param>
/// <returns>Reference to child element or null if no element at specified coordinates</returns>
public virtual GridElement GetElementAt(MouseEventArgs e)
{
return GetElementAt(e.X, e.Y);
}
/// <summary>
/// Returns element at specified mouse coordinates.
/// </summary>
/// <param name="x">Horizontal position</param>
/// <param name="y">Vertical position</param>
/// <returns>Reference to child element or null if no element at specified coordinates</returns>
public virtual GridElement GetElementAt(int x, int y)
{
GridPanel panel = GridPanel;
if (panel != null)
{
Rectangle t = CViewRect;
Rectangle bounds = Rectangle.Empty;
if (t.Contains(x, y) == true)
{
if (this is GridPanel || Expanded == true)
{
GridItemsCollection items = Rows;
for (int i = 0; i < items.Count; i++)
{
GridElement item = items[i];
if (item.IsVFrozen == false)
break;
if (IsElementAt(item, x, y, ref bounds) == true)
return (item);
if (bounds.Y > t.Bottom)
break;
}
for (int i = FirstOnScreenRowIndex; i < items.Count; i++)
{
GridElement item = items[i];
if (IsElementAt(item, x, y, ref bounds) == true)
{
GridGroup grp = item as GridGroup;
if (grp != null)
{
item = grp.GetElementAt(x, y);
if (item == null)
return (grp);
}
return (item);
}
if (bounds.Y > y)
break;
}
}
}
}
return (null);
}
private bool IsElementAt(
GridElement item, int x, int y, ref Rectangle bounds)
{
if (item.Visible == true)
{
bounds = item.BoundsRelative;
if (item.Visible == true)
{
if (item is GridPanel)
bounds = ((GridPanel)item).ContainerBounds;
bounds.X -= HScrollOffset;
if (item.IsVFrozen == false)
bounds.Y -= VScrollOffset;
if (bounds.Contains(x, y))
return (true);
}
}
return (false);
}
#endregion
#region InternalGetElementAt
internal GridElement InternalGetElementAt(MouseEventArgs e)
{
return (GetElementAt(e.X, e.Y));
}
internal GridElement InternalGetElementAt(int x, int y)
{
return (GetElementAt(x, y));
}
#endregion
#region CanSetActiveRow
internal bool CanSetActiveRow(bool beep)
{
return (CanSetActiveRow(GridPanel, this, beep));
}
internal bool CanSetActiveRow(
GridPanel panel, GridContainer row, bool beep)
{
if (row == null || row.AllowSelection == false)
{
if (beep == true)
{
if (SuperGrid.DoPlayingSoundEvent(panel, row, PlaySoundContext.RowActivate) == false)
SystemSounds.Beep.Play();
}
return (false);
}
if (row.IsActive == false)
{
GridContainer parent = row.Parent as GridContainer;
if (parent != null)
{
if ((uint)row.RowIndex > parent.MaxRowIndex)
return (false);
if (panel.SelectionGranularity != SelectionGranularity.Cell)
{
GridContainer cont = Parent as GridContainer;
if (cont != null)
{
CellRange cr = cont.SuspendedRange;
if (cr != null && (RowIndex < cr.RowStart || RowIndex > cr.RowEnd))
cont.ResumeMerge();
}
}
return (SuperGrid.DoRowActivatingEvent(panel, SuperGrid.ActiveRow, row) != true);
}
}
return (row.IsActive);
}
#endregion
#region FlushRow
internal virtual void FlushRow()
{
}
#endregion
#region PurgeDeletedRows
///<summary>
/// Purges all rows marked as 'deleted'. Once rows are purged
/// they cannot be restored.
///</summary>
public void PurgeDeletedRows()
{
PurgeDeletedRows(true);
}
///<summary>
/// Purges all rows marked as 'deleted'. Once rows are purged
/// they cannot be restored.
///</summary>
///<param name="includeNestedRows">Determines whether nested rows are also purged.</param>
public void PurgeDeletedRows(bool includeNestedRows)
{
GridPanel panel = GridPanel;
PurgeDeletedRowsEx(includeNestedRows, panel.IsDeleted);
}
private void PurgeDeletedRowsEx(bool includeNestedRows, bool isDeleted)
{
GridPanel panel = GridPanel;
if (SuperGrid.DoRowsPurgingEvent(this, ref includeNestedRows) == false)
{
if (panel.DeletedRowCount > 0)
{
if (panel.ActiveRow != null)
panel.SelectActiveRow = true;
}
if (panel.VirtualMode == true)
PurgeVirtualDeletedRows(panel);
else
PurgeRealDeletedRows(panel, includeNestedRows, isDeleted);
SuperGrid.DoRowsPurgedEvent(this);
}
}
#region PurgeVirtualDeletedRows
private void PurgeVirtualDeletedRows(GridPanel panel)
{
SelectedElements sec = panel.InternalDeletedRows;
if (sec != null && sec.Count > 0)
{
int offset = 0;
int topIndex = 0;
int activeIndex =
(panel.ActiveRow != null) ? panel.ActiveRow.RowIndex : -1;
int count = sec.Count;
int index = sec.LastIndex + 1;
try
{
while (sec.GetPrevIndex(ref index) == true)
{
GridRow row = panel.VirtualRows[index];
topIndex = row.RowIndex - 1;
if (row.RowIndex < activeIndex)
offset++;
panel.DataBinder.RemoveRow(row);
}
sec.Clear();
}
finally
{
panel.VirtualRowCount -= count;
panel.VirtualRows.MaxRowIndex = topIndex;
}
if (offset > 0)
{
panel.LatentActiveRowIndex = activeIndex - offset;
panel.LatentActiveContainer = this;
}
}
}
#endregion
#region PurgeRealDeletedRows
private void PurgeRealDeletedRows(
GridPanel panel, bool includeNestedRows, bool isDeleted)
{
if (panel.ActiveRow != null)
{
if (panel.ActiveRow.IsDeleted == true)
{
if (panel.VirtualMode == false)
{
GridContainer cont = panel.ActiveRow.Parent as GridContainer;
if (cont != null)
{
panel.ActiveRow = cont.GetNextLocalItem(panel.ActiveRow.RowIndex);
panel.SuperGrid.ActiveElement = panel.ActiveRow;
}
}
}
}
PurgeRealDeletedRowsEx(panel.Rows, includeNestedRows, isDeleted);
}
#region PurgeRealDeletedRowsEx
private void PurgeRealDeletedRowsEx(
GridItemsCollection rows, bool includeNestedRows, bool isDeleted)
{
for (int i = rows.Count - 1; i >= 0; i--)
{
GridContainer row = rows[i] as GridContainer;
if (row != null)
{
bool rowDeleted = (isDeleted | row.IsDeleted);
if (includeNestedRows == true)
{
if (row.Rows.Count > 0)
{
if (row is GridPanel)
row.PurgeDeletedRowsEx(true, rowDeleted);
else
row.PurgeRealDeletedRowsEx(row.Rows, true, rowDeleted);
}
}
if (rowDeleted == true)
{
row.IsDeleted = false;
rows.RemoveAt(i);
}
}
}
}
#endregion
#endregion
#region GetNextLocalItem
internal GridContainer GetNextLocalItem(int index)
{
GridPanel panel = GridPanel;
index = GetNextLocalItemIndex(index);
if (panel.VirtualMode == true)
{
if ((uint)index < panel.VirtualRowCount)
return (panel.VirtualRows[index]);
}
else
{
if ((uint) index < Rows.Count)
return (Rows[index] as GridContainer);
}
return (null);
}
#endregion
#region GetNextLocalItemIndex
private int GetNextLocalItemIndex(int index)
{
if (GridPanel.VirtualMode == true)
return (GetNextLocalVirtualItemIndex(index));
return (GetNextLocalRealItemIndex(index));
}
#region GetNextLocalRealItemIndex
internal int GetNextLocalRealItemIndex(int index)
{
if (Rows.Count > 0 && index >= 0)
{
if (index >= Rows.Count)
index = Rows.Count - 1;
for (int i = index + 1; i < Rows.Count; i++)
{
GridContainer item = Rows[i] as GridContainer;
if (item != null && item.Visible == true && item.IsDeleted == false)
return (i);
}
for (int i = index - 1; i >= 0; i--)
{
GridContainer item = Rows[i] as GridContainer;
if (item != null && item.Visible == true && item.IsDeleted == false)
return (i);
}
}
return (-1);
}
#endregion
#region GetNextLocalVirtualItemIndex
internal int GetNextLocalVirtualItemIndex(int index)
{
GridPanel panel = GridPanel;
if (panel.VirtualRowCount > 0 && index >= 0)
{
if (index >= panel.VirtualRowCount)
index = panel.VirtualRowCount - 1;
for (int i = index + 1; i < panel.VirtualRowCount; i++)
{
GridContainer item = panel.VirtualRows[i];
if (item != null && item.IsDeleted == false)
return (i);
}
for (int i = index - 1; i >= 0; i--)
{
GridContainer item = panel.VirtualRows[i];
if (item != null && item.IsDeleted == false)
return (i);
}
}
return (-1);
}
#endregion
#endregion
#endregion
#region DetachNestedRows
internal void DetachNestedRows(bool dispose)
{
DetachNestedRows(this, dispose);
}
private void DetachNestedRows(GridContainer cont, bool dispose)
{
cont.MergeScan = null;
if (dispose == true)
{
if (cont is GridPanel)
{
((GridPanel)cont).DataBinder.Dispose();
((GridPanel)cont).DataBinder = null;
}
}
if (cont is GridRow)
DetachGridRow((GridRow)cont);
if (cont.Rows.Count > 0)
{
foreach (GridContainer row in cont.Rows)
{
if (row != null)
DetachNestedRows(row, dispose);
}
}
if (SuperGrid != null)
{
if (SuperGrid.ActiveRow == cont)
SuperGrid.ActiveRow = null;
}
if (cont.GridPanel != null)
{
if (cont.GridPanel.ActiveRow == cont)
cont.GridPanel.ActiveRow = null;
}
}
private void DetachGridRow(GridRow row)
{
foreach (GridCell cell in row.Cells)
{
cell.EditControl = null;
cell.RenderControl = null;
}
//row.DataItem = null;
//row.DataItemIndex = -1;
}
#endregion
#region UpdateMergeFlags
internal void UpdateMergeFlags()
{
GridPanel panel = GridPanel;
if (panel.EnableCellMerging == true)
DisplayedCellRanges = MergeScan.GetScanItems();
else
DisplayedCellRanges = null;
_LastCellRange = null;
}
#endregion
#region GetCellRange
internal CellRange GetCellRange(GridCell cell)
{
if (DisplayedCellRanges != null)
{
int index = cell.GridPanel.Columns.GetDisplayIndex(cell.GridColumn);
if (_LastCellRange != null)
{
if (_LastCellRange.Contains(cell.RowIndex, index))
return (_LastCellRange);
}
foreach (CellRange cr in DisplayedCellRanges)
{
if (cr.Contains(cell.RowIndex, index))
{
_LastCellRange = cr;
return (cr);
}
}
}
return (null);
}
#endregion
#region SuspendMerge
///<summary>
///Temporarily suspends the merged display of the
///cells in the given CellRange.
///</summary>
///<param name="cr">CellRange to temporarily suspend</param>
public void SuspendMerge(CellRange cr)
{
if (cr != null && cr.Suspended == false)
{
ResumeMerge();
if (cr.AllowSuspend == true)
{
cr.Suspended = true;
InvalidateRender(cr.BackBounds);
}
}
_SuspendedRange = cr;
}
#endregion
#region ResumeMerge
///<summary>
///Resumes merged display of any current, temporarily
///suspended CellRange.
///</summary>
public void ResumeMerge()
{
CellRange cr = _SuspendedRange;
_SuspendedRange = null;
if (cr != null && cr.Suspended == true)
{
cr.Suspended = false;
if (cr.Modified == true)
{
UpdateCellResumeState(cr);
cr.Modified = false;
NeedMergeLayout = true;
InvalidateLayout();
}
GridPanel.SelectionUpdateCount++;
InvalidateRender(cr.BackBounds);
}
}
#region UpdateCellResumeState
private void UpdateCellResumeState(CellRange cr)
{
ushort n = MergeUpdateCount;
GridPanel panel = GridPanel;
GridColumnCollection columns = panel.Columns;
int[] map = columns.DisplayIndexMap;
for (int i = cr.RowStart; i < cr.RowEnd; i++)
{
for (int j = cr.ColumnStart; j < cr.ColumnEnd; j++)
{
GridCell cell = GetCell(i, map[j]);
if (cell != null && cell.Modified == true)
{
cell.MergeUpdateCount = --n;
cell.Modified = false;
}
}
}
}
#endregion
#endregion
#region SetMergeSelection
internal void SetMergeSelection(int startRowIndex,
int endRowIndex, int startColumnIndex, int endColumnIndex, int selected)
{
List<CellRange> cellRanges = DisplayedCellRanges;
if (cellRanges != null)
{
GridPanel panel = GridPanel;
foreach (CellRange cr in cellRanges)
{
if (cr.RowStart <= endRowIndex && cr.RowEnd > startRowIndex &&
cr.ColumnStart <= endColumnIndex && cr.ColumnEnd > startColumnIndex)
{
cr.SelectionUpdateCount = panel.SelectionUpdateCount - 1;
InvalidateRender(cr.BackBounds);
}
}
}
}
#endregion
#region ClearAllMergeSelected
internal virtual void ClearAllMergeSelected()
{
GridPanel panel = GridPanel;
List<CellRange> ranges = DisplayedCellRanges;
if (ranges != null)
{
foreach (CellRange range in ranges)
range.SelectionUpdateCount = panel.SelectionUpdateCount - 1;
}
foreach (GridContainer row in Rows)
{
if (row != null)
row.ClearAllMergeSelected();
}
}
#endregion
#region ResolveRows
/// <summary>
/// Resolves the row if marked as RowsUnresolved.
/// </summary>
public void ResolveRow()
{
ResolveRow(GridPanel, false);
}
/// <summary>
/// Resolves the row if marked as RowsUnresolved. If includeNested
/// is true, then all RowsUnresolved sub-Rows are also resolved.
/// </summary>
/// <param name="includeNested"></param>
public void ResolveRow(bool includeNested)
{
ResolveRow(GridPanel, includeNested);
}
internal void ResolveRow(GridPanel panel, bool includeNested)
{
panel.DataBinder.ResolveRow(this);
if (includeNested == true)
ResolveRows(true);
}
/// <summary>
/// Resolves all rows marked as RowsUnresolved.
/// </summary>
/// <param name="includeNested"></param>
public void ResolveRows(bool includeNested)
{
if (Rows.Count > 0)
{
GridPanel panel = GridPanel;
foreach (GridContainer row in Rows)
{
if (row != null)
row.ResolveRow(panel, includeNested);
}
}
}
#endregion
#region Style support routines
#region OnStyleChanged
private void OnStyleChanged(string property,
INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue)
{
UpdateChangeHandler(oldValue, newValue);
OnPropertyChanged(property);
}
#endregion
#region UpdateChangeHandler
private void UpdateChangeHandler(
INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue)
{
NeedsMeasured = true;
if (oldValue != null)
oldValue.PropertyChanged -= StyleChanged;
if (newValue != null)
newValue.PropertyChanged += StyleChanged;
}
#endregion
#region StyleChanged
/// <summary>
/// StyleChanged
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void StyleChanged(object sender, PropertyChangedEventArgs e)
{
if (SuperGrid != null)
SuperGrid.UpdateStyleCount();
VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType;
if (changeType == VisualChangeType.Layout)
{
NeedsMeasured = true;
InvalidateLayout();
}
else
{
if (SuperGrid != null)
InvalidateRender();
}
}
#endregion
#region GetEffectiveRowStyle
///<summary>
/// Gets the 'Effective' row style for the row. The
/// 'Effective' Style is the cached summation of SuperGrid,
/// Panel, Row, and Alternate Row styles. It is the Style
/// that is used to render each row element for the row.
///</summary>
///<returns>RowVisualStyle</returns>
public RowVisualStyle GetEffectiveRowStyle()
{
return (GetEffectiveRowStyle(this));
}
internal RowVisualStyle GetEffectiveRowStyle(GridContainer item)
{
StyleState rowState = GetRowState(item);
return (GetEffectiveRowStyle(item, rowState));
}
internal RowVisualStyle GetEffectiveRowStyle(
GridContainer item, StyleState rowState)
{
return (GetRowStateStyle(item, rowState));
}
#region GetRowState
internal StyleState GetRowState(GridContainer item)
{
StyleState rowState = StyleState.Default;
if (IsMouseOver == true)
{
Point pt = SuperGrid.PointToClient(Control.MousePosition);
Rectangle r = (item is GridPanel)
? item.ContainerBounds
: item.BoundsRelative;
r.X -= HScrollOffset;
if (item.IsVFrozen == false)
r.Y -= VScrollOffset;
Rectangle t = ViewRect;
r.Intersect(t);
if (r.Contains(pt) == true)
rowState |= StyleState.MouseOver;
}
if (item.IsSelected == true)
rowState |= StyleState.Selected;
return (rowState);
}
#endregion
#region GetRowStateStyle
private RowVisualStyle GetRowStateStyle(GridContainer item, StyleState rowState)
{
ValidateRowStyle();
switch (rowState)
{
case StyleState.MouseOver:
return (GetRowStyle(item, StyleType.MouseOver));
case StyleState.Selected:
return (GetRowStyle(item, StyleType.Selected));
case StyleState.Selected | StyleState.MouseOver:
return (GetRowStyle(item, StyleType.SelectedMouseOver));
case StyleState.ReadOnly:
return (GetRowStyle(item, StyleType.ReadOnly));
case StyleState.ReadOnly | StyleState.MouseOver:
return (GetRowStyle(item, StyleType.ReadOnlyMouseOver));
case StyleState.ReadOnly | StyleState.Selected:
return (GetRowStyle(item, StyleType.ReadOnlySelected));
case StyleState.ReadOnly | StyleState.MouseOver | StyleState.Selected:
return (GetRowStyle(item, StyleType.ReadOnlySelectedMouseOver));
default:
return (GetRowStyle(item, StyleType.Default));
}
}
#endregion
#region GetRowStyle
private RowVisualStyle GetRowStyle(GridContainer item, StyleType e)
{
if (_EffectiveRowStyles.IsValid(e) == false)
{
RowVisualStyle style = new RowVisualStyle();
StyleType[] css = style.GetApplyStyleTypes(e);
if (css != null)
{
GridPanel panel = GridPanel;
foreach (StyleType cs in css)
{
style.ApplyStyle(SuperGrid.BaseVisualStyles.RowStyles[cs]);
style.ApplyStyle(SuperGrid.DefaultVisualStyles.RowStyles[cs]);
style.ApplyStyle(GridPanel.DefaultVisualStyles.RowStyles[cs]);
style.ApplyStyle(item.RowStyles[cs]);
if (panel != null && panel.UseAlternateRowStyle == true)
{
if ((GridIndex % 2) > 0)
{
style.ApplyStyle(SuperGrid.BaseVisualStyles.AlternateRowCellStyles[cs]);
style.ApplyStyle(SuperGrid.DefaultVisualStyles.AlternateRowCellStyles[cs]);
style.ApplyStyle(GridPanel.DefaultVisualStyles.AlternateRowCellStyles[cs]);
}
}
style.ApplyStyle(item.CellStyles[cs]);
style.ApplyStyle(item.CellStyles[cs]);
}
}
SuperGrid.DoGetRowStyleEvent(this, e, ref style);
RowHeaderVisualStyle style2 = style.RowHeaderStyle;
SuperGrid.DoGetRowHeaderStyleEvent(this, e, ref style2);
if (style.Background == null || style.Background.IsEmpty == true)
style.Background = new Background(Color.White);
_EffectiveRowStyles[e] = style;
}
return (_EffectiveRowStyles[e]);
}
#endregion
#endregion
#region ValidateRowStyle
private void ValidateRowStyle()
{
if (_EffectiveRowStyles == null ||
(_StyleUpdateCount != SuperGrid.StyleUpdateCount))
{
if (_EffectiveRowStyles != null)
_EffectiveRowStyles.Dispose();
_EffectiveRowStyles = new RowVisualStyles();
_StyleUpdateCount = SuperGrid.StyleUpdateCount;
}
}
#endregion
#region InvalidateStyle
///<summary>
///Invalidates the cached Style
///definition for all defined StyleTypes
///</summary>
public virtual void InvalidateStyle()
{
if (_EffectiveRowStyles != null)
{
_EffectiveRowStyles.Dispose();
_EffectiveRowStyles = null;
}
InvalidateLayout();
}
///<summary>
///Invalidate the cached Style
///definition for the given StyleType
///</summary>
///<param name="type"></param>
public void InvalidateStyle(StyleType type)
{
if (_EffectiveRowStyles != null)
{
if (_EffectiveRowStyles[type] != null)
{
_EffectiveRowStyles[type].Dispose();
_EffectiveRowStyles[type] = null;
InvalidateLayout();
}
}
}
#endregion
#endregion
#region IsParentOf
///<summary>
/// Determines whether the row is
/// a parent row of the given container row.
///</summary>
///<param name="row"></param>
///<returns>true if the row is a parent of the given row.</returns>
public bool IsParentOf(GridContainer row)
{
if (row != null)
return (row.IsChildOf(this));
return (false);
}
#endregion
#region IsChildOf
///<summary>
/// Determines whether the row is
/// a child row of the given container row.
///</summary>
///<param name="row"></param>
///<returns>true if the row is a child of the given row.</returns>
public bool IsChildOf(GridContainer row)
{
if (row != null)
{
GridContainer parent = Parent as GridContainer;
while (parent != null)
{
if (parent == row)
return (true);
parent = parent.Parent as GridContainer;
}
}
return (false);
}
#endregion
#region GetCell
///<summary>
/// Gets the GridCell for the given row and column index
///</summary>
///<param name="rowIndex"></param>
///<param name="columnIndex"></param>
///<returns>GridCell, or null if not a valid cell</returns>
public GridCell GetCell(int rowIndex, int columnIndex)
{
GridPanel panel = GridPanel;
if (panel != null)
{
GridRow row = null;
if (panel.VirtualMode == true)
{
if ((uint)rowIndex < panel.VirtualRowCount)
row = panel.VirtualRows[rowIndex];
}
else
{
if ((uint) rowIndex < Rows.Count)
row = Rows[rowIndex] as GridRow;
}
if (row != null && columnIndex < row.Cells.Count)
return (row.Cells[columnIndex]);
}
return (null);
}
#endregion
#region Dispose
/// <summary>
/// Dispose
/// </summary>
public virtual void Dispose()
{
if (_EffectiveRowStyles != null)
{
_EffectiveRowStyles.Dispose();
_EffectiveRowStyles = null;
}
CellStyles = null;
RowStyles = null;
if (Rows != null && Rows.Count > 0)
{
foreach (GridElement item in Rows)
{
GridContainer row = item as GridContainer;
if (row != null)
row.Dispose();
}
}
}
#endregion
#region ContainerStates
[Flags]
private enum Cs
{
Checked = (1 << 0),
Deleted = (1 << 1),
Expanded = (1 << 2),
HasVisibleItems = (1 << 3),
ReadOnly = (1 << 4),
RowsUnresolved = (1 << 5),
Selected = (1 << 6),
ShowCheckBox = (1 << 7),
ShowTreeButton = (1 << 8),
ExpandedVisible = (1 << 9),
}
#endregion
}
#region enums
#region ExpandSource
///<summary>
/// Operation source resulting in the Expand call
///</summary>
public enum ExpandSource
{
///<summary>
/// Expand operation
///</summary>
Expand,
///<summary>
/// ExpandAll operation
///</summary>
ExpandAll,
}
#endregion
#endregion
}