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 { /// /// Represents a grid row consisting of one or more grid cells. /// 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 /// /// Creates a new GridRow /// public GridRow() { SetState(Rs.AllowEdit, true); SetState(Rs.Visible, true); _Cells = new GridCellCollection(); _Cells.CollectionChanged += CellsCollectionChanged; } /// /// Creates a new GridRow /// /// public GridRow(string text) : this() { GridCell cell = new GridCell(); cell.Value = text; _Cells.Add(cell); } /// /// Creates a new GridRow /// /// public GridRow(IEnumerable cells) : this() { foreach (GridCell cell in cells) _Cells.Add(cell); } /// /// Creates a new GridRow /// /// public GridRow(IEnumerable values) : this() { foreach (object o in values) _Cells.Add(new GridCell(o)); } /// /// Creates a new GridRow /// /// public GridRow(params object[] values) : this() { foreach (object o in values) _Cells.Add(new GridCell(o)); } #endregion #region Public properties #region AllowEdit /// /// Gets or sets whether the row cells can be edited by the user. /// [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 /// /// Gets the scroll adjusted bounds of the row /// [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 /// /// Gets or sets the row CheckBox checked state /// [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 /// /// 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. /// [DefaultValue(null), Category("Data")] [Description("Indicates a reference to the Cells collection.")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public GridCellCollection Cells { get { return (_Cells); } } #endregion #region DataItem /// /// Gets the object to which the row is bound. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public object DataItem { get { return (_DataItem); } internal set { _DataItem = value; } } #endregion #region EditorDirty /// /// Gets or sets whether the value being edited has changed. /// [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 /// /// Gets the effective height of the "pre detail" portion of the /// row (the area at the bottom of the row). /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int EffectivePreDetailRowHeight { get { return (_EffectivePreDetailRowHeight); } } #endregion #region EffectivePostDetailRowHeight /// /// Gets the effective height of the "post detail" portion of the /// row (the area at the bottom of the row). /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int EffectivePostDetailRowHeight { get { return (_EffectivePostDetailRowHeight); } } #endregion #region FirstFrozenCell /// /// Gets a reference to the first Frozen cell /// or null if there is none. /// [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 /// /// Gets a reference to the first on-screen cell /// (after frozen columns) or null if there is none. /// [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 /// /// Gets a reference to the first selectable cell /// or null if there is none defined. /// [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 /// /// Gets a reference to the first visible cell /// or null if there is none defined. /// [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) /// /// Gets or sets Cell item at the given Column /// /// Column containing the cell [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public GridCell this[GridColumn column] { get { return (this[column.ColumnIndex]); } } #endregion #region Indexer (int) /// /// Gets or sets Cell item at the given Column /// /// Column containing the cell [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public GridCell this[int columnIndex] { get { if (columnIndex < Cells.Count) return (Cells[columnIndex]); return (null); } } #endregion #region Indexer (string) /// /// Gets or sets Cell item at ColumnName index /// /// Name of Column containing the cell [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public GridCell this[string columnName] { get { return (FindCell(columnName)); } } #endregion #region InfoImageBounds /// /// Gets the bounds of the InfoImage /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Rectangle InfoImageBounds { get { return (_InfoImageBounds); } internal set { _InfoImageBounds = value; } } #endregion #region InfoText /// /// 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. /// [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 /// /// Gets or sets whether the row has been marked as deleted. /// [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 /// /// Gets whether the row is marked as a Group Detail row. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsDetailRow { get { return (TestState(Rs.DetailRow)); } internal set { SetState(Rs.DetailRow, value); } } #endregion #region IsInsertRow /// /// Gets whether the row is the Insert Row. /// [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 /// /// Gets whether the row is a temporary insert Row (created via editing the Insert Row) /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsTempInsertRow { get { return (TestState(Rs.TempInsertRow)); } internal set { SetState(Rs.TempInsertRow, value); } } #endregion #region LastFrozenCell /// /// Gets a reference to the last Frozen cell /// or null if there is none. /// [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 /// /// Gets a reference to the last on-screen cell /// or null if there is none. /// [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 /// /// Gets a reference to the last selectable cell /// or null if there is none defined. /// [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 /// /// Gets a reference to the last visible cell /// or null if there is none defined. /// [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 /// /// Gets or sets whether the row state has changed. /// [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 /// /// Gets whether the row has been filtered out. /// [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 /// /// Gets or sets the height of the row (0 denotes AutoSize, -1 denotes NotSet). /// [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 /// /// Gets or sets the height of the "post detail" portion of the /// row (the area at the bottom of the row). -1 denotes NotSet. /// [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 /// /// Gets or sets the height of the "pre detail" portion of the /// row (the area at the bottom of the row). -1 denotes NotSet. /// [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 /// /// Gets an array of the currently Selected Cells. /// [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 /// /// Gets or sets whether the row is visible. /// [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 /// /// Gets the row WhiteSpace Bounds (the area /// past the end of the last defined column). /// [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 /// /// RowCheckChanged /// 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 /// /// RowNeedsGrouped /// internal bool RowNeedsGrouped { get { return (TestState(Rs.RowNeedsGrouped)); } set { SetState(Rs.RowNeedsGrouped, value); } } #endregion #region RowNeedsSorted /// /// RowNeedsSorted /// internal bool RowNeedsSorted { get { return (TestState(Rs.RowNeedsSorted)); } set { SetState(Rs.RowNeedsSorted, value); } } #endregion #region RowNeedsStored /// /// RowNeedsStored /// 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 /// /// Performs the layout of the item /// and sets the Size property to size that item will take. /// /// Layout information. /// /// 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 /// /// Performs the arrange pass layout of the /// item when final position and size of the item has been set. /// /// Layout information. /// /// Layout bounds 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 /// /// Performs drawing of the item and its children /// /// Holds contextual rendering information. 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 /// /// RenderRowHeader /// /// /// /// /// /// 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 /// /// RenderSubItems /// /// /// /// /// /// 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 /// /// RenderRowBackground /// /// /// /// 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 /// /// RenderRowCheckBox /// /// /// /// 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 /// /// RenderRowBorder /// /// /// /// 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 /// /// Gets the Row Cell for the given column index. If /// the cell does not exist,then null will be returned. /// /// /// public GridCell GetCell(int columnIndex) { return (GetCell(columnIndex, false)); } /// /// Gets the Row Cell for the given column name. If /// the cell does not exist, null will be returned. /// /// /// public GridCell GetCell(string name) { return (FindCell(name)); } /// /// 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. /// /// /// /// 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 /// /// InternalMouseEnter /// /// 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 /// /// InternalMouseLeave /// /// 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 /// /// InternalMouseMove /// /// 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 /// /// InternalMouseDown /// /// 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 /// /// InternalMouseUp /// /// 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 /// /// This routine gets the RowArea 'HitArea' containing the /// given point (e.g. InCellCheckBox, InCellExpand, InRowHeader, etc). /// /// /// 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 /// /// Gets the row element containing the given coordinates. /// /// /// /// Element or null 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 /// /// Returns element at specified mouse coordinates /// /// /// Horizontal position /// Vertical position /// Reference to child element or null /// if no element at specified coordinates 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 /// /// Creates the GridItemsCollection that hosts the items. /// /// New instance of GridItemsCollection. protected override GridItemsCollection CreateItemsCollection() { GridItemsCollection items = new GridItemsCollection(); items.CollectionChanged += ItemsCollectionChanged; return (items); } #endregion #region DisposeItemsCollection /// /// DisposeItemsCollection /// /// 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 /// /// 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. /// /// ///Next cell, or null /// 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 /// /// 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. /// /// ///Previous cell, or null /// 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 /// /// This routine calculates and returns the maximum /// row height based upon the individual measured heights /// of each visible cell in the row. /// /// 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()); } /// /// 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. /// /// 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 /// /// Reloads the row with the current external DataSource data. /// 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 /// /// Cancels any inprogress operations (resize, reorder) /// that may have the mouse captured. /// 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 /// ///Invalidates the cached Style ///definition for all defined StyleTypes /// public void InvalidateCellStyle() { if (_EffectiveCellStyles != null) { _EffectiveCellStyles.Dispose(); _EffectiveCellStyles = null; } foreach (GridCell cell in Cells) cell.InvalidateStyle(); InvalidateLayout(); } /// ///Invalidate the cached Style ///definition for the given StyleType /// /// 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 /// /// InvalidateRender /// public override void InvalidateRender() { base.InvalidateRender(); foreach (GridCell cell in Cells) cell.InvalidateRender(); } /// /// InvalidateRender /// /// public override void InvalidateRender(Rectangle bounds) { base.InvalidateRender(bounds); foreach (GridCell cell in Cells) cell.InvalidateRender(); } #endregion #region ToString /// /// ToString /// /// 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 ? "" : cell.Value.ToString()); sb.Append(", "); } sb.Length -= 2; sb.Append("}"); } } return (sb.ToString()); } #endregion #region IDisposable Members /// /// Dispose /// 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 /// /// RowArea /// public enum RowArea { /// /// NoWhere /// NoWhere, /// /// InCellCheckBox /// InCellCheckBox, /// /// InCellExpand /// InCellExpand, /// /// InRowCheckBox /// InRowCheckBox, /// /// InRowHeader /// InRowHeader, /// /// InRowInfo /// InRowInfo, /// /// InRowResize /// InRowResize, /// /// InContent /// InContent, /// /// InSubItem /// InSubItem, /// /// InWhiteSpace /// InWhiteSpace, } #endregion #region RowDoubleClickBehavior /// /// Indicates what happens when a row is double clicked /// public enum RowDoubleClickBehavior { /// /// The row is activated /// Activate, /// /// The row is expanded or collapsed /// ExpandCollapse, } #endregion #endregion }