5470 lines
156 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using DevComponents.DotNetBar.SuperGrid.Primitives;
using DevComponents.DotNetBar.SuperGrid.Style;
namespace DevComponents.DotNetBar.SuperGrid
{
/// <summary>
/// Represents a grid row consisting of one or more grid cells.
/// </summary>
public class GridRow : GridContainer
{
#region Constants
private const int SeparatorHeight = 2;
#endregion
#region Static data
private static bool _dragSelection;
private static bool _dragStarted;
private static FloatWindow _separatorFw;
private static FloatWindow _headerFw;
#endregion
#region Private variables
private readonly GridCellCollection _Cells;
private int _AnchorIndex;
private int _RowHeight = -1;
private int _PreDetailRowHeight = -1;
private int _PostDetailRowHeight = -1;
private int _EffectivePreDetailRowHeight;
private int _EffectivePostDetailRowHeight;
private Rs _States;
private RowArea _HitArea;
private GridContainer _HitItem;
private RowArea _LastArea;
private RowArea _MouseDownHitArea;
private GridContainer _MouseDownHitRow;
private Point _MouseDownPoint;
private int _MouseDownDelta;
private GridContainer _SeparatorRow;
private string _InfoText;
private Rectangle _InfoImageBounds;
private Rectangle _ExpandButtonBounds;
private object _DataItem;
private int _DataItemIndex = -1;
private GridCell _EmptyRenderCell;
private GridCell _EmptySelectionCell;
private ushort _ArrangeLayoutCount;
private ushort _MeasureCount;
private Size _RowHeaderSize;
private ushort _StyleUpdateCount;
private CellVisualStyles _EffectiveCellStyles;
private CellMergeMode _CellMergeMode = CellMergeMode.NotSet;
private GridPanel _AllocPanel;
#endregion
#region Constructors
/// <summary>
/// Creates a new GridRow
/// </summary>
public GridRow()
{
SetState(Rs.AllowEdit, true);
SetState(Rs.Visible, true);
_Cells = new GridCellCollection();
_Cells.CollectionChanged += CellsCollectionChanged;
}
/// <summary>
/// Creates a new GridRow
/// </summary>
/// <param name="text"></param>
public GridRow(string text)
: this()
{
GridCell cell = new GridCell();
cell.Value = text;
_Cells.Add(cell);
}
/// <summary>
/// Creates a new GridRow
/// </summary>
/// <param name="cells"></param>
public GridRow(IEnumerable<GridCell> cells)
: this()
{
foreach (GridCell cell in cells)
_Cells.Add(cell);
}
/// <summary>
/// Creates a new GridRow
/// </summary>
/// <param name="values"></param>
public GridRow(IEnumerable<object> values)
: this()
{
foreach (object o in values)
_Cells.Add(new GridCell(o));
}
/// <summary>
/// Creates a new GridRow
/// </summary>
/// <param name="values"></param>
public GridRow(params object[] values)
: this()
{
foreach (object o in values)
_Cells.Add(new GridCell(o));
}
#endregion
#region Public properties
#region AllowEdit
/// <summary>
/// Gets or sets whether the row cells can be edited by the user.
/// </summary>
[DefaultValue(true), Category("Behavior")]
[Description("Indicates whether the row cells can be edited by the user.")]
public bool AllowEdit
{
get { return (TestState(Rs.AllowEdit)); }
set
{
if (value != AllowEdit)
{
SetState(Rs.AllowEdit, value);
OnPropertyChanged("AllowEdit");
}
}
}
#endregion
#region Bounds
///<summary>
/// Gets the scroll adjusted bounds of the row
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override Rectangle Bounds
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
Rectangle r = BoundsRelative;
if (panel.IsSubPanel == true)
r.X -= HScrollOffset;
if (IsVFrozen == false)
r.Y -= VScrollOffset;
r.Height = FixedRowHeight;
return (r);
}
return (Rectangle.Empty);
}
}
#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 override bool Checked
{
get { return (base.Checked); }
set
{
if (Checked != value)
{
base.Checked = value;
RowCheckChanged = true;
}
}
}
#endregion
#region Cells
/// <summary>
/// Gets a reference to the Cells collection. Cells in the
/// Cells member are not allocated by default, but are only
/// done so if the cell Values are provided to the GridRow
/// constructor at row allocation time. Row cells can be allocated
/// later, and assigned (or added) to the current Cells collection.
/// Cells are sequentially allocated, thus you can not allocate and
/// assign Cell 10 without also having allocated and assigned cells 0 - 9.
/// </summary>
[DefaultValue(null), Category("Data")]
[Description("Indicates a reference to the Cells collection.")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public GridCellCollection Cells
{
get { return (_Cells); }
}
#endregion
#region DataItem
///<summary>
/// Gets the object to which the row is bound.
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public object DataItem
{
get { return (_DataItem); }
internal set { _DataItem = value; }
}
#endregion
#region EditorDirty
///<summary>
/// Gets or sets whether the value being edited has changed.
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool EditorDirty
{
get { return (TestState(Rs.EditorDirty)); }
set
{
if (EditorDirty != value)
{
SetState(Rs.EditorDirty, value);
GridPanel panel = GridPanel;
if (panel != null)
{
if (value == false)
{
SetState(Rs.RowDirty, true);
SetState(Rs.RowNeedsStored, true);
}
else
{
ProcessNewRowChange(panel);
}
InvalidateRowHeader();
}
}
}
}
#endregion
#region EffectivePreDetailRowHeight
///<summary>
/// Gets the effective height of the "pre detail" portion of the
/// row (the area at the bottom of the row).
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int EffectivePreDetailRowHeight
{
get { return (_EffectivePreDetailRowHeight); }
}
#endregion
#region EffectivePostDetailRowHeight
///<summary>
/// Gets the effective height of the "post detail" portion of the
/// row (the area at the bottom of the row).
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int EffectivePostDetailRowHeight
{
get { return (_EffectivePostDetailRowHeight); }
}
#endregion
#region FirstFrozenCell
/// <summary>
/// Gets a reference to the first Frozen cell
/// or null if there is none.
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridCell FirstFrozenCell
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
GridColumn column = panel.FirstFrozenColumn;
if (column != null)
{
int index = column.ColumnIndex;
if (index < _Cells.Count)
return (_Cells[index]);
}
}
return (null);
}
}
#endregion
#region FirstOnScreenCell
/// <summary>
/// Gets a reference to the first on-screen cell
/// (after frozen columns) or null if there is none.
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridCell FirstOnScreenCell
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
GridColumn column = panel.FirstOnScreenColumn;
if (column != null)
{
int index = column.ColumnIndex;
if (index < _Cells.Count)
return (_Cells[index]);
}
}
return (null);
}
}
#endregion
#region FirstSelectableCell
/// <summary>
/// Gets a reference to the first selectable cell
/// or null if there is none defined.
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridCell FirstSelectableCell
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
for (int i = 0; i < panel.Columns.Count; i++)
{
GridColumn column = panel.Columns[i];
if (column.Visible == true && column.AllowSelection == true)
{
GridCell cell =
GetCell(i, panel.AllowEmptyCellSelection);
if (cell != null)
{
if (cell.AllowSelection == true)
return (cell);
}
}
}
}
return (null);
}
}
#endregion
#region FirstVisibleCell
/// <summary>
/// Gets a reference to the first visible cell
/// or null if there is none defined.
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridCell FirstVisibleCell
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
GridColumn column = panel.Columns.FirstVisibleColumn;
if (column != null)
{
int index = column.ColumnIndex;
GridCell cell =
GetCell(index, panel.AllowEmptyCellSelection);
if (cell != null)
return (cell);
}
}
return (null);
}
}
#endregion
#region Indexer (Column)
/// <summary>
/// Gets or sets Cell item at the given Column
/// </summary>
/// <param name="column">Column containing the cell</param>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridCell this[GridColumn column]
{
get { return (this[column.ColumnIndex]); }
}
#endregion
#region Indexer (int)
/// <summary>
/// Gets or sets Cell item at the given Column
/// </summary>
/// <param name="columnIndex">Column containing the cell</param>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridCell this[int columnIndex]
{
get
{
if (columnIndex < Cells.Count)
return (Cells[columnIndex]);
return (null);
}
}
#endregion
#region Indexer (string)
/// <summary>
/// Gets or sets Cell item at ColumnName index
/// </summary>
/// <param name="columnName">Name of Column containing the cell</param>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridCell this[string columnName]
{
get { return (FindCell(columnName)); }
}
#endregion
#region InfoImageBounds
///<summary>
/// Gets the bounds of the InfoImage
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Rectangle InfoImageBounds
{
get { return (_InfoImageBounds); }
internal set { _InfoImageBounds = value; }
}
#endregion
#region InfoText
///<summary>
/// Gets or sets the informational text associated with
/// the row. If the InfoText is non-null, then the rows
/// associated InfoImage is displayed in the RowHeader, with
/// the InfoText being displayed as the ToolTip for the InfoImage.
///</summary>
[DefaultValue(null), Category("Appearance")]
[Description("Gets or sets the informational text associated with the row. If the InfoText is non-null, then the rows associated InfoImage is displayed in the RowHeader, with the InfoText being displayed as the ToolTip for the InfoImage.")]
public string InfoText
{
get { return (_InfoText); }
set
{
if (_InfoText != value)
{
_InfoText = value;
OnPropertyChangedEx("InfoText", VisualChangeType.Render);
InvalidateRowHeader();
}
}
}
#endregion
#region IsDeleted
///<summary>
/// Gets or sets whether the row has been marked as deleted.
///</summary>
[DefaultValue(false), Category("Appearance")]
[Description("Indicates whether the row has been marked as deleted.")]
public override bool IsDeleted
{
get { return (base.IsDeleted); }
set
{
if (base.IsDeleted != value)
{
SetState(Rs.RowDirty, true);
SetState(Rs.RowNeedsStored, true);
base.IsDeleted = value;
}
}
}
#endregion
#region IsDetailRow
///<summary>
/// Gets whether the row is marked as a Group Detail row.
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsDetailRow
{
get { return (TestState(Rs.DetailRow)); }
internal set { SetState(Rs.DetailRow, value); }
}
#endregion
#region IsInsertRow
///<summary>
/// Gets whether the row is the Insert Row.
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsInsertRow
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (IsDesignerHosted == true)
return (false);
if (panel.ShowInsertRow == true)
{
if (panel.VirtualMode == true)
{
if (GridIndex == panel.VirtualRowCountEx - 1)
return (true);
}
else
{
if (RowIndex == panel.Rows.Count - 1)
return (true);
}
}
}
return (false);
}
}
#endregion
#region IsTempInsertRow
///<summary>
/// Gets whether the row is a temporary insert Row (created via editing the Insert Row)
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsTempInsertRow
{
get { return (TestState(Rs.TempInsertRow)); }
internal set { SetState(Rs.TempInsertRow, value); }
}
#endregion
#region LastFrozenCell
/// <summary>
/// Gets a reference to the last Frozen cell
/// or null if there is none.
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridCell LastFrozenCell
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
GridColumn column = panel.LastFrozenColumn;
if (column != null)
{
int index = column.ColumnIndex;
if (index < _Cells.Count)
return (_Cells[index]);
}
}
return (null);
}
}
#endregion
#region LastOnScreenCell
/// <summary>
/// Gets a reference to the last on-screen cell
/// or null if there is none.
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridCell LastOnScreenCell
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
GridColumn column = panel.LastOnScreenColumn;
if (column != null)
{
int index = column.ColumnIndex;
if (index < _Cells.Count)
return (_Cells[index]);
}
}
return (null);
}
}
#endregion
#region LastSelectableCell
/// <summary>
/// Gets a reference to the last selectable cell
/// or null if there is none defined.
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridCell LastSelectableCell
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
for (int i = panel.Columns.Count - 1; i >= 0; i--)
{
GridColumn column = panel.Columns[i];
if (column.Visible == true && column.AllowSelection == true)
{
GridCell cell = GetCell(i, panel.AllowEmptyCellSelection);
if (cell != null)
{
if (cell.AllowSelection == true)
return (cell);
}
}
}
}
return (null);
}
}
#endregion
#region LastVisibleCell
/// <summary>
/// Gets a reference to the last visible cell
/// or null if there is none defined.
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridCell LastVisibleCell
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
GridColumn column = panel.Columns.LastVisibleColumn;
if (column != null)
{
int index = column.ColumnIndex;
if (index < _Cells.Count)
return (_Cells[index]);
}
}
return (null);
}
}
#endregion
#region RowDirty
///<summary>
/// Gets or sets whether the row state has changed.
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool RowDirty
{
get { return (TestState(Rs.RowDirty)); }
set
{
if (RowDirty != value)
{
SetState(Rs.RowDirty, value);
InvalidateRowHeader();
}
}
}
#endregion
#region IsRowFilteredOut
///<summary>
/// Gets whether the row has been filtered out.
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsRowFilteredOut
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
panel.UpdateDataFiltering();
return (panel.IsFiltered == true &&
RowFilteredOut == true);
}
return (false);
}
set
{
RowFilteredOut = value;
}
}
#endregion
#region RowHeight
///<summary>
/// Gets or sets the height of the row (0 denotes AutoSize, -1 denotes NotSet).
///</summary>
[DefaultValue(-1), Category("Sizing")]
[Description("Indicates the height of the row (0 denotes AutoSize, -1 denotes NotSet).")]
public int RowHeight
{
get { return (_RowHeight); }
set
{
if (_RowHeight != value)
{
_RowHeight = (value < 0) ? -1 : value;
NeedsMeasured = true;
OnPropertyChangedEx("RowHeight", VisualChangeType.Layout);
}
}
}
#endregion
#region PostDetailRowHeight
///<summary>
/// Gets or sets the height of the "post detail" portion of the
/// row (the area at the bottom of the row). -1 denotes NotSet.
///</summary>
[DefaultValue(-1), Category("Sizing")]
[Description("Indicates the height of the 'post detail' portion of the row (the area at the bottom of the row). -1 denotes NotSet.")]
public int PostDetailRowHeight
{
get { return (_PostDetailRowHeight); }
set
{
if (_PostDetailRowHeight != value)
{
_PostDetailRowHeight = (value < 0) ? -1 : value;
NeedsMeasured = true;
OnPropertyChangedEx("PostDetailRowHeight", VisualChangeType.Layout);
}
}
}
#endregion
#region RowPreDetailHeight
///<summary>
/// Gets or sets the height of the "pre detail" portion of the
/// row (the area at the bottom of the row). -1 denotes NotSet.
///</summary>
[DefaultValue(-1), Category("Sizing")]
[Description("Indicates the height of the 'pre detail' portion of the row (the area at the bottom of the row). -1 denotes NotSet.")]
public int RowPreDetailHeight
{
get { return (_PreDetailRowHeight); }
set
{
if (_PreDetailRowHeight != value)
{
_PreDetailRowHeight = (value < 0) ? -1 : value;
NeedsMeasured = true;
OnPropertyChangedEx("RowPreDetailHeight", VisualChangeType.Layout);
}
}
}
#endregion
#region SelectedCells
///<summary>
/// Gets an array of the currently Selected Cells.
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public GridCell[] SelectedCells
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (IsSelected == true)
{
GridCell[] cells = new GridCell[Cells.Count];
for (int i = 0; i < Cells.Count; i++)
{
if (Cells[i].AllowSelection == true)
cells[i] = Cells[i];
}
return (cells);
}
}
return (null);
}
}
#endregion
#region Visible
/// <summary>
/// Gets or sets whether the row is visible.
/// </summary>
[DefaultValue(true), Category("Appearance")]
[Description("Indicates whether the row is visible.")]
public override bool Visible
{
get { return (base.Visible); }
set
{
SetState(Rs.Visible, value);
if (RowFilteredOut == true)
value = false;
if (base.Visible != value)
{
base.Visible = value;
GridPanel panel = GridPanel;
if (panel != null)
{
int index = GridIndex;
if (index < panel.Rows.Count)
{
int count = GetVisibleItemCount() + 1;
panel.ExpandSelectedAtIndex(index, count, value);
}
if (value == false)
{
if (panel.ActiveRow == this)
{
GridContainer row = GetNextActiveRow(panel, GridIndex);
panel.SetActiveRow(row, true);
panel.LastProcessedItem = row;
}
}
panel.UpdateRowCountEx();
}
}
}
}
private GridContainer GetNextActiveRow(GridPanel panel, int index)
{
GridContainer row = panel.GetRowFromIndex(index);
while (row != null)
{
if (panel.CanSetActiveRow(panel, row, false) == true)
return (row);
row = row.NextVisibleRow;
}
row = panel.GetRowFromIndex(index - 1);
while (row != null)
{
if (panel.CanSetActiveRow(false) == true)
return (row);
row = row.PrevVisibleRow;
}
return (null);
}
#endregion
#region WhiteSpaceBounds
///<summary>
/// Gets the row WhiteSpace Bounds (the area
/// past the end of the last defined column).
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Rectangle WhiteSpaceBounds
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
GridColumn lastcol = panel.Columns.LastVisibleColumn;
if (lastcol != null)
{
Rectangle colBounds = lastcol.Bounds;
Rectangle panelBounds = panel.Bounds;
if (panel.IsSubPanel == true)
panelBounds.Width -= 5;
if (colBounds.Right < panelBounds.Right)
{
int left = colBounds.Right;
int right = panelBounds.Right;
if (left < right)
{
Rectangle rowBounds = Bounds;
rowBounds.X = left;
rowBounds.Width = right - left;
return (rowBounds);
}
}
}
}
return (Rectangle.Empty);
}
}
#endregion
#endregion
#region Internal properties
#region AllocPanel
internal GridPanel AllocPanel
{
get { return (_AllocPanel); }
set { _AllocPanel = value; }
}
#endregion
#region ArrangeLayoutCount
internal ushort ArrangeLayoutCount
{
get { return (_ArrangeLayoutCount); }
set { _ArrangeLayoutCount = value; }
}
#endregion
#region CanModify
internal override bool CanModify
{
get
{
if (AllowEdit == false)
return (false);
return (base.CanModify);
}
}
#endregion
#region DataItemIndex
internal int DataItemIndex
{
get
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (panel.VirtualMode == true)
return (RowIndex);
}
return (_DataItemIndex);
}
set { _DataItemIndex = value; }
}
#endregion
#region DragSelection
internal bool DragSelection
{
get { return (_dragSelection); }
set { _dragSelection = value; }
}
#endregion
#region ExpandButtonBounds
internal Rectangle ExpandButtonBounds
{
get { return (_ExpandButtonBounds); }
set { _ExpandButtonBounds = value; }
}
#endregion
#region IsReordering
internal bool IsReordering
{
get { return (TestState(Rs.Reordering)); }
set { SetState(Rs.Reordering, value); }
}
#endregion
#region IsResizing
internal bool IsResizing
{
get { return (TestState(Rs.Resizing)); }
set { SetState(Rs.Resizing, value); }
}
#endregion
#region IsControlDown
internal bool IsControlDown
{
get { return (TestState(Rs.ControlDown)); }
set { SetState(Rs.ControlDown, value); }
}
#endregion
#region Loading
internal bool Loading
{
get { return (TestState(Rs.Loading)); }
set { SetState(Rs.Loading, value); }
}
#endregion
#region MeasureCount
internal ushort MeasureCount
{
get { return (_MeasureCount); }
}
#endregion
#region NeedsMeasured
internal override bool NeedsMeasured
{
get { return (base.NeedsMeasured); }
set
{
if (value == true)
_MeasureCount++;
base.NeedsMeasured = value;
}
}
#endregion
#region RowCheckChanged
///<summary>
/// RowCheckChanged
///</summary>
internal bool RowCheckChanged
{
get { return (TestState(Rs.RowCheckChanged)); }
set { SetState(Rs.RowCheckChanged, value); }
}
#endregion
#region RowFilteredOut
internal bool RowFilteredOut
{
get { return (TestState(Rs.RowFilteredOut)); }
set
{
SetState(Rs.RowFilteredOut, value);
base.Visible = (value != true) && TestState(Rs.Visible);
InvalidateMerge();
}
}
#endregion
#region RowNeedsGrouped
///<summary>
/// RowNeedsGrouped
///</summary>
internal bool RowNeedsGrouped
{
get { return (TestState(Rs.RowNeedsGrouped)); }
set { SetState(Rs.RowNeedsGrouped, value); }
}
#endregion
#region RowNeedsSorted
///<summary>
/// RowNeedsSorted
///</summary>
internal bool RowNeedsSorted
{
get { return (TestState(Rs.RowNeedsSorted)); }
set { SetState(Rs.RowNeedsSorted, value); }
}
#endregion
#region RowNeedsStored
///<summary>
/// RowNeedsStored
///</summary>
internal bool RowNeedsStored
{
get { return (TestState(Rs.RowNeedsStored)); }
set { SetState(Rs.RowNeedsStored, value); }
}
#endregion
#region IsSeparatorAtBottom
internal bool IsSeparatorAtBottom
{
get { return (TestState(Rs.SeparatorAtBottom)); }
set { SetState(Rs.SeparatorAtBottom, value); }
}
#endregion
#endregion
#region TestState
private bool TestState(Rs state)
{
return ((_States & state) == state);
}
#endregion
#region SetState
private void SetState(Rs state, bool value)
{
if (value == true)
_States |= state;
else
_States &= ~state;
}
#endregion
#region MeasureOverride
#region MeasureOverride
/// <summary>
/// Performs the layout of the item
/// and sets the Size property to size that item will take.
/// </summary>
/// <param name="layoutInfo">Layout information.</param>
/// <param name="stateInfo"></param>
/// <param name="constraintSize"></param>
protected override void MeasureOverride(
GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize)
{
GridPanel panel = stateInfo.GridPanel;
Size sizeNeeded = Size.Empty;
if (panel.ShowRowHeaders == true)
sizeNeeded = MeasureRowHeader(panel);
Size size = Size.Empty;
if (panel.VirtualMode == true)
{
size.Width = GetColumnsWidth(stateInfo);
size.Height = Dpi.Height(panel.VirtualRowHeight);
}
else
{
int rowHeight = GetRowHeight();
if (rowHeight == 0)
{
size = MeasureCells(layoutInfo, stateInfo);
}
else
{
size.Width = GetColumnsWidth(stateInfo);
size.Height = rowHeight;
}
}
sizeNeeded.Width += size.Width;
sizeNeeded.Height = Math.Max(size.Height, sizeNeeded.Height);
sizeNeeded.Height = Math.Max(sizeNeeded.Height, Dpi.Height(panel.MinRowHeight));
sizeNeeded.Height = Math.Min(sizeNeeded.Height, Dpi.Height(panel.MaxRowHeight));
_EffectivePreDetailRowHeight = GetRowPreDetailHeight();
_EffectivePostDetailRowHeight = GetRowPostDetailHeight();
SuperGrid.DoRowGetDetailHeightEvent(this, layoutInfo,
sizeNeeded, ref _EffectivePreDetailRowHeight, ref _EffectivePostDetailRowHeight);
_EffectivePreDetailRowHeight = Dpi.Height(_EffectivePreDetailRowHeight);
_EffectivePostDetailRowHeight = Dpi.Height(_EffectivePostDetailRowHeight);
sizeNeeded.Height += (_EffectivePreDetailRowHeight + _EffectivePostDetailRowHeight);
FixedRowHeight = sizeNeeded.Height;
HasVisibleItems = false;
if (Rows != null && Rows.Count > 0)
{
if (Expanded == true)
{
GridLayoutStateInfo itemStateInfo = new
GridLayoutStateInfo(panel, stateInfo.IndentLevel + 1);
size = MeasureSubItems(layoutInfo, itemStateInfo, constraintSize);
sizeNeeded.Width = Math.Max(size.Width, sizeNeeded.Width);
sizeNeeded.Height += size.Height;
}
else
{
HasVisibleItems = AnyVisibleItems();
}
}
Size = sizeNeeded;
}
#region GetColumnsWidth
private int GetColumnsWidth(GridLayoutStateInfo stateInfo)
{
int width = 0;
GridColumnCollection columns = stateInfo.GridPanel.Columns;
foreach (GridColumn column in columns)
{
if (column.Visible == true)
width += column.Size.Width;
}
return (width);
}
#endregion
#region MeasureRowHeader
private Size MeasureRowHeader(GridPanel panel)
{
Size size = Dpi.Size(panel.RowHeaderSize);
if (size.IsEmpty == true)
{
if (NeedsMeasured == true)
{
size.Width = panel.RowHeaderWidthEx;
if (GetRowHeight() == 0)
{
RowHeaderVisualStyle style = GetEffectiveRowStyle().RowHeaderStyle;
if (panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Image ||
panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Both)
{
MaxImageHeight(style.GetActiveRowImage(panel), ref size);
}
if (panel.ShowEditingImage == true)
MaxImageHeight(style.GetEditingRowImage(panel), ref size);
if (panel.ShowInsertRow == true)
MaxImageHeight(panel.GetInsertRowImage(), ref size);
}
_RowHeaderSize = size;
}
size = _RowHeaderSize;
}
return (size);
}
private void MaxImageHeight(Image image, ref Size size)
{
if (image != null)
size.Height = Math.Max(size.Height, image.Height + 6);
}
#endregion
#region AnyVisibleItems
internal bool AnyVisibleItems()
{
GridItemsCollection items = Rows;
foreach (GridElement item in items)
{
if (item.Visible == true)
return (true);
}
return (false);
}
#endregion
#endregion
#region MeasureCells
private Size MeasureCells(GridLayoutInfo layoutInfo,
GridLayoutStateInfo stateInfo)
{
GridPanel panel = stateInfo.GridPanel;
Size sizeNeeded = Size.Empty;
int rowHeight = GetRowHeight();
GridCellCollection cells = _Cells;
foreach (GridCell cell in cells)
{
if (cell.ColumnIndex < panel.Columns.Count)
{
GridColumn column = panel.Columns[cell.ColumnIndex];
if (column.Visible == true)
{
ColumnAutoSizeMode mode = column.GetAutoSizeMode();
Size size = column.BoundsRelative.Size;
if (column.IsPrimaryColumn == true)
{
size.Width -= stateInfo.IndentLevel * Dpi.Width(panel.LevelIndentSize.Width);
if (panel.ShowTreeButtons == true || panel.ShowTreeLines == true)
size.Width -= panel.TreeButtonIndent;
if (panel.CheckBoxes == true)
size.Width -= Dpi.Width(panel.CheckBoxSize.Width + 6);
}
if ((rowHeight == 0 && mode == ColumnAutoSizeMode.Fill) ||
cell.NeedsMeasured == true || column.NeedsMeasured == true ||
NeedsMeasured == true || panel.NeedsMeasured == true)
{
cell.Measure(layoutInfo, stateInfo, size);
}
size.Height = cell.MeasuredSize.Height;
if (mode != ColumnAutoSizeMode.None) // Was Fill
size.Width = cell.MeasuredSize.Width;
if (rowHeight != 0)
size.Height = rowHeight;
cell.Size = size;
sizeNeeded.Width += cell.Size.Width;
sizeNeeded.Height = Math.Max(cell.Size.Height, sizeNeeded.Height);
}
}
}
if (sizeNeeded.IsEmpty == true)
sizeNeeded = new Size(Dpi.Width100, rowHeight);
return (sizeNeeded);
}
#endregion
#endregion
#region ArrangeOverride
#region ArrangeOverride
/// <summary>
/// Performs the arrange pass layout of the
/// item when final position and size of the item has been set.
/// </summary>
/// <param name="layoutInfo">Layout information.</param>
/// <param name="stateInfo"></param>
/// <param name="layoutBounds">Layout bounds</param>
protected override void ArrangeOverride(
GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Rectangle layoutBounds)
{
ContainerBounds = layoutBounds;
Rectangle bounds = layoutBounds;
bounds.Height = FixedRowHeight;
GridPanel panel = stateInfo.GridPanel;
IndentLevel = stateInfo.IndentLevel;
if (panel.ShowRowHeaders == true)
bounds.X += panel.RowHeaderWidthEx;
ArrangeCells(layoutInfo, stateInfo, bounds);
if (Rows != null && Expanded == true)
{
bounds = layoutBounds;
int n = FixedRowHeight;
bounds.Y += n;
bounds.Height -= n;
GridLayoutStateInfo itemStateInfo =
new GridLayoutStateInfo(panel, IndentLevel + 1);
ArrangeSubItems(layoutInfo, itemStateInfo, bounds);
}
ArrangeLayoutCount = SuperGrid.ArrangeLayoutCount;
}
#endregion
#region ArrangeCells
private void ArrangeCells(GridLayoutInfo layoutInfo,
GridLayoutStateInfo stateInfo, Rectangle bounds)
{
GridPanel panel = stateInfo.GridPanel;
if (panel.Columns.Count > 0)
{
int indentLevel = stateInfo.IndentLevel;
GridCellCollection cells = _Cells;
GridColumnCollection columns = panel.Columns;
int j = 0;
int[] map = columns.DisplayIndexMap;
for (int i = 0; i < map.Length; i++)
{
int index = map[i];
GridColumn column = columns[index];
if (column.Visible == true)
{
if (index < cells.Count)
{
GridCell cell = cells[index];
if (panel.GroupColumns.Count > 0)
{
cell.IndentLevel = (j == 0 ? indentLevel : 0);
}
else
{
cell.IndentLevel =
(panel.PrimaryColumnIndex == index) ? indentLevel : 0;
}
bounds.Width = column.Size.Width;
cell.Arrange(layoutInfo, stateInfo, bounds);
}
j++;
bounds.X += column.Size.Width;
}
}
}
}
#endregion
#endregion
#region RenderOverride
/// <summary>
/// Performs drawing of the item and its children
/// </summary>
/// <param name="renderInfo">Holds contextual rendering information.</param>
protected override void RenderOverride(GridRenderInfo renderInfo)
{
GridPanel panel = GridPanel;
if (panel != null)
{
Rectangle bounds = Bounds;
GridPanelVisualStyle pstyle = panel.GetEffectiveStyle();
if (bounds.IntersectsWith(renderInfo.ClipRectangle))
RenderRow(renderInfo, panel, pstyle, bounds);
if (Rows != null && Rows.Count > 0 && Expanded == true)
{
UpdateMergeFlags();
RenderSubItems(renderInfo, panel, pstyle, panel.IsSubPanel, IsVFrozen);
}
RenderDesignerElement(renderInfo, bounds);
}
}
#region RenderRow
private void RenderRow(GridRenderInfo renderInfo,
GridPanel panel, GridPanelVisualStyle pstyle, Rectangle r)
{
Graphics g = renderInfo.Graphics;
bool cancelled = SuperGrid.DoPreRenderRowEvent(g, this, RenderParts.Background, r);
if (HScrollOffset == 0 || panel.Parent != null || panel.FrozenColumnCount <= 0)
RenderAllColumns(renderInfo, panel);
else
RenderScrollableColumns(renderInfo, panel);
if (cancelled == false)
SuperGrid.DoPostRenderRowEvent(g, this, RenderParts.Background, r);
if (panel.ShowRowHeaders == true)
RenderRowHeader(renderInfo, panel, this, pstyle, r);
Rectangle w = WhiteSpaceBounds;
if (w.Width > 0 && w.Height > 0)
RenderRowWhitespace(renderInfo, panel, pstyle, w);
if (panel.FocusCuesEnabled == true && SuperGrid.ActiveElement == this)
{
if (panel.EnableCellMerging == false)
RenderFocusRect(g, r);
}
}
#region RenderAllColumns
private void RenderAllColumns(
GridRenderInfo renderInfo, GridPanel panel)
{
GridCellCollection cells = _Cells;
GridColumnCollection columns = panel.Columns;
bool isVFrozen = IsVFrozen;
int[] map = columns.DisplayIndexMap;
for (int i = 0; i < map.Length; i++)
{
int index = map[i];
GridColumn column = columns[index];
if (column.Visible == true)
{
if (column.Bounds.IntersectsWith(renderInfo.ClipRectangle))
{
if (index < cells.Count)
{
if (RenderCell(renderInfo, cells[index], false, isVFrozen) == false)
break;
}
else
{
RenderEmptyCell(renderInfo, column, false, isVFrozen);
}
}
}
}
}
#endregion
#region RenderScrollableColumns
private void RenderScrollableColumns(
GridRenderInfo renderInfo, GridPanel panel)
{
Graphics g = renderInfo.Graphics;
GridCellCollection cells = _Cells;
GridColumnCollection columns = panel.Columns;
Region saveClip = null;
bool isVFrozen = IsVFrozen;
int[] map = columns.DisplayIndexMap;
GridColumn lastCol = null;
for (int i = 0; i < map.Length; i++)
{
int index = map[i];
GridColumn column = columns[index];
if (column.Visible == true)
{
bool isHFrozen = column.IsHFrozen;
if (saveClip == null && isHFrozen == false)
saveClip = SetScrollableClip(g, lastCol);
if (index < cells.Count)
{
if (RenderCell(renderInfo, cells[index], isHFrozen, isVFrozen) == false)
break;
}
else
{
if (RenderEmptyCell(renderInfo, column, isHFrozen, isVFrozen) == false)
break;
}
lastCol = column;
}
}
if (saveClip != null)
g.Clip = saveClip;
}
#region SetScrollableClip
private Region SetScrollableClip(Graphics g, GridColumn column)
{
Region clip = g.Clip;
if (column != null)
{
Rectangle r = SuperGrid.ViewRectEx;
r.X = column.Bounds.Right;
g.SetClip(r);
}
return (clip);
}
#endregion
#endregion
#region RenderCell
private bool RenderCell(GridRenderInfo renderInfo,
GridCell cell, bool isHFrozen, bool isVFrozen)
{
Rectangle bounds = cell.BoundsRelative;
if (isHFrozen == false)
bounds.X -= HScrollOffset;
if (isVFrozen == false)
bounds.Y -= VScrollOffset;
if (bounds.X > renderInfo.ClipRectangle.Right)
return (false);
cell.Render(renderInfo);
return (true);
}
#endregion
#region RenderEmptyCell
private bool RenderEmptyCell(GridRenderInfo renderInfo,
GridColumn column, bool isHFrozen, bool isVFrozen)
{
Rectangle r = column.BoundsRelative;
r.Y = BoundsRelative.Y;
r.Height = FixedRowHeight;
Rectangle bounds = r;
if (isHFrozen == false)
bounds.X -= HScrollOffset;
if (isVFrozen == false)
{
bounds.Y -= VScrollOffset;
bounds.Intersect(SViewRect);
}
if (bounds.X > renderInfo.ClipRectangle.Right)
return (false);
GridCell cell = GetEmptyRenderCell(column);
cell.IsMouseOver =
bounds.Contains(SuperGrid.PointToClient(Control.MousePosition));
cell.Render(renderInfo);
return (true);
}
#region GetEmptyRenderCell
private GridCell GetEmptyRenderCell(GridColumn column)
{
if (_EmptyRenderCell == null)
_EmptyRenderCell = new GridCell();
int oldIndex = _EmptyRenderCell.ColumnIndex;
_EmptyRenderCell = GetEmptyCell(_EmptyRenderCell, column.ColumnIndex);
if (_EmptyRenderCell.ColumnIndex != oldIndex)
_EmptyRenderCell.ClearEffectiveStyles();
return (_EmptyRenderCell);
}
#endregion
#endregion
#region RenderFocusRect
private void RenderFocusRect(Graphics g, Rectangle r)
{
if (SuperGrid.Focused == true && IsDesignerHosted == false)
{
GridCell cell = FirstVisibleCell;
if (cell != null)
{
Rectangle v = cell.HighLightBounds;
r.X = v.X;
if (r.X < 0)
{
r.X = -(r.X % 2);
r.Width -= (r.X - v.X);
}
}
r.Height = FixedRowHeight;
switch (GridPanel.GridLines)
{
case GridLines.Both:
r.Width -= Dpi.Width1;
r.Height -= Dpi.Height1;
break;
case GridLines.Vertical:
r.Width -= Dpi.Width1;
break;
case GridLines.Horizontal:
r.Height -= Dpi.Height1;
break;
}
Region clip = null;
if (IsVFrozen == false)
{
Rectangle t = SViewRect;
GridPanel panel = GridPanel;
GridColumn col = panel.Columns.LastVisibleColumn;
if (col != null)
{
switch (panel.RowFocusMode)
{
case RowFocusMode.FullRow:
Rectangle w = panel.Bounds;
if (r.Right > w.Right)
{
r.Width -= (r.Right - w.Right + 1);
if (panel.IsSubPanel == true && panel.ShowDropShadow == true)
r.Width -= Dpi.Width5;
}
if (r.Right < col.Bounds.Right)
r.Width += (col.Bounds.Right - r.Right - 1);
break;
default:
if (r.Right > col.Bounds.Right)
r.Width -= (r.Right - col.Bounds.Right + 1);
break;
}
}
clip = g.Clip;
g.SetClip(t);
}
ControlPaint.DrawFocusRectangle(g, r);
if (clip != null)
g.Clip = clip;
}
}
#endregion
#endregion
#region RenderRowHeader
/// <summary>
/// RenderRowHeader
/// </summary>
/// <param name="renderInfo"></param>
/// <param name="panel"></param>
/// <param name="item"></param>
/// <param name="pstyle"></param>
/// <param name="r"></param>
protected void RenderRowHeader(GridRenderInfo renderInfo,
GridPanel panel, GridContainer item, GridPanelVisualStyle pstyle, Rectangle r)
{
Graphics g = renderInfo.Graphics;
r.Width = panel.RowHeaderWidthEx;
if (r.IntersectsWith(renderInfo.ClipRectangle))
{
if (r.Height > 100)
r = GetCenterBounds(r);
RenderRowHeader(g, panel, item, pstyle, r, true);
}
}
#region RenderRowHeader
private void RenderRowHeader(Graphics g, GridPanel panel,
GridContainer item, GridPanelVisualStyle pstyle, Rectangle r, bool highlight)
{
r.Width--;
r.Height--;
if (r.Width > 0 && r.Height > 0)
{
StyleState rowState = GetRowHeaderState(item, r);
RowVisualStyle style = GetEffectiveRowStyle(item, rowState);
if (SuperGrid.DoPreRenderRowEvent(g, this, RenderParts.RowHeader, r) == false)
{
if (item.IsActiveRow == true &&
(panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Highlight ||
panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Both))
{
using (Brush br = style.RowHeaderStyle.ActiveRowBackground.GetBrush(r))
g.FillRectangle(br, r);
}
else
{
using (Brush br = style.RowHeaderStyle.Background.GetBrush(r))
g.FillRectangle(br, r);
}
if (highlight == true)
{
using (Pen pen = new Pen(style.RowHeaderStyle.BorderHighlightColor, Dpi.Height1))
g.DrawLine(pen, r.X, r.Top, r.Right, r.Top);
using (Pen pen = new Pen(style.RowHeaderStyle.BorderHighlightColor, Dpi.Width1))
g.DrawLine(pen, r.X + 1, r.Top, r.X + 1, r.Bottom);
using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Height1))
{
g.DrawLine(pen, r.X, r.Top - 1, r.Right, r.Top - 1);
g.DrawLine(pen, r.X, r.Bottom, r.Right, r.Bottom);
}
using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Width1))
g.DrawLine(pen, r.Right, r.Top, r.Right, r.Bottom);
}
if (item is GridRow)
{
if (RowDirty == true && panel.ShowRowDirtyMarker == true)
{
Rectangle t = r;
t.X++;
t.Width = Dpi.Width3;
using (Brush br = style.RowHeaderStyle.DirtyMarkerBackground.GetBrush(t))
g.FillRectangle(br, t);
}
}
r.Width = panel.RowHeaderWidthEx;
RenderHeaderInfo(g, panel, item, style, r);
SuperGrid.DoPostRenderRowEvent(g, this, RenderParts.RowHeader, r);
}
}
}
#region GetRowHeaderState
private StyleState GetRowHeaderState(
GridContainer item, Rectangle r)
{
StyleState rowState = StyleState.Default;
if (IsMouseOver == true)
{
r.Height++;
if (IsResizing == true ||
r.Contains(SuperGrid.PointToClient(Control.MousePosition)) == true)
{
rowState |= StyleState.MouseOver;
}
}
if (item.IsSelected == true)
rowState |= StyleState.Selected;
return (rowState);
}
#endregion
#endregion
#region RenderHeaderInfo
private void RenderHeaderInfo(Graphics g,
GridPanel panel, GridContainer item, RowVisualStyle style, Rectangle r)
{
r.X += Dpi.Width4;
r.Width -= Dpi.Width4;
GridRow row = item as GridRow;
int m = RenderInfoImage(g, panel, item, r);
if (row != null && row.IsInsertRow == true)
{
RenderInsertIndicator(g, panel, r);
RenderIndicatorImage(g, panel, item, r);
}
else
{
if (panel.ShowEditingImage == true &&
(row != null && row.EditorDirty == true))
{
RenderEditingImage(g, panel, r);
}
else
{
int n = RenderIndicatorImage(g, panel, item, r);
r.X += n;
r.Width -= n;
string text = item.RowHeaderText;
if (string.IsNullOrEmpty(text) == true)
{
text = (panel.ShowRowGridIndex == true)
? (item.GridIndex + panel.RowHeaderIndexOffset).ToString() : "";
}
SuperGrid.DoGetRowHeaderTextEvent(item, ref text);
if (string.IsNullOrEmpty(text) == false)
RenderGridIndex(g, text, style, r, m);
}
}
}
#region RenderInfoImage
private int RenderInfoImage(
Graphics g, GridPanel panel, GridContainer item, Rectangle r)
{
GridRow row = item as GridRow;
if (row != null)
{
row.InfoImageBounds = Rectangle.Empty;
if (ShowInfoRowImage(panel, row) == true)
{
StyleState rowState = GetRowHeaderState(this, r);
RowHeaderVisualStyle style = GetEffectiveRowStyle(this, rowState).RowHeaderStyle;
Image image = style.GetInfoRowImage(panel);
if (image != null)
{
Rectangle u = r;
Size size = image.Size;
u.Size = size;
u.X = r.Right - u.Width - 4;
u.X = Math.Max(r.X, u.X);
if (r.Height > u.Height)
u.Y += (r.Height - u.Height)/2;
u.Intersect(r);
row.InfoImageBounds = u;
g.DrawImageUnscaledAndClipped(image, u);
return (size.Width);
}
}
}
return (0);
}
#region ShowInfoRowImage
private bool ShowInfoRowImage(GridPanel panel, GridRow row)
{
if (panel.ShowRowInfo == false || row.InfoText == null)
return (false);
if (row.InfoText.Equals("") == false)
return (true);
return (panel.ShowRowInfoDisplayMode == ShowRowInfoDisplayMode.ShowWithEmptyText);
}
#endregion
#endregion
#region RenderEditingImage
private void RenderEditingImage(
Graphics g, GridPanel panel, Rectangle r)
{
StyleState rowState = GetRowHeaderState(this, r);
RowHeaderVisualStyle style = GetEffectiveRowStyle(this, rowState).RowHeaderStyle;
Image image = style.GetEditingRowImage(panel);
if (image != null)
{
Rectangle u = r;
u.Size = image.Size;
if (r.Width > u.Width)
u.X += (r.Width - u.Width) / 2;
if (r.Height > u.Height)
u.Y += (r.Height - u.Height) / 2;
u.Intersect(r);
g.DrawImageUnscaledAndClipped(image, u);
}
}
#endregion
#region RenderInsertIndicator
private void RenderInsertIndicator(
Graphics g, GridPanel panel, Rectangle r)
{
if (panel.ShowInsertRowImage == true)
{
Image image = panel.GetInsertRowImage();
if (image != null)
{
Rectangle u = r;
u.Size = image.Size;
if (r.Width > u.Width)
u.X = r.X + (r.Width - u.Width) / 2;
if (r.Height > u.Height)
u.Y += (r.Height - u.Height) / 2;
u.Intersect(r);
g.DrawImageUnscaledAndClipped(image, u);
}
}
}
#endregion
#region RenderIndicatorImage
private int RenderIndicatorImage(Graphics g,
GridPanel panel, GridContainer row, Rectangle r)
{
StyleState rowState = GetRowHeaderState(this, r);
RowHeaderVisualStyle style = GetEffectiveRowStyle(this, rowState).RowHeaderStyle;
Image image = null;
GridRow grow = row as GridRow;
if (grow != null)
{
if (grow.IsTempInsertRow == true && grow.IsInsertRow == false)
image = panel.GetInsertTempRowImage();
else
image = style.GetActiveRowImage(panel);
}
if (image != null)
{
Size size = image.Size;
int n = size.Width;
if (row.IsActiveRow == true)
{
if (panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Image ||
panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Both)
{
Rectangle u = r;
u.Size = size;
if (r.Height > u.Height)
u.Y += (r.Height - u.Height) / 2;
u.Intersect(r);
g.DrawImageUnscaledAndClipped(image, u);
}
}
return (n);
}
return (0);
}
#endregion
#region RenderGridIndex
private void RenderGridIndex(Graphics g,
string text, RowVisualStyle style, Rectangle r, int m)
{
Font font = style.RowHeaderStyle.Font ?? SystemFonts.DefaultFont;
r.Inflate(-Dpi.Width2, 0);
r.Width -= m;
eTextFormat tf = style.RowHeaderStyle.GetTextFormatFlags();
TextDrawing.DrawString(g, text,
font, style.RowHeaderStyle.TextColor, r, tf);
}
#endregion
#endregion
#endregion
#region RenderRowWhitespace
private void RenderRowWhitespace(GridRenderInfo renderInfo,
GridPanel panel, GridPanelVisualStyle pstyle, Rectangle r)
{
Graphics g = renderInfo.Graphics;
if (SuperGrid.DoPreRenderRowEvent(g, this, RenderParts.Whitespace, r) == false)
{
StyleState state = GetWhiteSpaceState(panel);
RowVisualStyle style = GetEffectiveRowStyle(this, state);
using (Brush br = style.Background.GetBrush(r))
g.FillRectangle(br, r);
if (panel.ShowWhitespaceRowLines == true)
{
switch (panel.GridLines)
{
case GridLines.Both:
case GridLines.Horizontal:
if (pstyle.HorizontalLinePattern != LinePattern.None &&
pstyle.HorizontalLinePattern != LinePattern.NotSet)
{
using (Pen pen = new Pen(pstyle.HorizontalLineColor, Dpi.Height1))
{
pen.DashStyle = (DashStyle)pstyle.HorizontalLinePattern;
g.DrawLine(pen, r.Left, r.Bottom - 1, r.Right - 1, r.Bottom - 1);
g.DrawLine(pen, r.Left, r.Top - 1, r.Right - 1, r.Top - 1);
}
}
break;
}
}
SuperGrid.DoPostRenderRowEvent(g, this, RenderParts.Whitespace, r);
}
}
#region GetWhiteSpaceState
private StyleState GetWhiteSpaceState(GridPanel panel)
{
StyleState rowState = StyleState.Default;
if (IsMouseOver == true && _HitArea == RowArea.InWhiteSpace)
rowState |= StyleState.MouseOver;
if (IsSelected == true && panel.RowHighlightType != RowHighlightType.None)
rowState |= StyleState.Selected;
if (panel.SelectionGranularity != SelectionGranularity.Cell &&
panel.RowHighlightType == RowHighlightType.Full)
{
if (Bounds.Contains(SuperGrid.PointToClient(Control.MousePosition)))
rowState |= StyleState.MouseOver;
}
if (SuperGrid.ScrollBarScrolling == true)
rowState &= ~StyleState.MouseOver;
return (rowState);
}
#endregion
#endregion
#region RenderSubItems
/// <summary>
/// RenderSubItems
/// </summary>
/// <param name="renderInfo"></param>
/// <param name="panel"></param>
/// <param name="pstyle"></param>
/// <param name="isSubPanel"></param>
/// <param name="isFrozen"></param>
protected void RenderSubItems(GridRenderInfo renderInfo,
GridPanel panel, GridPanelVisualStyle pstyle, bool isSubPanel, bool isFrozen)
{
Rectangle t = SViewRect;
GridItemsCollection items = Rows;
for (int i = FirstOnScreenRowIndex; i < items.Count; i++)
{
GridElement item = items[i];
if (item.Visible == true)
{
GridPanel ipanel = item as GridPanel;
if (ipanel != null)
{
Graphics g = renderInfo.Graphics;
Rectangle r = ipanel.ContainerBounds;
if (isFrozen == false)
r.Y -= VScrollOffset;
if (isSubPanel == true)
r.X -= HScrollOffset;
if (r.Y > t.Bottom)
break;
if (r.IntersectsWith(renderInfo.ClipRectangle))
{
Rectangle r2 = r;
if (panel.ShowRowHeaders == true)
{
r2.X += panel.RowHeaderWidthEx;
r2.Width -= panel.RowHeaderWidthEx;
}
if (SuperGrid.DoPreRenderPanelRowEvent(g,
ipanel, RenderParts.Background | RenderParts.Border, r2) == false)
{
RenderRowBackground(g, ipanel, r2);
RenderRowBorder(g, panel, r2);
SuperGrid.DoPostRenderPanelRowEvent(g,
ipanel, RenderParts.Background | RenderParts.Border, r2);
}
RenderTreeLines(g, panel, ipanel, r, isSubPanel);
RenderRowCheckBox(g, panel, ipanel);
item.Render(renderInfo);
if (panel.ShowRowHeaders == true)
{
r2 = r;
r2.Width = panel.RowHeaderWidthEx;
if (SuperGrid.DoPreRenderPanelRowEvent(g,
ipanel, RenderParts.RowHeader, r2) == false)
{
RenderRowHeader(renderInfo, panel, ipanel, pstyle, r2);
SuperGrid.DoPostRenderPanelRowEvent(g,
ipanel, RenderParts.RowHeader, r2);
}
}
}
}
else
{
Rectangle r = item.BoundsRelative;
if (isFrozen == false)
r.Y -= VScrollOffset;
if (isSubPanel == true)
r.X -= HScrollOffset;
if (r.Y > t.Bottom)
break;
if (r.IntersectsWith(renderInfo.ClipRectangle))
item.Render(renderInfo);
}
}
}
}
#endregion
#region RenderTreeLines
private void RenderTreeLines(Graphics g,
GridPanel panel, GridPanel ipanel, Rectangle r, bool isSubPanel)
{
if (panel.ShowTreeButtons == true && panel.ShowTreeLines == true)
{
if (panel.PrimaryColumn != null &&
panel.PrimaryColumn.Visible == true)
{
int n = panel.PrimaryColumn.BoundsRelative.X -
panel.BoundsRelative.X;
r.X += n;
r.Width -= n;
r = GetCenterBounds(r);
if (panel.PrimaryColumn.IsHFrozen == false)
{
if (isSubPanel == false)
r.X -= HScrollOffset;
}
TreeDisplay.RenderLines(g, panel, r, ipanel, ipanel.IndentLevel,
Dpi.Width(panel.LevelIndentSize.Width), panel.TreeButtonIndent, false);
}
}
}
#endregion
#region RenderRowBackground
/// <summary>
/// RenderRowBackground
/// </summary>
/// <param name="g"></param>
/// <param name="item"></param>
/// <param name="r"></param>
protected void RenderRowBackground(
Graphics g, GridContainer item, Rectangle r)
{
if (item is GridPanel)
{
RowVisualStyle style = GetEffectiveRowStyle(item);
if (style.Background != null && style.Background.IsEmpty == false)
{
Rectangle t = item.ContainerBounds;
t.X -= HScrollOffset;
if (IsVFrozen == false)
{
t.Y -= VScrollOffset;
r.Intersect(SViewRect);
t.Intersect(SViewRect);
t.Y = r.Y;
}
using (Brush br = style.Background.GetBrush(t))
g.FillRectangle(br, r);
}
}
}
#endregion
#region RenderRowCheckBox
/// <summary>
/// RenderRowCheckBox
/// </summary>
/// <param name="g"></param>
/// <param name="panel"></param>
/// <param name="ipanel"></param>
protected void RenderRowCheckBox(Graphics g,
GridPanel panel, GridPanel ipanel)
{
if (ipanel.HasCheckBox == true)
{
Rectangle r = GetRowCheckBoxBounds(panel, ipanel);
if (ipanel.Checked == true)
{
CheckDisplay.RenderCheckbox(g, r,
CheckBoxState.CheckedNormal, ButtonState.Checked);
}
else
{
CheckDisplay.RenderCheckbox(g, r,
CheckBoxState.UncheckedNormal, ButtonState.Normal);
}
}
}
#endregion
#region GetRowCheckBoxBounds
private Rectangle GetRowCheckBoxBounds(GridPanel panel, GridPanel ipanel)
{
Rectangle r = ipanel.CheckBoxBounds;
if (ipanel.HasCheckBox == true)
{
Rectangle bounds = ipanel.ContainerBounds;
bounds.Location = PointToScroll(ipanel, bounds.Location);
Rectangle t = GetCenterBounds(bounds);
r.Y = t.Y + (t.Height - Dpi.Height(panel.CheckBoxSize.Height)) / 2;
r.X -= HScrollOffset;
if (r.Bottom > bounds.Bottom)
r.Y -= (r.Bottom - bounds.Bottom);
if (r.Y < bounds.Y)
r.Y = bounds.Y;
t = r;
t.X += HScrollOffset;
if (ipanel.IsVFrozen == false)
t.Y += VScrollOffset;
ipanel.CheckBoxBounds = t;
}
else
{
r = Rectangle.Empty;
ipanel.CheckBoxBounds = r;
}
return (r);
}
#endregion
#region RenderRowBorder
/// <summary>
/// RenderRowBorder
/// </summary>
/// <param name="g"></param>
/// <param name="panel"></param>
/// <param name="r"></param>
protected void RenderRowBorder(
Graphics g, GridPanel panel, Rectangle r)
{
if (panel.GridLines == GridLines.Horizontal || panel.GridLines == GridLines.Both)
{
if (panel.ShowWhitespaceRowLines == true)
{
GridPanelVisualStyle pstyle = panel.GetEffectiveStyle();
using (Pen pen = new Pen(pstyle.HorizontalLineColor, Dpi.Height1))
{
pen.DashStyle = (DashStyle)pstyle.HorizontalLinePattern;
pen.DashOffset = r.X % 2;
g.DrawLine(pen, r.X, r.Top - 1, r.Right - 1, r.Top - 1);
g.DrawLine(pen, r.X, r.Bottom - 1, r.Right - 1, r.Bottom - 1);
}
}
}
}
#endregion
#region RenderDesignerElement
private void RenderDesignerElement(
GridRenderInfo renderInfo, Rectangle r)
{
if (SuperGrid.DesignerElement == this)
{
r.X -= Dpi.Width2;
r.Y += Dpi.Height1;
r.Height -= Dpi.Height4;
r.Width += Dpi.Width5;
if (r.Width > 0 && r.Height > 0)
{
using (Pen pen = new Pen(Color.Purple, Dpi.Width1))
{
pen.DashStyle = DashStyle.Dash;
renderInfo.Graphics.DrawRectangle(pen, r);
}
}
}
}
#endregion
#endregion
#region GetCenterBounds
private Rectangle GetCenterBounds(Rectangle bounds)
{
Rectangle r = SuperGrid.ClientRectangle;
int m = r.Y;
if (IsVFrozen == false)
m += SuperGrid.PrimaryGrid.FixedRowHeight;
if (bounds.Y < m)
{
int n = m - bounds.Y;
bounds.Y = m;
bounds.Height -= n;
}
m = r.Bottom;
if (SuperGrid.IsHScrollBarVisible == true)
m -= SuperGrid.HScrollBarHeight;
if (SuperGrid.PrimaryGrid.Footer != null &&
SuperGrid.PrimaryGrid.Footer.Visible == true)
{
m -= SuperGrid.PrimaryGrid.Footer.Size.Height;
}
if (bounds.Bottom > m)
bounds.Height -= (bounds.Bottom - m) - 1;
return (bounds);
}
#endregion
#region FindCell
private GridCell FindCell(string columnName)
{
if (string.IsNullOrEmpty(columnName) == true)
throw new Exception("Invalid Column Name.");
foreach (GridCell cell in Cells)
{
GridColumn col = cell.GridColumn;
if (col == null)
break;
if (columnName.Equals(col.Name) == true)
return (cell);
}
return (null);
}
#endregion
#region GetCell
///<summary>
/// Gets the Row Cell for the given column index. If
/// the cell does not exist,then null will be returned.
///</summary>
///<param name="columnIndex"></param>
///<returns></returns>
public GridCell GetCell(int columnIndex)
{
return (GetCell(columnIndex, false));
}
///<summary>
/// Gets the Row Cell for the given column name. If
/// the cell does not exist, null will be returned.
///</summary>
///<param name="name"></param>
///<returns></returns>
public GridCell GetCell(string name)
{
return (FindCell(name));
}
///<summary>
/// Gets the Row Cell for the given column index. If
/// "includeEmpty" is true, and the cell does not exist
/// (i.e. is empty) then a dummy empty cell will be created
/// and returned.
///</summary>
///<param name="columnIndex"></param>
///<param name="includeEmpty"></param>
///<returns></returns>
public GridCell GetCell(int columnIndex, bool includeEmpty)
{
if (columnIndex < _Cells.Count)
return (_Cells[columnIndex]);
if (includeEmpty == true)
return (GetEmptyCell(null, columnIndex));
return (null);
}
#endregion
#region GetEmptyCell
internal GridCell GetEmptyCell(GridCell cell, int columnIndex)
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (columnIndex < panel.Columns.Count)
{
GridColumn column = panel.Columns[columnIndex];
if (cell == null)
cell = new GridCell();
Rectangle r = column.BoundsRelative;
r.Y = BoundsRelative.Y;
r.Height = FixedRowHeight;
cell.BoundsRelative = r;
cell.Parent = this;
cell.IsEmptyCell = true;
cell.ColumnIndex = columnIndex;
cell.SelectionUpdateCount = (ushort)(GridPanel.SelectionUpdateCount - 1);
cell.Selected = ExpandedVisible(panel) == true ? panel.IsItemSelectedEx(cell) : false;
return (cell);
}
}
return (cell);
}
#endregion
#region Mouse Handling
#region InternalMouseEnter
/// <summary>
/// InternalMouseEnter
/// </summary>
/// <param name="e"></param>
internal override void InternalMouseEnter(EventArgs e)
{
IsMouseOver = true;
if (GridPanel.RowHighlightType == RowHighlightType.Full)
InvalidateRender();
SuperGrid.DoRowMouseEnterEvent(this);
base.InternalMouseEnter(e);
}
#region InvalidateWhitespace
private void InvalidateWhitespace()
{
Rectangle r = WhiteSpaceBounds;
if (r.IsEmpty == false)
InvalidateRender(r);
}
#endregion
#endregion
#region InternalMouseLeave
/// <summary>
/// InternalMouseLeave
/// </summary>
/// <param name="e"></param>
internal override void InternalMouseLeave(EventArgs e)
{
GridPanel panel = GridPanel;
if (panel != null)
{
IsMouseOver = false;
if (GridPanel.RowHighlightType == RowHighlightType.Full)
InvalidateRender(Bounds);
if (panel.ShowRowHeaders == true)
{
panel.HotItem = null;
_HitArea = RowArea.NoWhere;
_HitItem = null;
}
SuperGrid.ToolTip.Hide(SuperGrid);
if (_LastArea == RowArea.InRowInfo)
ProcessRowInfoLeave();
}
CancelCapture();
base.InternalMouseLeave(e);
SuperGrid.DoRowMouseLeaveEvent(this);
}
#endregion
#region InternalMouseMove
/// <summary>
/// InternalMouseMove
/// </summary>
/// <param name="e"></param>
internal override void InternalMouseMove(MouseEventArgs e)
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (IsMouseDown == true && _MouseDownHitRow != null)
ProcessMouseDownMove(e, panel);
ProcessMouseMove(e, panel);
}
SuperGrid.DoRowMouseMoveEvent(this, e, _HitArea);
if (Capture == false)
base.InternalMouseMove(e);
}
#region ProcessMouseDownMove
private void ProcessMouseDownMove(MouseEventArgs e, GridPanel panel)
{
if (_MouseDownHitRow != null)
{
Rectangle r = ViewRect;
if (MouseDownPoint.Y < r.Y)
{
int n = SuperGrid.PrimaryGrid.FixedRowHeight -
SuperGrid.PrimaryGrid.FixedHeaderHeight;
r.Y -= n;
r.Height += n;
}
VScrollBarAdv vsb = SuperGrid.VScrollBar;
if ((e.Y >= r.Y) &&
(e.Y < r.Bottom || (vsb.Value >= vsb.Maximum - vsb.LargeChange)))
{
SuperGrid.DisableAutoScrolling();
switch (_MouseDownHitArea)
{
case RowArea.InRowHeader:
panel.HotItem = _HitItem;
ProcessInRowHeader(panel, e);
break;
case RowArea.InRowResize:
ProcessInRowResize(panel, e.Location);
break;
case RowArea.InContent:
case RowArea.InWhiteSpace:
ProcessInContent(panel, e.Location, e);
break;
}
}
else
{
SuperGrid.EnableAutoScrolling(AutoScrollEnable.Vertical, r);
StopResize();
StopReorder();
}
}
}
#region ProcessInContent
private void ProcessInContent(
GridPanel panel, Point pt, MouseEventArgs e)
{
GridContainer container = _MouseDownHitRow.Parent as GridContainer;
if (container != null)
{
if (panel.SelectionGranularity != SelectionGranularity.Cell)
{
_HitItem = GetRowAt(panel, pt);
if (_HitItem != null)
{
if (DragStarted(panel, e) == false)
{
if (panel.CellDragBehavior == CellDragBehavior.ExtendSelection)
{
if (panel.MultiSelect == true)
{
if (_HitItem != panel.LastProcessedItem)
ProcessExtendSelection(panel, true);
}
}
}
}
}
}
}
#endregion
#endregion
#region ProcessMouseMove
private void ProcessMouseMove(MouseEventArgs e, GridPanel panel)
{
_HitArea = GetHitArea(e.Location);
if (IsMouseDown == false)
{
switch (_HitArea)
{
case RowArea.InRowHeader:
panel.HotItem = _HitItem;
SuperGrid.GridCursor = Cursors.Default;
break;
case RowArea.InRowCheckBox:
case RowArea.InCellCheckBox:
case RowArea.InCellExpand:
panel.HotItem = null;
SuperGrid.GridCursor = Cursors.Hand;
break;
case RowArea.InRowResize:
panel.HotItem = _HitItem;
SuperGrid.GridCursor = Cursors.HSplit;
break;
default:
panel.HotItem = null;
SuperGrid.GridCursor = Cursors.Default;
break;
}
}
else
{
if ((Control.MouseButtons & MouseButtons.Left) != MouseButtons.Left)
SuperGrid.GridCursor = Cursors.Default;
}
if (_HitArea != _LastArea)
{
if (_HitArea == RowArea.InRowInfo)
ProcessRowInfoEnter(e);
else if (_LastArea == RowArea.InRowInfo)
ProcessRowInfoLeave();
if (_HitArea == RowArea.InWhiteSpace || _LastArea == RowArea.InWhiteSpace)
{
if (panel.RowHighlightType == RowHighlightType.Full)
InvalidateRender(Bounds);
else
InvalidateWhitespace();
}
_LastArea = _HitArea;
}
}
#region ProcessRowInfoEnter
private void ProcessRowInfoEnter(MouseEventArgs e)
{
if (SuperGrid.DoRowInfoEnterEvent(this, e.Location) == false)
SuperGrid.ToolTipText = InfoText;
}
#endregion
#region ProcessRowInfoLeave
private void ProcessRowInfoLeave()
{
SuperGrid.ToolTipText = "";
SuperGrid.DoRowInfoLeaveEvent(this);
}
#endregion
#endregion
#endregion
#region InternalMouseDown
/// <summary>
/// InternalMouseDown
/// </summary>
/// <param name="e"></param>
internal override void InternalMouseDown(MouseEventArgs e)
{
GridPanel panel = GridPanel;
RowArea hitArea = _HitArea;
GridContainer hitItem = _HitItem;
if (panel != null && hitItem != null)
{
SuperGrid.DoRowMouseDownEvent(this, e, hitArea);
if (_HitArea == RowArea.InRowResize)
{
_MouseDownHitArea = _HitArea;
_MouseDownHitRow = _HitItem;
_MouseDownPoint = e.Location;
InitRowResize(e);
return;
}
if (CanSetActiveRow(panel, hitItem, true) == true)
{
_HitItem = hitItem;
_HitArea = hitArea;
int rowIndex = RowIndex;
if (panel.OnlySendFinalRowActivatedEvents == false || hitArea != RowArea.InSubItem)
{
if (panel.SetActiveRow(_HitItem, true) == true)
{
if (_HitArea != RowArea.InContent)
panel.DeactivateEdit();
if (rowIndex > RowIndex)
{
SuperGrid.ArrangeGrid();
GridContainer row = panel.GetElementAt(e) as GridContainer;
if (row != null)
{
row.InternalMouseMove(e);
row.InternalMouseDown(e);
return;
}
}
_MouseDownHitArea = _HitArea;
_MouseDownHitRow = _HitItem;
_MouseDownPoint = e.Location;
_dragSelection = false;
_dragStarted = false;
switch (_HitArea)
{
case RowArea.InRowHeader:
panel.LastProcessedItem = _HitItem;
switch (panel.RowDragBehavior)
{
case RowDragBehavior.Move:
case RowDragBehavior.GroupMove:
InitExtendSelection(panel);
if ((Control.ModifierKeys & (Keys.Control | Keys.Shift)) == 0)
InitRowMove(panel);
break;
case RowDragBehavior.ExtendSelection:
InitSelectOrDrag(panel);
break;
}
return;
case RowArea.InContent:
if (_HitItem is GridPanel ||
panel.SelectionGranularity != SelectionGranularity.Cell)
{
InitSelectOrDrag(panel);
}
break;
case RowArea.InWhiteSpace:
panel.LastProcessedItem = _HitItem;
GridCell acell = SuperGrid.ActiveCell;
if (acell != null)
acell.ResumeMerge(null);
switch (panel.RowWhitespaceClickBehavior)
{
case RowWhitespaceClickBehavior.ClearSelection:
panel.ClearAll();
break;
case RowWhitespaceClickBehavior.ExtendSelection:
InitExtendSelection(panel);
break;
}
return;
case RowArea.InCellExpand:
panel.LastProcessedItem = _HitItem;
ProcessInExpandButton(e);
if (panel.SelectionGranularity != SelectionGranularity.Cell)
return;
break;
}
base.InternalMouseDown(e);
}
else
{
_MouseDownHitArea = RowArea.NoWhere;
_MouseDownHitRow = null;
}
}
else
{
_MouseDownHitArea = _HitArea;
_MouseDownHitRow = _HitItem;
_MouseDownPoint = e.Location;
base.InternalMouseDown(e);
}
}
}
}
#region InitSelectOrDrag
private void InitSelectOrDrag(GridPanel panel)
{
if (panel.SuperGrid.HasItemDragHandler == false || IsSelected == false ||
((Control.ModifierKeys & (Keys.Control | Keys.Shift)) != Keys.None))
{
InitExtendSelection(panel);
}
else if (IsMouseDown == true)
{
Capture = true;
_dragSelection = true;
}
}
#endregion
#endregion
#region InternalMouseUp
/// <summary>
/// InternalMouseUp
/// </summary>
/// <param name="e"></param>
internal override void InternalMouseUp(MouseEventArgs e)
{
GridPanel panel = GridPanel;
if (panel != null)
{
SuperGrid.DisableAutoScrolling();
if (SuperGrid.DoRowClickEvent(this, _MouseDownHitArea, e) == false)
{
switch (_MouseDownHitArea)
{
case RowArea.InRowInfo:
SuperGrid.DoRowInfoClickEvent(this, e);
break;
case RowArea.InRowCheckBox:
ProcessInCheckBox(panel, _HitItem, e);
break;
case RowArea.InRowResize:
if (IsResizing == true)
{
StopResize();
if (panel.ImmediateResize == false)
{
ResizeRow(panel, e.Location.Y);
PostInternalMouseMove();
}
}
break;
case RowArea.InRowHeader:
if (IsReordering == true)
{
ReorderRow(panel);
StopReorder();
PostInternalMouseMove();
}
else
{
ExtendDragSelection(panel, e);
panel.ColumnHeader.InvalidateRowHeader();
}
SuperGrid.DoRowHeaderClickEvent(panel, this, e);
break;
case RowArea.InCellCheckBox:
ProcessInCheckBox(panel, this, e);
break;
case RowArea.InContent:
ExtendDragSelection(panel, e);
break;
}
}
base.InternalMouseUp(e);
SuperGrid.DoRowMouseUpEvent(this, e, _MouseDownHitArea);
}
_MouseDownHitRow = null;
}
#region ExtendDragSelection
private void ExtendDragSelection(GridPanel panel, MouseEventArgs e)
{
if (_dragSelection == true && Capture == true)
{
if (IsMouseSelectableEx(e.Button) == true)
ExtendSelectionEx(panel);
}
}
#endregion
#endregion
#region InternalMouseDoubleClick
internal override void InternalMouseDoubleClick(MouseEventArgs e)
{
if (SuperGrid.EditorCell == null)
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (SuperGrid.DoRowDoubleClickEvent(this, _MouseDownHitArea, e) == false)
{
switch (_MouseDownHitArea)
{
case RowArea.InRowHeader:
SuperGrid.DoRowHeaderDoubleClickEvent(this, e);
break;
case RowArea.InRowInfo:
SuperGrid.DoRowInfoDoubleClickEvent(this, e);
break;
case RowArea.InRowResize:
int n = Dpi.DescaleHeight(GetMaximumRowHeight());
if (panel.VirtualMode == true)
panel.VirtualRowHeight = n;
else
RowHeight = n;
StopResize();
break;
case RowArea.InContent:
if (panel.RowDoubleClickBehavior == RowDoubleClickBehavior.Activate)
{
if (MouseActivateCell(e, panel) == true)
return;
}
else
{
Expanded = !Expanded;
}
break;
}
base.InternalMouseDoubleClick(e);
}
}
}
}
#region MouseActivateCell
private bool MouseActivateCell(MouseEventArgs e, GridPanel panel)
{
if (panel.MouseEditMode == MouseEditMode.DoubleClick)
{
GridCell cell = null;
if (panel.SelectionGranularity != SelectionGranularity.Cell)
{
if (_HitArea == RowArea.InContent)
{
switch (panel.RowEditMode)
{
case RowEditMode.PrimaryCell:
if (panel.PrimaryColumn != null &&
panel.PrimaryColumn.Visible == true)
{
cell = _Cells[panel.PrimaryColumnIndex];
}
else
{
cell = FirstVisibleCell;
}
break;
default:
cell = GetCellAt(panel, e.X, e.Y);
break;
}
}
}
else
{
cell = GetCellAt(panel, e.X, e.Y);
}
if (cell != null)
{
cell.InternalMouseDoubleClick(e);
return (true);
}
}
return (false);
}
#endregion
#endregion
#region ProcessInExpandButton
private void ProcessInExpandButton(MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
Expanded = !Expanded;
}
#endregion
#region ProcessInCheckBox
internal void ProcessInCheckBox(
GridPanel panel, GridContainer item, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
if (item != null && item.CanModify == true)
{
ProcessNewRowChange(panel);
if (SuperGrid.DoBeforeCheckEvent(panel, item) == false)
item.Checked = !item.Checked;
}
}
}
#endregion
#region ProcessInRowHeader
private void ProcessInRowHeader(GridPanel panel, MouseEventArgs e)
{
GridContainer container = _MouseDownHitRow.Parent as GridContainer;
if (container != null)
{
Point pt = e.Location;
_HitItem = GetRowAt(panel, pt);
if (_HitItem != null)
{
switch (panel.RowDragBehavior)
{
case RowDragBehavior.Move:
case RowDragBehavior.GroupMove:
if (IsInsertRow == false &&
panel.VirtualMode == false)
{
if (IsReordering == false)
StartReorder(pt);
else
ContinueReorder(panel, pt);
}
break;
case RowDragBehavior.ExtendSelection:
if (DragStarted(panel, e) == false)
{
if (panel.MultiSelect == true)
{
if (_HitItem != panel.LastProcessedItem)
ProcessExtendSelection(panel, true);
}
}
break;
}
}
}
}
#region DragStarted
private bool DragStarted(GridPanel panel, MouseEventArgs e)
{
if (_dragSelection == true && Capture == true)
{
if (_dragStarted == false)
{
if (DragDrop.DragStarted(_MouseDownPoint, e.Location) == true)
{
_dragStarted = true;
if (SuperGrid.DoItemDragEvent(this, e) == true)
{
_dragSelection = false;
InitExtendSelection(panel);
}
}
}
return (true);
}
return (false);
}
#endregion
#endregion
#region InitExtendSelection
private void InitExtendSelection(GridPanel panel)
{
if (IsMouseSelectable() == true)
{
Capture = true;
ExtendSelectionEx(panel);
}
}
#region ExtendSelectionEx
private void ExtendSelectionEx(GridPanel panel)
{
if (_MouseDownHitRow != null && _HitItem != null)
{
_AnchorIndex = _MouseDownHitRow.GridIndex;
if (panel.LastProcessedItem != this && panel.LastProcessedItem != null)
panel.LastProcessedItem.InvalidateRender();
bool ckey = panel.MultiSelect == true
? ((Control.ModifierKeys & Keys.Control) == Keys.Control)
: false;
panel.LastProcessedItem = (ckey == true) ? _HitItem : this;
ProcessExtendSelection(panel, false);
}
}
#endregion
#endregion
#region ProcessExtendSelection
internal void ProcessExtendSelection(GridPanel panel, bool extend)
{
bool ckey = panel.MultiSelect == true
? ((Control.ModifierKeys & Keys.Control) == Keys.Control)
: false;
if (ckey == true)
ProcessControlExtend(panel, extend);
else
ProcessNonControlExtend(panel, extend);
panel.LastProcessedItem = _HitItem;
}
#region IsMouseSelectable
private bool IsMouseSelectable()
{
return (IsMouseSelectableEx(Control.MouseButtons));
}
private bool IsMouseSelectableEx(MouseButtons mb)
{
if ((mb & MouseButtons.Left) == MouseButtons.Left)
return (true);
return (IsSelected == false);
}
#endregion
#region ProcessControlExtend
private void ProcessControlExtend(GridPanel panel, bool extend)
{
if (panel.LastProcessedItem == null)
panel.LastProcessedItem = _MouseDownHitRow;
GridContainer lastRow = panel.LastProcessedItem as GridContainer;
if (lastRow != null)
{
int startIndex = lastRow.GridIndex;
int endIndex = _HitItem.GridIndex;
panel.NormalizeIndices(extend,
_AnchorIndex, ref startIndex, ref endIndex);
for (int i = startIndex; i <= endIndex; i++)
{
if (extend == false || i != _AnchorIndex)
panel.SetSelectedRows(i, 1, !panel.IsRowSelected(i));
}
InvalidateRows(panel, startIndex, endIndex, true);
}
}
#endregion
#region ProcessNonControlExtend
private void ProcessNonControlExtend(GridPanel panel, bool extend)
{
bool skey = (panel.MultiSelect == true) ?
((Control.ModifierKeys & Keys.Shift) == Keys.Shift) : false;
if (skey == false || panel.SelectionRowAnchor == null)
panel.SelectionRowAnchor = _MouseDownHitRow;
ExtendSelection(panel, _HitItem, extend);
}
#endregion
#endregion
#region ResizeRow
#region InitRowResize
private void InitRowResize(MouseEventArgs e)
{
if ((Control.MouseButtons & MouseButtons.Left) == MouseButtons.Left)
{
Capture = true;
_MouseDownDelta = e.Y - _MouseDownHitRow.BoundsRelative.Bottom;
if (IsVFrozen == false)
_MouseDownDelta += VScrollOffset;
IsResizing = false;
}
else
{
_MouseDownHitArea = RowArea.NoWhere;
}
}
#endregion
#region ProcessInRowResize
private void ProcessInRowResize(GridPanel panel, Point pt)
{
if (IsResizing == false)
{
StartResize();
}
else
{
if (panel.ImmediateResize == false)
ContinueResize(panel, pt);
else
ResizeRow(panel, pt.Y);
}
}
#endregion
#region StartResize
private void StartResize()
{
GridPanel panel = GridPanel;
if (panel != null)
{
IsResizing = true;
if (panel.ImmediateResize == false)
{
_separatorFw = new FloatWindow();
_separatorFw.Opacity = .5;
_separatorFw.BackColor = Color.Black;
_separatorFw.Owner = SuperGrid.FindForm();
}
}
}
#endregion
#region StopResize
private void StopResize()
{
IsResizing = false;
if (_separatorFw != null)
{
_separatorFw.Close();
_separatorFw.Dispose();
_separatorFw = null;
}
}
#endregion
#region ContinueResize
private void ContinueResize(GridPanel panel, Point pt)
{
Rectangle r = panel.BoundsRelative;
if (panel.Parent != null)
r.Y -= VScrollOffset;
r.X -= HScrollOffset;
if (pt.X > r.X)
{
Rectangle t = _MouseDownHitRow.BoundsRelative;
if (panel.IsSubPanel == true)
t.X -= HScrollOffset;
if (IsVFrozen == false)
t.Y -= VScrollOffset;
int height = pt.Y - t.Y;
if (height < Dpi.Height(panel.MinRowHeight))
pt.Y = t.Y + Dpi.Height(panel.MinRowHeight);
if (pt.Y >= SuperGrid.PrimaryGrid.BoundsRelative.Bottom - Dpi.Height2)
{
_separatorFw.Hide();
}
else
{
if (pt.Y == panel.BoundsRelative.Bottom - 1)
pt.Y--;
r.Height = SeparatorHeight;
r.Y = pt.Y;
r.X = t.X;
r.Width = t.Width;
Rectangle v = SViewRect;
if (r.X < v.X)
{
r.Width -= (v.X - r.X);
r.X = v.X;
}
if (r.Right > v.Right)
r.Width -= (r.Right - v.Right);
r.Location = SuperGrid.PointToScreen(r.Location);
_separatorFw.Show();
_separatorFw.Bounds = r;
_separatorFw.Size = r.Size;
}
}
}
#endregion
#region ResizeRow
private void ResizeRow(GridPanel panel, int y)
{
int ry = _MouseDownHitRow.BoundsRelative.Bottom;
y -= _MouseDownDelta;
if (IsVFrozen == false)
y += VScrollOffset;
int dy = y - ry;
if (dy != 0)
{
int n = Dpi.DescaleHeight(Size.Height + dy + _MouseDownDelta);
n = Math.Max(n, panel.MinRowHeight);
n = Math.Min(n, panel.MaxRowHeight);
if (panel.VirtualMode == true)
{
panel.VirtualRowHeight = n;
}
else
{
if (_MouseDownHitRow is GridRow)
((GridRow)_MouseDownHitRow).RowHeight = n;
}
SuperGrid.DoRowResizedEvent(panel, _MouseDownHitRow);
}
}
#endregion
#endregion
#region ReorderRow
#region InitRowMove
private void InitRowMove(GridPanel panel)
{
if (panel.CanMoveRow == true)
{
Capture = true;
panel.ClearAll();
IsSelected = true;
IsReordering = false;
panel.SelectionRowAnchor = _MouseDownHitRow;
}
}
#endregion
#region StartReorder
private void StartReorder(Point pt)
{
if (Math.Abs(MouseDownPoint.Y - pt.Y) > 5)
{
IsReordering = true;
_SeparatorRow = null;
_headerFw = new FloatWindow();
_headerFw.Opacity = .3;
_headerFw.Owner = SuperGrid.FindForm();
_headerFw.Paint += RowHeaderFwPaint;
_separatorFw = new FloatWindow();
_separatorFw.BackColor = Color.Black;
_separatorFw.Owner = SuperGrid.FindForm();
using (GraphicsPath path = new GraphicsPath())
{
path.AddLines(new Point[]
{
new Point(Dpi.Width3, Dpi.Height3),
new Point(0, Dpi.Height6),
new Point(0, 0),
new Point(Dpi.Width3, Dpi.Height3),
});
path.CloseFigure();
path.AddLines(new Point[]
{
new Point(Dpi.Width4, Dpi.Height3),
new Point(10000, Dpi.Height3),
new Point(10000, Dpi.Height4),
new Point(Dpi.Width4, Dpi.Height4),
new Point(Dpi.Width4, Dpi.Height3),
});
path.CloseFigure();
Region rgn = new Region(path);
_separatorFw.Region = rgn;
}
}
}
#endregion
#region StopReorder
private void StopReorder()
{
IsReordering = false;
if (_headerFw != null)
{
_headerFw.Close();
_headerFw.Paint -= RowHeaderFwPaint;
_headerFw.Dispose();
_headerFw = null;
}
if (_separatorFw != null)
{
_separatorFw.Close();
_separatorFw.Dispose();
_separatorFw = null;
}
}
#endregion
#region ContinueReorder
private void ContinueReorder(GridPanel panel, Point pt)
{
GridContainer row = _HitItem;
if (row != null)
{
ReorderHeader(pt);
GridContainer mcont =
_MouseDownHitRow.Parent as GridContainer;
GridContainer ncont =
row.Parent as GridContainer;
if (mcont != null && ncont != null)
{
if (mcont == ncont ||
(panel.RowDragBehavior == RowDragBehavior.GroupMove))
{
int n = ncont.Rows.IndexOf(row);
int m = mcont.Rows.IndexOf(_MouseDownHitRow);
if (m >= 0 && n >= 0)
{
if (_MouseDownHitRow.IsVFrozen == row.IsVFrozen)
ReorderSeparator(panel, pt);
}
}
}
}
}
#region ReorderHeader
private void ReorderHeader(Point pt)
{
GridPanel panel = GridPanel;
if (panel != null)
{
Rectangle r = BoundsRelative;
r.Location = PointToScroll(panel, r.Location);
if (r.Height <= 0)
{
_headerFw.Hide();
}
else
{
Size size = _headerFw.Size;
Rectangle t = panel.IsSubPanel ? SViewRect : ViewRect;
if (r.X < t.X)
r.X = t.X;
if (r.Right > t.Right)
r.Width -= (r.Right - t.Right);
r.Height = _MouseDownHitRow.ContainerBounds.Height;
r.Height = Math.Min(r.Height, panel.MaxRowHeight);
r.Y = pt.Y - (r.Height / 2);
r.Location = SuperGrid.PointToScreen(r.Location);
_headerFw.Bounds = r;
if (_headerFw.Visible == false)
_headerFw.Show();
else if (r.Size.Equals(size) == false)
_headerFw.Refresh();
}
}
}
#endregion
#region ReorderSeparator
private void ReorderSeparator(GridPanel panel, Point pt)
{
GridContainer row = _HitItem;
if (row != null &&
(row.IsChildOf(_MouseDownHitRow) == false))
{
Rectangle bounds = row.ContainerBounds;
bounds.Location = PointToScroll(panel, bounds.Location);
bool isBottom = (pt.Y > bounds.Y + bounds.Height / 2);
bool isControlDown = (Control.ModifierKeys & Keys.Control) == Keys.Control;
if (IsControlDown != isControlDown ||
_SeparatorRow != row || IsSeparatorAtBottom != isBottom)
{
if (isBottom == false || panel.ShowInsertRow == false)
{
_SeparatorRow = row;
IsSeparatorAtBottom = isBottom;
IsControlDown = isControlDown;
Rectangle r = bounds;
r.Y += isBottom ? row.FixedRowHeight - Dpi.Width4 : -Dpi.Width4;
Rectangle t = SViewRect;
if (r.X < t.X)
r.X = t.X;
int level = row.IndentLevel;
if (IsSeparatorAtBottom == true && isControlDown == true)
level++;
int n = Dpi.Width(level * panel.LevelIndentSize.Width + 1);
r.X += n;
r.Width -= n;
if (r.Right > t.Right)
r.Width -= (r.Right - t.Right);
if (IsVFrozen == true || (r.Y + 4 >= t.Y && r.Y < t.Bottom))
{
r.Location = SuperGrid.PointToScreen(r.Location);
_separatorFw.Show();
_separatorFw.Location = r.Location;
_separatorFw.Width = r.Width;
}
}
}
}
else
{
_SeparatorRow = null;
if (_separatorFw != null)
_separatorFw.Hide();
}
}
#endregion
#endregion
#region ReorderRow
private void ReorderRow(GridPanel panel)
{
if ((_MouseDownHitRow != _SeparatorRow) &&
(_MouseDownHitRow != null && _SeparatorRow != null))
{
if (_SeparatorRow.IsChildOf(_MouseDownHitRow) == false)
{
GridContainer mcont = _MouseDownHitRow.Parent as GridContainer;
GridContainer ncont = _SeparatorRow.Parent as GridContainer;
if (mcont != null && ncont != null)
{
int n = ncont.Rows.IndexOf(_SeparatorRow);
int m = mcont.Rows.IndexOf(_MouseDownHitRow);
if (panel.RowDragBehavior == RowDragBehavior.GroupMove)
{
if (IsSeparatorAtBottom == true &&
((Control.ModifierKeys & Keys.Control) == Keys.Control))
{
n = 0;
ncont = _SeparatorRow;
IsSeparatorAtBottom = false;
}
}
if (m >= 0 && n >= 0)
{
if (ncont == mcont)
{
if (n > m && IsSeparatorAtBottom == false)
n--;
else if (m > n && IsSeparatorAtBottom == true)
n++;
if (m == n)
return;
}
else
{
if (IsSeparatorAtBottom == true)
n++;
}
if (SuperGrid.DoRowMovingEvent(this, mcont, m, ref ncont, ref n) == false)
{
_MouseDownHitRow.IsSelected = false;
mcont.Rows.RemoveAt(m);
ncont.Rows.Insert(n, _MouseDownHitRow);
panel.UpdateIndicees(panel, panel.Rows, true);
if (_MouseDownHitRow.IsExpandedVisible == true)
_MouseDownHitRow.SetActive(true);
ncont.InvalidateRender();
SuperGrid.DoRowMovedEvent(
mcont.GridPanel, mcont, _MouseDownHitRow);
}
}
}
}
}
}
#endregion
#endregion
#region RowHeaderFwPaint
void RowHeaderFwPaint(object sender, PaintEventArgs e)
{
Rectangle r = _headerFw.ClientRectangle;
if (_MouseDownHitRow != null)
{
GridPanel panel = GridPanel;
if (panel != null)
{
GridPanelVisualStyle pstyle = panel.GetEffectiveStyle();
RenderRowHeader(e.Graphics, panel, _MouseDownHitRow, pstyle, r, false);
}
}
r.Width--;
r.Height--;
e.Graphics.DrawRectangle(Pens.DimGray, r);
}
#endregion
#endregion
#region ExtendSelection
internal void ExtendSelection(GridPanel panel)
{
_HitItem = this;
_MouseDownHitRow = _HitItem;
_MouseDownHitArea = RowArea.InContent;
InvalidateRowHeader(_MouseDownHitRow);
ProcessExtendSelection(panel, false);
}
#endregion
#region GetHitArea
///<summary>
/// This routine gets the RowArea 'HitArea' containing the
/// given point (e.g. InCellCheckBox, InCellExpand, InRowHeader, etc).
///</summary>
///<param name="pt"></param>
///<returns></returns>
public RowArea GetHitArea(Point pt)
{
GridPanel panel = GridPanel;
if (panel != null)
{
_HitItem = this;
Rectangle r = BoundsRelative;
r.Height = FixedRowHeight;
if (panel.IsSubPanel == true)
r.X -= HScrollOffset;
if (IsVFrozen == false)
r.Y -= VScrollOffset;
if (r.Contains(pt))
return (GetRowHitArea(pt, panel, r));
return (GetItemHitArea(pt, panel));
}
return (RowArea.NoWhere);
}
#region GetRowHitArea
private RowArea GetRowHitArea(
Point pt, GridPanel panel, Rectangle r)
{
if (panel.ShowRowHeaders == true)
{
if (pt.X >= r.X && pt.X < r.X + panel.RowHeaderWidthEx)
return (GetRowHeaderArea(pt, panel, r));
}
GridColumn column = panel.PrimaryColumn;
if (column != null && column.Visible == true)
{
Rectangle t = _ExpandButtonBounds;
if (IsVFrozen == false)
t.Y -= VScrollOffset;
if (panel.IsSubPanel == true || column.IsHFrozen == false)
t.X -= HScrollOffset;
if (t.Contains(pt) == true)
return (RowArea.InCellExpand);
if (CanModify == true)
{
t = CheckBoxBounds;
if (IsVFrozen == false)
t.Y -= VScrollOffset;
if (panel.IsSubPanel == true || column.IsHFrozen == false)
t.X -= HScrollOffset;
if (t.Contains(pt) == true)
return (RowArea.InCellCheckBox);
}
column = panel.Columns.LastVisibleColumn;
t = column.BoundsRelative;
t.Location = PointToScroll(panel, t.Location);
if (pt.X > t.Right)
return (RowArea.InWhiteSpace);
}
return (RowArea.InContent);
}
#endregion
#region GetRowHeaderArea
private RowArea GetRowHeaderArea(
Point pt, GridPanel panel, Rectangle r)
{
if (InfoImageBounds.Contains(pt) == true)
return (RowArea.InRowInfo);
if (panel.AllowRowResize == true)
{
if (pt.Y > r.Bottom - Dpi.Height6)
return (RowArea.InRowResize);
}
return (RowArea.InRowHeader);
}
#endregion
#region GetItemHitArea
private RowArea GetItemHitArea(Point pt, GridPanel panel)
{
_HitItem = GetRowElementAt(pt.X, pt.Y, false) as GridContainer;
if (_HitItem != null)
{
Rectangle t = SViewRect;
GridPanel ipanel = _HitItem as GridPanel;
if (ipanel != null)
{
Rectangle bounds = ipanel.BoundsRelative;
bounds.X -= HScrollOffset;
if (IsVFrozen == false)
bounds.Y -= VScrollOffset;
if (bounds.X < t.X)
{
bounds.Width -= (t.X - bounds.X);
bounds.X = t.X;
}
if (bounds.Contains(pt))
return (RowArea.InSubItem);
if (panel.ShowRowHeaders == true)
{
Rectangle r = ipanel.ContainerBounds;
r.Width = panel.RowHeaderWidthEx;
if (panel.IsSubPanel == true)
r.X -= HScrollOffset;
if (IsVFrozen == false)
r.Y -= VScrollOffset;
if (r.Contains(pt))
return (RowArea.InRowHeader);
}
if (ipanel.HasCheckBox == true && panel.ReadOnly == false)
{
Rectangle r = ipanel.CheckBoxBounds;
r.Location = PointToScroll(ipanel, r.Location);
if (r.Contains(pt) == true)
return (RowArea.InRowCheckBox);
}
}
else
{
return (RowArea.InSubItem);
}
}
return (RowArea.InContent);
}
#endregion
#endregion
#region GetElementAt
/// <summary>
/// Gets the row element containing the given coordinates.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns>Element or null</returns>
public override GridElement GetElementAt(int x, int y)
{
return (GetRowElementAt(x, y, true));
}
#endregion
#region GetRowElementAt
internal GridElement GetRowElementAt(int x, int y, bool clip)
{
GridPanel panel = GridPanel;
if (panel != null)
{
Rectangle r = BoundsRelative;
r.Height = FixedRowHeight;
if (IsVFrozen == false)
r.Y -= VScrollOffset;
if (panel.IsSubPanel == true)
r.X -= HScrollOffset;
if (r.Contains(x, y))
{
GridCell cell = GetCellAt(panel, x, y);
if (cell != null)
return (cell);
}
else
{
return (base.GetElementAt(x, y));
}
}
return (null);
}
#endregion
#region GetCellAt
/// <summary>
/// Returns element at specified mouse coordinates
/// </summary>
/// <param name="panel"></param>
/// <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>
protected virtual GridCell GetCellAt(GridPanel panel, int x, int y)
{
bool isFrozen = IsVFrozen;
Rectangle t = SViewRect;
int[] map = panel.Columns.DisplayIndexMap;
for (int i = 0; i < map.Length; i++)
{
int index = map[i];
GridColumn column = panel.Columns[index];
if (column.Visible == true)
{
if (index < _Cells.Count)
{
Rectangle bounds = _Cells[index].BoundsRelative;
if (panel.IsSubPanel == true || column.IsHFrozen == false)
bounds.X -= HScrollOffset;
if (isFrozen == false)
{
bounds.Y -= VScrollOffset;
bounds.Intersect(t);
}
if (bounds.Contains(x, y))
return (_Cells[index]);
}
else
{
Rectangle r = column.BoundsRelative;
r.Y = BoundsRelative.Y;
r.Height = BoundsRelative.Height;
Rectangle bounds = r;
if (panel.IsSubPanel == true || column.IsHFrozen == false)
bounds.X -= HScrollOffset;
if (isFrozen == false)
{
bounds.Y -= VScrollOffset;
bounds.Intersect(t);
}
if (bounds.Contains(x, y))
return (GetEmptySelectionCell(column));
}
}
}
return (null);
}
#region GetEmptySelectionCell
private GridCell GetEmptySelectionCell(GridColumn column)
{
if (_EmptySelectionCell == null ||
_EmptySelectionCell.ColumnIndex != column.ColumnIndex)
{
_EmptySelectionCell = new GridCell();
}
_EmptySelectionCell =
GetEmptyCell(_EmptySelectionCell, column.ColumnIndex);
return (_EmptySelectionCell);
}
#endregion
#endregion
#region GetRowAt
private GridContainer GetRowAt(GridPanel panel, Point pt)
{
Rectangle r = panel.ContainerBounds;
r.X -= HScrollOffset;
if (pt.X < r.X)
pt.X = r.X;
GridContainer row = panel;
GridElement item = row.InternalGetElementAt(pt.X, pt.Y);
while (item != null)
{
row = item as GridContainer;
if (row == null)
break;
if (row is GridRow)
item = ((GridRow)row).GetRowElementAt(pt.X, pt.Y, false);
else
item = row.GetElementAt(pt.X, pt.Y);
if (item is GridContainer == false)
return (row);
}
return (null);
}
#endregion
#region CreateItemsCollection
/// <summary>
/// Creates the GridItemsCollection that hosts the items.
/// </summary>
/// <returns>New instance of GridItemsCollection.</returns>
protected override GridItemsCollection CreateItemsCollection()
{
GridItemsCollection items = new GridItemsCollection();
items.CollectionChanged += ItemsCollectionChanged;
return (items);
}
#endregion
#region DisposeItemsCollection
/// <summary>
/// DisposeItemsCollection
/// </summary>
/// <param name="items"></param>
protected override void DisposeItemsCollection(GridItemsCollection items)
{
items.CollectionChanged -= ItemsCollectionChanged;
}
#endregion
#region ItemsCollectionChanged
void ItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
GridPanel panel = GridPanel;
bool dataRowChange = false;
switch (e.Action)
{
case NotifyCollectionChangedAction.Replace:
case NotifyCollectionChangedAction.Add:
foreach (GridElement item in e.NewItems)
{
if (panel != null && panel.VirtualMode == true)
throw new Exception("Virtual Grid can not have nested items.");
item.Parent = this;
item.NeedsMeasured = true;
if (panel != null)
{
GridRow row = item as GridRow;
if (row != null)
{
dataRowChange = true;
if (e.Action == NotifyCollectionChangedAction.Replace)
panel.RemoveFromExpDictionary(row);
panel.AddToExpDictionary(row);
}
else
{
panel.NeedToUpdateIndicees = true;
}
if (SuperGrid.IsUpdateSuspended == false && panel.IsSorting == false)
panel.ExpandDeletedAtIndex(FullIndex + 1, 1);
panel.NeedToUpdateIndicees = true;
}
}
if (dataRowChange == true && panel.GroupColumns.Count > 0)
panel.NeedsGrouped = true;
break;
case NotifyCollectionChangedAction.Reset:
if (panel != null)
{
dataRowChange = true;
panel.ClearAll();
if (panel.IsSorting == false)
panel.ExpDictionary.Clear();
}
break;
case NotifyCollectionChangedAction.Remove:
if (panel != null)
{
dataRowChange = true;
panel.ClearAll();
if (panel.ExpDictionary.Count > 0)
{
foreach (GridContainer item in e.OldItems)
panel.RemoveFromExpDictionary(item as GridRow);
}
}
break;
}
InvalidateMerge();
if (dataRowChange == true)
{
panel.UpdateRowCount();
SuperGrid.Invalidate();
}
}
#endregion
#region CellsCollectionChanged
void CellsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
GridPanel panel = GridPanel;
switch (e.Action)
{
case NotifyCollectionChangedAction.Replace:
case NotifyCollectionChangedAction.Add:
if (e.Action == NotifyCollectionChangedAction.Replace)
{
for (int i = 0; i < e.OldItems.Count; i++)
{
GridCell cell = e.OldItems[i] as GridCell;
if (cell != null)
{
if (panel.ExpDictionary.ContainsKey(cell))
panel.ExpDictionary.Remove(cell);
}
}
}
for (int i = 0; i < e.NewItems.Count; i++)
{
GridCell cell = e.NewItems[i] as GridCell;
if (cell != null)
{
cell.Parent = this;
cell.ColumnIndex = e.NewStartingIndex + i;
if (panel != null)
{
string newExp = cell.Value as string;
if (newExp != null)
{
newExp = newExp.Trim();
if (newExp.StartsWith("="))
cell.SetCellExp(panel, newExp);
}
}
}
}
break;
default:
for (int i = 0; i < _Cells.Count; i++)
_Cells[i].Parent = this;
break;
}
for (int i = 0; i < _Cells.Count; i++)
_Cells[i].ColumnIndex = i;
if (SuperGrid != null)
{
GridCell cell = SuperGrid.ActiveElement as GridCell;
if (cell != null)
{
if (cell.GridRow == this && cell.ColumnIndex < Cells.Count)
SuperGrid.ActiveElement = Cells[cell.ColumnIndex];
}
}
NeedsMeasured = true;
if (panel != null && panel.VirtualMode == false)
InvalidateMerge();
}
#endregion
#region GetNextVisibleCell
///<summary>
/// This routine returns the next visible cell in the
/// row, after the given cell. If the given cell is null,
/// the first visible cell in the row will be returned.
///</summary>
///<param name="cell"></param>
///<returns>Next cell, or null</returns>
///<exception cref="Exception"></exception>
public GridCell GetNextVisibleCell(GridCell cell)
{
GridPanel panel = GridPanel;
if (panel != null)
{
GridColumn column;
if (cell != null)
{
if (cell.Parent != this)
throw new Exception("Cell is not a member of this row.");
column = cell.GridColumn;
if (column != null)
column = panel.Columns.GetNextVisibleColumn(column);
}
else
{
column = panel.FirstVisibleColumn;
}
if (column != null)
return (GetCell(column.ColumnIndex, panel.AllowEmptyCellSelection));
}
return (null);
}
#endregion
#region GetPrevVisibleCell
///<summary>
/// This routine returns the previous visible cell in the
/// row, prior to the given cell. If the given cell is null,
/// the last visible cell in the row will be returned.
///</summary>
///<param name="cell"></param>
///<returns>Previous cell, or null</returns>
///<exception cref="Exception"></exception>
public GridCell GetPrevVisibleCell(GridCell cell)
{
GridPanel panel = GridPanel;
if (panel != null)
{
GridColumn column;
if (cell != null)
{
if (cell.Parent != this)
throw new Exception("Cell is not a member of this row.");
column = cell.GridColumn;
if (column != null)
column = panel.Columns.GetPrevVisibleColumn(column);
}
else
{
column = panel.LastVisibleColumn;
}
if (column != null)
return (GetCell(column.ColumnIndex, panel.AllowEmptyCellSelection));
}
return (null);
}
#endregion
#region GetRowHeight
internal int GetRowHeight()
{
return (Dpi.Height(GetRowHeightEx()));
}
internal int GetRowHeightEx()
{
if (_RowHeight >= 0)
return (_RowHeight);
GridPanel panel = GridPanel;
if (panel != null)
return (panel.DefaultRowHeight);
return (20);
}
#endregion
#region GetRowPreDetailHeight
internal int GetRowPreDetailHeight()
{
if (_PreDetailRowHeight >= 0)
return (_PreDetailRowHeight);
GridPanel panel = GridPanel;
if (panel != null)
return (panel.DefaultPreDetailRowHeight);
return (0);
}
#endregion
#region GetRowPostDetailHeight
internal int GetRowPostDetailHeight()
{
if (_PostDetailRowHeight >= 0)
return (_PostDetailRowHeight);
GridPanel panel = GridPanel;
if (panel != null)
return (panel.DefaultPostDetailRowHeight);
return (0);
}
#endregion
#region GetMaximumRowHeight
///<summary>
/// This routine calculates and returns the maximum
/// row height based upon the individual measured heights
/// of each visible cell in the row.
///</summary>
///<returns></returns>
public int GetMaximumRowHeight()
{
GridPanel panel = GridPanel;
if (panel != null)
{
GridColumn[] columns = new GridColumn[panel.Columns.Count];
int n = 0;
for (int i = 0; i < panel.Columns.Count; i++)
{
if (panel.Columns[i].Visible == true)
columns[n++] = panel.Columns[i];
}
return (GetMaximumRowHeight(columns));
}
return (GetRowHeight());
}
///<summary>
/// This routine calculates and returns the maximum
/// row height based upon the individual measured heights
/// of each cell in the row, based upon the given array of
/// columns to included in the calculation process.
///</summary>
///<returns></returns>
public int GetMaximumRowHeight(GridColumn[] columns)
{
GridPanel panel = GridPanel;
if (panel != null)
{
int maxHeight = 0;
using (Graphics g = SuperGrid.CreateGraphics())
{
GridLayoutInfo layoutInfo = new GridLayoutInfo(g, panel.BoundsRelative);
GridLayoutStateInfo layoutState = new GridLayoutStateInfo(panel, 0);
foreach (GridColumn column in columns)
{
if (column != null &&
column.ColumnIndex < Cells.Count)
{
GridCell cell = Cells[column.ColumnIndex];
if (cell != null)
{
Size oldSize = cell.Size;
cell.Measure(layoutInfo, layoutState, new Size(column.Width, 0));
if (cell.Size.Height > maxHeight)
maxHeight = cell.Size.Height;
cell.Size = oldSize;
}
}
}
}
if (maxHeight > 0)
return (maxHeight);
}
return (GetRowHeight());
}
#endregion
#region PointToScroll
internal Point PointToScroll(GridPanel panel, Point pt)
{
pt.X -= HScrollOffset;
if (IsVFrozen == false)
pt.Y -= VScrollOffset;
return (pt);
}
#endregion
#region FlushRow
internal override void FlushRow()
{
GridPanel panel = GridPanel;
if (panel != null)
{
if (RowNeedsStored == true)
{
RowNeedsStored = false;
panel.DataBinder.FlushRow();
if (panel.NeedToUpdateDataFilter == true)
DataFilter.UpdateRowFilterState(panel, this);
if (panel.VirtualMode == true)
SuperGrid.DoStoreVirtualRowEvent(panel, this);
if (RowNeedsSorted == true ||
IsTempInsertRow == true || IsInsertRow == true)
{
RowNeedsSorted = false;
if (panel.VirtualMode == true)
{
panel.VirtualRows.Clear();
panel.InvalidateMerge();
panel.DataBinder.UpdateDataSourceSort();
}
else
{
panel.UpdateRowPosition(this);
}
panel.DataBinder.SetPosition(this);
}
}
}
base.FlushRow();
}
#endregion
/// <summary>
/// Reloads the row with the current external DataSource data.
/// </summary>
public void ReloadRow()
{
GridPanel panel = GridPanel;
if (panel != null)
panel.DataBinder.ReloadRow(this);
}
#region ProcessNewRowChange
private void ProcessNewRowChange(GridPanel panel)
{
if (panel.ShowInsertRow == true)
{
if (IsInsertRow == true)
{
panel.AddNewInsertRow();
SuperGrid.DoRowAddedEvent(panel, panel.Rows.Count - 2);
panel.InvalidateMerge();
}
}
}
#endregion
#region CancelCapture
/// <summary>
/// Cancels any inprogress operations (resize, reorder)
/// that may have the mouse captured.
/// </summary>
public override void CancelCapture()
{
StopReorder();
StopResize();
base.CancelCapture();
}
#endregion
#region Style support
internal void ApplyCellStyle(CellVisualStyle style, StyleType cs)
{
ValidateStyle();
if (_EffectiveCellStyles == null)
_EffectiveCellStyles = new CellVisualStyles();
if (_EffectiveCellStyles.IsValid(cs) == false)
{
GridPanel panel = GridPanel;
int rowIndex = panel.UseAlternateRowStyle ? GridIndex : -1;
if (rowIndex >= 0 && Parent is GridGroup)
rowIndex -= ((GridGroup)Parent).GridIndex + 1;
CellVisualStyle cstyle = new CellVisualStyle();
if ((rowIndex % 2) > 0)
{
cstyle.ApplyStyle(SuperGrid.BaseVisualStyles.AlternateRowCellStyles[cs]);
cstyle.ApplyStyle(SuperGrid.DefaultVisualStyles.AlternateRowCellStyles[cs]);
cstyle.ApplyStyle(GridPanel.DefaultVisualStyles.AlternateRowCellStyles[cs]);
}
cstyle.ApplyStyle(CellStyles[cs]);
SuperGrid.DoGetRowCellStyleEvent(this, cs, ref cstyle);
_EffectiveCellStyles[cs] = cstyle;
}
style.ApplyStyle(_EffectiveCellStyles[cs]);
}
#region ValidateStyle
private void ValidateStyle()
{
if (_StyleUpdateCount != SuperGrid.StyleUpdateCount)
{
if (_EffectiveCellStyles != null)
{
_EffectiveCellStyles.Dispose();
_EffectiveCellStyles = null;
}
_StyleUpdateCount = SuperGrid.StyleUpdateCount;
}
}
#endregion
#region InvalidateCellStyle
///<summary>
///Invalidates the cached Style
///definition for all defined StyleTypes
///</summary>
public void InvalidateCellStyle()
{
if (_EffectiveCellStyles != null)
{
_EffectiveCellStyles.Dispose();
_EffectiveCellStyles = null;
}
foreach (GridCell cell in Cells)
cell.InvalidateStyle();
InvalidateLayout();
}
///<summary>
///Invalidate the cached Style
///definition for the given StyleType
///</summary>
///<param name="type"></param>
public void InvalidateCellStyle(StyleType type)
{
if (_EffectiveCellStyles != null)
{
if (_EffectiveCellStyles[type] != null)
{
_EffectiveCellStyles[type].Dispose();
_EffectiveCellStyles[type] = null;
}
}
foreach (GridCell cell in Cells)
cell.InvalidateStyle();
InvalidateLayout();
}
#endregion
#endregion
#region InvalidateRender
/// <summary>
/// InvalidateRender
/// </summary>
public override void InvalidateRender()
{
base.InvalidateRender();
foreach (GridCell cell in Cells)
cell.InvalidateRender();
}
/// <summary>
/// InvalidateRender
/// </summary>
/// <param name="bounds"></param>
public override void InvalidateRender(Rectangle bounds)
{
base.InvalidateRender(bounds);
foreach (GridCell cell in Cells)
cell.InvalidateRender();
}
#endregion
#region ToString
/// <summary>
/// ToString
/// </summary>
/// <returns></returns>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
GridPanel panel = GridPanel;
if (panel != null)
{
sb.Append("GridRow");
if (_Cells.Count > 0)
{
sb.Append(" {");
foreach (GridCell cell in _Cells)
{
sb.Append(cell.Value == null ? "<null>" : cell.Value.ToString());
sb.Append(", ");
}
sb.Length -= 2;
sb.Append("}");
}
}
return (sb.ToString());
}
#endregion
#region IDisposable Members
/// <summary>
/// Dispose
/// </summary>
public override void Dispose()
{
if (_EffectiveCellStyles != null)
{
_EffectiveCellStyles.Dispose();
_EffectiveCellStyles = null;
}
if (_Cells != null)
{
foreach (GridCell cell in _Cells)
{
if (cell != null)
cell.Dispose();
}
_Cells.CollectionChanged -= CellsCollectionChanged;
}
DetachNestedRows(true);
Rows = null;
base.Dispose();
}
#endregion
#region RowStates
[Flags]
private enum Rs
{
AllowEdit = (1<<0),
EditorDirty = (1<<1),
ControlDown = (1<<2),
DetailRow = (1<<3),
TempInsertRow = (1<<4),
Loading = (1<<5),
Resizing = (1<<6),
Reordering = (1<<7),
RowDirty = (1<<8),
RowFilteredOut = (1<<9),
RowCheckChanged = (1 << 10),
RowNeedsGrouped = (1 << 11),
RowNeedsSorted = (1<<12),
RowNeedsStored = (1<<13),
SeparatorAtBottom = (1<<14),
Visible = (1<<15),
}
#endregion
}
#region enums
#region RowArea
///<summary>
/// RowArea
///</summary>
public enum RowArea
{
///<summary>
/// NoWhere
///</summary>
NoWhere,
///<summary>
/// InCellCheckBox
///</summary>
InCellCheckBox,
///<summary>
/// InCellExpand
///</summary>
InCellExpand,
///<summary>
/// InRowCheckBox
///</summary>
InRowCheckBox,
///<summary>
/// InRowHeader
///</summary>
InRowHeader,
///<summary>
/// InRowInfo
///</summary>
InRowInfo,
///<summary>
/// InRowResize
///</summary>
InRowResize,
///<summary>
/// InContent
///</summary>
InContent,
///<summary>
/// InSubItem
///</summary>
InSubItem,
///<summary>
/// InWhiteSpace
///</summary>
InWhiteSpace,
}
#endregion
#region RowDoubleClickBehavior
///<summary>
/// Indicates what happens when a row is double clicked
///</summary>
public enum RowDoubleClickBehavior
{
///<summary>
/// The row is activated
///</summary>
Activate,
///<summary>
/// The row is expanded or collapsed
///</summary>
ExpandCollapse,
}
#endregion
#endregion
}