using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data.SqlTypes; using System.Drawing; using System.Drawing.Design; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Globalization; using System.Media; using System.Reflection; using System.Windows.Forms; using System.Windows.Forms.VisualStyles; using DevComponents.DotNetBar.SuperGrid.Primitives; using DevComponents.DotNetBar.SuperGrid.Style; using DevComponents.SuperGrid.TextMarkup; namespace DevComponents.DotNetBar.SuperGrid { /// /// Represents grid cell. /// public class GridCell : GridElement, IComparable, IDisposable { #region Constants private const int CheckBoxSpacing = 3; #endregion #region Static variables private static CellInfoWindow _cellInfoWindow; private static CellArea _hitArea; private static CellArea _lastHitArea; private static GridCell _hitCell; private static CellArea _mouseDownHitArea; private static GridCell _mouseDownHitCell; private static Point _mouseDownPoint; private static IGridCellEditControl _mouseRenderer; private static bool _mouseInItem; private static bool _mouseDownInItem; private static bool _needsMouseEnter; private static bool _dragSelection; private static bool _dragStarted; private static int _anchorRowIndex; private static int _anchorColumnIndex; private static string _toolTipText; #endregion #region Private variables private int _ColumnIndex; private int _IndentLevel; private Size _CellSize; private Size _ContentSize; private Size _MeasuredSize; private Rectangle _Bounds; private Rectangle _BackBounds; private string _InfoText; private Image _InfoImage; private Cs _States; private EditorInfo _EditorInfo; private ushort _BoundsUpdateCount; private ushort _ColumnMeasureCount; private ushort _DataResetCount; private ushort _MergeUpdateCount; private ushort _RowMeasureCount; private ushort _SelectionClearCount; private ushort _SelectionUpdateCount; private ushort _StyleUpdateCount; private object _Value; private object _ExpValue; private CellVisualStyles _Styles; private CellVisualStyles _EffectiveStyles; #endregion #region Constructors /// /// GridCell /// public GridCell() { SetState(Cs.AllowEdit, true); } /// /// GridCell /// /// public GridCell(object value) : this() { _Value = value; } #endregion #region Internal properties #region AllowNullMerge internal bool AllowNullMerge { get { Tbool ns = GridColumn.AllowNullCellMerge; if (ns != Tbool.NotSet) return (ns == Tbool.True ? true : false); return (GridPanel.AllowNullCellMerge); } } #endregion #region CanModify internal bool CanModify { get { GridColumn col = GridColumn; if (col == null || (col.AllowEdit == false || col.AllowSelection == false)) return (false); GridRow row = GridRow; if (row == null || (row.AllowEdit == false || row.AllowSelection == false || row.IsDeleted == true)) return (false); GridPanel panel = GridPanel; if (panel == null || (panel.AllowEdit == false || panel.AllowSelection == false)) return (false); if (Visible == false || AllowEdit == false || AllowSelection == false || IsEmptyCell == true || IsReadOnly == true) { return (false); } return (true); } } #endregion #region CanModifyMerge internal bool CanModifyMerge { get { if (CanModify == false) return (false); return (Merged == false || MergeSuspended == true); } } #endregion #region AnySelected internal bool AnySelected { get { return (TestState(Cs.AnySelected)); } set { SetState(Cs.AnySelected, value); } } #endregion #region CellSize internal Size CellSize { get { return (_CellSize); } set { _CellSize = value; } } #endregion #region CellEditMode internal CellEditMode CellEditMode { get { IGridCellEditControl editor = (EditControl ?? (GridColumn != null ? GridColumn.EditControl : null)); if (editor == null) editor = GetInternalEditControl(); if (editor != null) return (editor.CellEditMode); return (CellEditMode.InPlace); } } #endregion #region CheckBoxBounds internal Rectangle CheckBoxBounds { get { return (GridRow.CheckBoxBounds); } } #endregion #region ContentSize internal Size ContentSize { get { return(_ContentSize); } } #endregion #region RowContainer internal GridContainer RowContainer { get { GridRow row = GridRow; if (row != null) return (row.Parent as GridContainer); return (null); } } #endregion #region HitArea internal CellArea HitArea { get { return (_hitArea); } set { _hitArea = value; } } #endregion #region IndentLevel internal int IndentLevel { get { return (_IndentLevel); } set { _IndentLevel = value; } } #endregion #region IsDragSelection internal bool IsDragSelection { get { return (_dragSelection); } set { _dragSelection = value; } } #endregion #region IsDragStarted internal bool IsDragStarted { get { return (_dragStarted); } set { _dragStarted = value; } } #endregion #region MergeUpdateCount internal ushort MergeUpdateCount { get { return (_MergeUpdateCount); } set { _MergeUpdateCount = value; } } #endregion #region MeasuredSize internal Size MeasuredSize { get { return (_MeasuredSize); } } #endregion #region Modified internal bool Modified { get { return (TestState(Cs.Modified)); } set { SetState(Cs.Modified, value); } } #endregion #region MouseRenderer internal IGridCellEditControl MouseRenderer { get { return (_mouseRenderer); } set { _mouseRenderer = value; } } #endregion #region NeedsMeasured internal override bool NeedsMeasured { get { if (_ColumnMeasureCount != GridColumn.MeasureCount) return (true); if (_RowMeasureCount != GridRow.MeasureCount) return (true); return (base.NeedsMeasured); } set { if (value == false) { _ColumnMeasureCount = GridColumn.MeasureCount; _RowMeasureCount = GridRow.MeasureCount; } base.NeedsMeasured = value; } } #endregion #region Selected internal bool Selected { get { if (AllowSelection == false) return (false); GridPanel panel = GridPanel; if (panel != null) { if (_SelectionClearCount != panel.SelectionClearCount) { _SelectionClearCount = panel.SelectionClearCount; Selected = false; if (GridRow.ExpandedVisible(panel) == true) panel.SetSelectedEx(this, false); InvalidateRender(); } } return (TestState(Cs.Selected)); } set { SetState(Cs.Selected, value); GridPanel panel = GridPanel; if (panel != null) _SelectionClearCount = panel.SelectionClearCount; } } #endregion #region SelectionUpdateCount internal ushort SelectionUpdateCount { get { return (_SelectionUpdateCount); } set { _SelectionUpdateCount = value; } } #endregion #region ValueEx internal object ValueEx { get { return (_Value); } set { if ((value != null && value.Equals(_Value) == false) || (value == null && _Value != null)) { object oldValue = _Value; _Value = value; OnValueChanged(oldValue, value, DataContext.CellValueLoad); } } } #endregion #region ValueExx internal object ValueExx { get { return (_Value); } set { _Value = value; } } #endregion #endregion #region Public properties #region AllowEdit /// /// Gets or sets whether the cell can be edited by the user. /// [DefaultValue(true), Category("Behavior")] [Description("Indicates whether the cell can be edited by the user.")] public bool AllowEdit { get { return (TestState(Cs.AllowEdit)); } set { if (value != AllowEdit) { SetState(Cs.AllowEdit, value); OnPropertyChanged("AllowEdit"); } } } #endregion #region BackBounds /// /// Gets the scroll adjusted background bounds of the cell /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Rectangle BackBounds { get { if (_BoundsUpdateCount != SuperGrid.BoundsUpdateCount) UpdateBoundingRects(); return (_BackBounds); } } #endregion #region Bounds /// /// Gets the scroll adjusted bounds of the cell /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override Rectangle Bounds { get { if (_BoundsUpdateCount != SuperGrid.BoundsUpdateCount) UpdateBoundingRects(); GridPanel panel = GridPanel; if (panel != null) { CellRange cr = GetStateCellRange(); if (cr != null) return (GetBounds(panel, cr.BackBounds)); } return (_Bounds); } } #endregion #region BoundsRelative /// /// Gets or sets the relative bounds of the cell /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override Rectangle BoundsRelative { get { return (base.BoundsRelative); } internal set { base.BoundsRelative = value; _BoundsUpdateCount = 0; } } #endregion #region CellBounds /// /// Gets the clipped, scroll adjusted, bounding rectangle of the cell /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Rectangle CellBounds { get { if (_BoundsUpdateCount != SuperGrid.BoundsUpdateCount) UpdateBoundingRects(); GridPanel panel = GridPanel; if (panel != null) return (GetCellBounds(panel)); return (Bounds); } } #endregion #region CellStyles /// /// Gets or sets the visual styles assigned to the cell /// [Category("Style")] [Description("Indicates the visual styles assigned to the cell.")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public CellVisualStyles CellStyles { get { if (_Styles == null) { _Styles = new CellVisualStyles(); StyleVisualChangeHandler(null, _Styles); } return (_Styles); } set { if (_Styles != value) { CellVisualStyles oldValue = _Styles; _Styles = value; OnCellStyleChanged("CellVisualStyles", oldValue, value); if (oldValue != null) oldValue.Dispose(); } } } private void OnCellStyleChanged(string property, CellVisualStyles oldValue, CellVisualStyles newValue) { StyleVisualChangeHandler(oldValue, newValue); OnPropertyChanged(property); } #endregion #region ColumnIndex /// /// Gets the associated Column index for the cell /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int ColumnIndex { get { return (_ColumnIndex); } internal set { _ColumnIndex = value; } } #endregion #region ContentBounds /// /// Gets the scroll adjusted, content only, bounding rectangle of the cell /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Rectangle ContentBounds { get { GridPanel panel = GridPanel; if (panel != null) return (GetContentBounds(panel)); return (Rectangle.Empty); } } #endregion #region EditBounds /// /// Gets the clipped, scroll adjusted, edit bounding rectangle of the cell /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Rectangle EditBounds { get { GridPanel panel = GridPanel; if (panel != null) return (GetEditBounds(panel)); return (Rectangle.Empty); } } #endregion #region EditControl /// /// Gets the Edit Control used for the cell. The cell level /// edit control is a non-shared control, created and based /// upon the cell level EditorType and EditorParams properties. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IGridCellEditControl EditControl { get { if (_EditorInfo == null || _EditorInfo.EditorType == null) return (null); if (_EditorInfo.EditControl == null) EditControl = GetEditControl(_EditorInfo.EditorType, _EditorInfo.EditorParams); return (_EditorInfo.EditControl); } internal set { if (_EditorInfo == null) _EditorInfo = new EditorInfo(); if (_EditorInfo.EditControl != value) { if (_EditorInfo.EditControl != null) { if (_EditorInfo.EditControl.EditorPanel.Parent != null) SuperGrid.Controls.Remove(_EditorInfo.EditControl.EditorPanel); _EditorInfo.EditControl.EditorCellBitmap = null; if (_EditorInfo.EditorType != null) ((Control)_EditorInfo.EditControl).Dispose(); } _EditorInfo.EditControl = value; if (_EditorInfo.EditControl != null) { if (_EditorInfo.EditControl.EditorPanel.Parent == null) SuperGrid.Controls.Add(_EditorInfo.EditControl.EditorPanel); } } } } #endregion #region EditorDirty /// /// Gets or sets whether the value /// being edited has been changed in the editor /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool EditorDirty { get { return (GridRow.EditorDirty); } set { GridRow.EditorDirty = value; // If it is a non-modal edit event then we want the // editor's dirty state to be cleared immediately. if (SuperGrid.EditorActive == false) GridRow.EditorDirty = false; } } #endregion #region EditorParams /// /// Gets or sets an array of arguments that match in number, /// order, and type the parameters of the EditControl constructor /// to invoke. If empty or null, the default constructor is invoked. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public object[] EditorParams { get { if (_EditorInfo == null) return (null); return (_EditorInfo.EditorParams); } set { if (_EditorInfo == null) _EditorInfo = new EditorInfo(); if (IsSameParams(_EditorInfo.EditorParams, value) == false) { _EditorInfo.EditorParams = value; EditControl = null; RenderControl = null; NeedsMeasured = true; OnPropertyChangedEx("EditorParams", VisualChangeType.Layout); } if (_EditorInfo.IsEmpty == true) _EditorInfo = null; } } #region IsSameParams private bool IsSameParams(object[] p1, object[] p2) { if (p1 == null || p2 == null) return (p1 == p2); if (p1.Length != p2.Length) return (false); for (int i = 0; i < p1.Length; i++) { if (p1[i] != p2[i]) return (false); } return (true); } #endregion #endregion #region EditorType /// /// Indicates the cell editor type. This is the control type /// used to perform the actual modification of the cell value /// [DefaultValue(null), Category("Data")] [Description("Indicates the cell editor type. This is the control type used to perform the actual modification of the cell value.")] [TypeConverter(typeof(EditTypeConverter))] [Editor("DevComponents.SuperGrid.Design.EditTypeEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] public Type EditorType { get { if (_EditorInfo == null) return (null); return (_EditorInfo.EditorType); } set { if (value != null || _EditorInfo != null) { if (_EditorInfo == null) _EditorInfo = new EditorInfo(); if (_EditorInfo.EditorType != value) { _EditorInfo.EditorType = value; _EditorInfo.EditControl = null; _EditorInfo.RenderControl = null; NeedsMeasured = true; OnPropertyChangedEx("EditorType", VisualChangeType.Layout); } if (_EditorInfo.IsEmpty == true) _EditorInfo = null; } } } #endregion #region ExpValue /// /// Gets the last evaluated expression value for the cell. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public object ExpValue { get { return (_ExpValue); } } #endregion #region FormattedValue /// /// Gets the associated Formatted Value for the cell /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string FormattedValue { get { return (GetFormattedValue()); } } #endregion #region GridColumn /// /// Gets the GridColumn associated with the cell /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public GridColumn GridColumn { get { GridPanel panel = GridPanel; if (panel == null && GridRow != null) panel = GridRow.AllocPanel; if (panel != null) { if (_ColumnIndex < panel.Columns.Count) return (panel.Columns[_ColumnIndex]); } return (null); } } #endregion #region GridRow /// /// Gets the GridRow associated with the cell. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public GridRow GridRow { get { return (Parent as GridRow); } } #endregion #region HighLightBounds /// /// Gets the scroll adjusted, bounding rectangle used /// to highlight the cell contents when selected. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Rectangle HighLightBounds { get { Rectangle r = Rectangle.Empty; GridPanel panel = GridPanel; if (panel != null) { switch (GetCellHighlightMode(panel)) { case CellHighlightMode.Content: IGridCellEditControl editor = GetInternalRenderControl(); r = GetAdjustedBounds(ContentBounds); r = GetEditPanelBounds(editor, r); r.Inflate(1, 1); break; case CellHighlightMode.Partial: r = GetAdjustedBounds(ContentBounds); r.Inflate(1, 1); break; case CellHighlightMode.Full: r = GetAdjustedBounds(); Rectangle t = SViewRect; if (t.X == 0 && r.X == 0) { r.X += Dpi.Width1; r.Width -= Dpi.Width1; } break; } } return (r); } } #endregion #region InfoImage /// /// Gets or sets the cell informational Image (the image /// to display when InfoText is non-empty) /// [DefaultValue(null), Category("Appearance")] [Description("Indicates the cell informational Image (the image to display when InfoText is non-empty).")] public Image InfoImage { get { return (_InfoImage); } set { if (_InfoImage != value) { _InfoImage = value; OnPropertyChangedEx("InfoImage", VisualChangeType.Render); } } } #region GetInfoImage internal Image GetInfoImage() { return (_InfoImage ?? GridColumn.GetInfoImage()); } #endregion #endregion #region InfoImageBounds /// /// Gets the scroll adjusted, bounding /// rectangle for the current set info image /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Rectangle InfoImageBounds { get { GridPanel panel = GridPanel; if (panel != null) { Image image = GetInfoImage(); if (image != null) { if (ShowInfoCellImage(panel) == true) { Rectangle r = GetAdjustedBounds(ContentBounds); r.Inflate(-2, -1); Rectangle t = r; switch (GridColumn.InfoImageAlignment) { case Alignment.TopCenter: r.X += (r.Width - image.Width) / 2; break; case Alignment.TopRight: r.X = (r.Right - image.Width); break; case Alignment.MiddleLeft: if (GridColumn.InfoImageOverlay == false) r.X -= (image.Width + 4); r.Y += (r.Height - image.Height) / 2; break; case Alignment.MiddleCenter: r.X += (r.Width - image.Width) / 2; r.Y += (r.Height - image.Height) / 2; break; case Alignment.MiddleRight: r.X = (GridColumn.InfoImageOverlay == true) ? (r.Right - image.Width) : (r.Right + 4); r.Y += (r.Height - image.Height) / 2; break; case Alignment.BottomLeft: r.Y = (r.Bottom - image.Height); break; case Alignment.BottomCenter: r.X += (r.Width - image.Width) / 2; r.Y = (r.Bottom - image.Height); break; case Alignment.BottomRight: r.X = (r.Right - image.Width); r.Y = (r.Bottom - image.Height); break; } if (r.Y < t.Y) r.Y = t.Y; r.Width = image.Width; r.Height = image.Height; return (r); } } } return (Rectangle.Empty); } } #endregion #region InfoText /// /// Gets or sets the informational text associated with /// the cell. If the InfoText is non-null, then the cells /// associated InfoImage is displayed in the cell, with the /// InfoText being displayed as the ToolTip for the InfoImage. /// [DefaultValue(null), Category("Appearance")] [Description("Indicates the informational text associated with the cell. If the InfoText is non-null, then the cells associated InfoImage is displayed in the cell, with the InfoText being displayed as the ToolTip for the InfoImage.")] public string InfoText { get { return (_InfoText); } set { if (_InfoText != value) { _InfoText = value; UpdateInfoWindow(); OnPropertyChangedEx("InfoText", VisualChangeType.Render); } } } #endregion #region IsActiveCell /// /// Gets whether the cell is the Active cell. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsActiveCell { get { if (SuperGrid != null) return (SuperGrid.ActiveCell == this); return(false); } } #endregion #region IsCellVisible /// /// Gets whether the cell is visible (taking row visibility, /// column visibility, and expanded row state into account). /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsCellVisible { get { if (BoundsRelative.Width > 0) { GridRow row = GridRow; if (row != null) { if (GridColumn.Visible == false) return (false); return (row.IsExpandedVisible); } } return (false); } } #endregion #region IsDataError /// /// Gets whether setting the cell Value has caused a Data Error /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsDataError { get { return (TestState(Cs.DataError)); } internal set { SetState(Cs.DataError, value); } } #endregion #region IsEditorCell /// /// Gets whether the cell is the cell being edited. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsEditorCell { get { if (SuperGrid != null) return (SuperGrid.EditorCell == this); return (false); } } #endregion #region IsEmptyCell /// /// Gets whether the cell is an Empty cell. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsEmptyCell { get { return (TestState(Cs.EmptyCell)); } internal set { SetState(Cs.EmptyCell, value); } } #endregion #region IsHFrozen /// /// Gets whether the cell is horizontally frozen /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsHFrozen { get { GridColumn column = GridColumn; if (column != null) return (column.IsHFrozen); return (false); } } #endregion #region IsPrimaryCell /// /// Gets whether the cell is the defined PrimaryCell /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsPrimaryCell { get { GridPanel panel = GridPanel; if (panel != null) return (panel.PrimaryColumnIndex == _ColumnIndex); return (false); } } #endregion #region IsReadOnly /// /// Gets whether the cell is ReadOnly due to /// row, column, or cell ReadOnly property status. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsReadOnly { get { GridPanel panel = GridPanel; if (panel != null) { if (panel.ReadOnly || GridColumn.ReadOnly || GridRow.ReadOnly) return (true); } return (TestState(Cs.ReadOnly)); } } #endregion #region IsSelectable /// /// Gets whether the cell is selectable due to /// row, column, or cell AllowSelection property status. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsSelectable { get { return (AllowSelection == true && GridRow.AllowSelection == true && GridColumn.AllowSelection == true); } } #endregion #region IsSelected /// /// Gets or sets whether the cell is selected. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsSelected { get { GridPanel panel = GridPanel; if (panel != null) { if (AllowSelection == true && panel.AllowSelection == true) { if (_SelectionUpdateCount != panel.SelectionUpdateCount) { _SelectionUpdateCount = panel.SelectionUpdateCount; AnySelected = false; if (GridRow != null && GridColumn != null) { if (GridRow.IsSelected == true || GridColumn.IsSelected == true) { AnySelected = true; } else { CellRange cr = GetCellRange(); if (cr != null && cr.Suspended == false) { AnySelected = cr.IsSelected(panel, RowContainer); } else { if (GridRow.ExpandedVisible(panel) == true) Selected = panel.IsItemSelectedEx(this); AnySelected = Selected; } } } } return (AnySelected); } } return (false); } set { GridPanel panel = GridPanel; if (panel != null) { if (Selected != value) { Selected = value; if (GridRow != null) { if (GridRow.ExpandedVisible(panel) == true) panel.SetSelectedEx(this, value); if (value == true) { AnySelected = true; _SelectionUpdateCount = panel.SelectionUpdateCount; } InvalidateRender(); } } } } } #endregion #region IsValueExpression /// /// Gets whether the cell Value is an expression. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsValueExpression { get { return (TestState(Cs.ValueExpression)); } internal set { SetState(Cs.ValueExpression, value); } } #endregion #region IsValueNull /// /// Gets whether the cell Value is null. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsValueNull { get { object value = Value; return (((GridPanel != null && GridPanel.NullValue == NullValue.DBNull) ? DBNull.Value : null) == value); } } #endregion #region Merged /// ///Gets whether the cell is merged /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool Merged { get { return (TestState(Cs.Merged)); } internal set { if (value != Merged) { SetState(Cs.Merged, value); ClearEffectiveStyles(); if (value == true && _mouseDownHitCell == this) DoRendererMouseLeave(EventArgs.Empty); } } } #endregion #region MergedBottom /// ///Gets or sets whether the cell is Merged at the Bottom /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool MergedBottom { get { return (TestState(Cs.MergedBottom)); } set { SetState(Cs.MergedBottom, value); } } #endregion #region MergedLeft /// ///Gets or sets whether the cell is Merged to the Left /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool MergedLeft { get { return (TestState(Cs.MergedLeft)); } set { SetState(Cs.MergedLeft, value); } } #endregion #region MergedRight /// ///Gets or sets whether the cell is Merged to the Right /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool MergedRight { get { return (TestState(Cs.MergedRight)); } set { SetState(Cs.MergedRight, value); } } #endregion #region MergedTop /// ///Gets or sets whether the cell is Merged at the Top /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool MergedTop { get { return (TestState(Cs.MergedTop)); } set { SetState(Cs.MergedTop, value); } } #endregion #region MergeSuspended /// ///Gets whether the cell is merged and suspended. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool MergeSuspended { get { CellRange cr = GetCellRange(); return (cr != null && cr.Suspended == true); } } #endregion #region NullString /// /// Gets how null values are displayed /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string NullString { get { GridPanel panel = GridPanel; if (panel != null) return (GridColumn.NullString ?? panel.NullString); return (String.Empty); } } #endregion #region ReadOnly /// /// Gets or sets whether the user can change cell contents /// [DefaultValue(false), Category("Behavior")] [Description("Indicates whether the user can change cell contents.")] public bool ReadOnly { get { return (TestState(Cs.ReadOnly)); } set { if (value != ReadOnly) { SetState(Cs.ReadOnly, value); OnPropertyChangedEx("ReadOnly", VisualChangeType.Render); } } } #endregion #region RenderControl /// /// Gets the current set Render Control for the cell /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IGridCellEditControl RenderControl { get { if (_EditorInfo == null || (_EditorInfo.RenderType == null && _EditorInfo.EditorType == null)) { return (null); } if (_EditorInfo.RenderControl == null) { RenderControl = (_EditorInfo.RenderType != null) ? GetEditControl(_EditorInfo.RenderType, _EditorInfo.RenderParams) : GetEditControl(_EditorInfo.EditorType, _EditorInfo.EditorParams); } return (_EditorInfo.RenderControl); } internal set { if (_EditorInfo == null) _EditorInfo = new EditorInfo(); if (_EditorInfo.RenderControl != value) { if (_EditorInfo.RenderControl != null) { if (_EditorInfo.RenderControl.EditorPanel.Parent != null) SuperGrid.Controls.Remove(_EditorInfo.RenderControl.EditorPanel); _EditorInfo.RenderControl.EditorCellBitmap = null; if (_EditorInfo.RenderType != null || _EditorInfo.EditorType != null) ((Control)_EditorInfo.RenderControl).Dispose(); } _EditorInfo.RenderControl = value; if (_EditorInfo.RenderControl != null) { if (_EditorInfo.RenderControl.EditorPanel.Parent == null) SuperGrid.Controls.Add(_EditorInfo.RenderControl.EditorPanel); } } } } #endregion #region RenderParams /// /// Gets or sets an array of arguments that match in number, /// order, and type the parameters of the RenderControl constructor /// to invoke. If empty or null, the default constructor is invoked. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public object[] RenderParams { get { if (_EditorInfo == null) return (null); return (_EditorInfo.RenderParams); } set { if (_EditorInfo == null) _EditorInfo = new EditorInfo(); if (IsSameParams(_EditorInfo.RenderParams, value) == false) { _EditorInfo.RenderParams = value; RenderControl = null; NeedsMeasured = true; OnPropertyChangedEx("RenderParams", VisualChangeType.Layout); } if (_EditorInfo.IsEmpty == true) _EditorInfo = null; } } #endregion #region RenderType /// /// Gets or sets the cell render type. This is the control /// type used to perform the default rendering of the cell value /// [DefaultValue(null), Category("Data")] [Description("Indicates the cell render type. This is the control type used to perform the default rendering of the cell value.")] [TypeConverter(typeof(EditTypeConverter))] [Editor("DevComponents.SuperGrid.Design.EditTypeEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] public Type RenderType { get { if (_EditorInfo == null) return (null); return (_EditorInfo.RenderType); } set { if (value != null || _EditorInfo != null) { if (_EditorInfo == null) _EditorInfo = new EditorInfo(); if (_EditorInfo.RenderType != value) { _EditorInfo.RenderType = value; _EditorInfo.RenderControl = null; NeedsMeasured = true; OnPropertyChangedEx("RenderType", VisualChangeType.Layout); } if (_EditorInfo.IsEmpty == true) _EditorInfo = null; } } } #endregion #region RowIndex /// /// Gets the associated Row index for the cell /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int RowIndex { get { GridRow row = GridRow; return (row != null ? row.RowIndex : -1); } } #endregion #region UnMergedBounds /// /// Gets the scroll adjusted un-merged bounds of the cell /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Rectangle UnMergedBounds { get { if (_BoundsUpdateCount != SuperGrid.BoundsUpdateCount) UpdateBoundingRects(); return (_Bounds); } } #endregion #region Value /// /// Gets or sets the cell value /// [DefaultValue(null), Category("Data")] [Description("Indicates the cell value.")] [TypeConverter(typeof(ValueTypeConverter))] [Editor("DevComponents.SuperGrid.Design.ValueTypeEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] public object Value { get { GridPanel panel = GridPanel; if (panel != null) { object o = GetValue(panel); if (SuperGrid != null) SuperGrid.DoGetCellValueEvent(this, ref o); return (o); } return (_Value); } set { if ((value != null && value.Equals(_Value) == false) || (value == null && _Value != null)) { object oldValue = _Value; SetValue(value); GridRow row = GridRow; if (row != null && row.Loading == false) OnValueChanged(oldValue, value, DataContext.CellEdit); } } } #region GetValue /// /// GetValue /// /// /// protected virtual object GetValue(GridPanel panel) { if (panel.DataSource != null) { if (ActiveIList(panel) == true || _DataResetCount != panel.DataBinder.DataResetCount) { _DataResetCount = panel.DataBinder.DataResetCount; object o = panel.DataBinder.GetValue(this, _Value); if ((o == null && o != _Value) || (o != null && o.Equals(_Value) == false)) { _Value = o; GridColumn.NeedsFilterScan = true; InvalidateRender(); return (o); } } } return (_Value); } #region ActiveIList private bool ActiveIList(GridPanel panel) { if (panel.DataSource is IList && (panel.DataSource is IListSource == false && panel.DataSource is IBindingList == false)) { GridRow row = GridRow; if (row != null) { if (panel.LatentActiveRowIndex < 0 && row.IsTempInsertRow == false) return (true); } } return (false); } #endregion #endregion #region SetValue /// /// SetValue /// /// protected virtual void SetValue(object value) { _Value = value; GridPanel panel = GridPanel; if (panel != null) { GridRow row = GridRow; if (row.Loading == false && IsLoading() == false) { GridColumn column = GridColumn; panel.DataBinder.SetValue(this, value); row.RowNeedsStored = true; column.NeedsFilterScan = true; if (column.IsGroupColumn == true) { if (row == panel.ActiveRow) row.RowNeedsGrouped = true; else panel.NeedsGrouped = true; } if (panel.KeepRowsSorted == true) { if (column.IsSortColumn == true) { if (row.IsTempInsertRow == false) { if (row == panel.ActiveRow) row.RowNeedsSorted = true; else panel.NeedsSorted = true; } } } } } } private bool IsLoading() { SuperGridControl sg = SuperGrid; return (sg == null || sg.Parent == null); } #endregion #region OnValueChanged private void OnValueChanged(object oldValue, object newValue, DataContext context) { NeedsMeasured = true; IsDataError = false; ClearEffectiveStyles(); if (GridRow.Loading == false) RefreshCellEditor(); OnPropertyChanged("Value"); GridPanel panel = GridPanel; if (panel != null) { SuperGrid.DoCellValueChangedEvent(this, oldValue, newValue, context); if (panel.EnableCellExpressions == true) { if (GridRow.Loading == false) UpdateCellExp(panel, oldValue, newValue); } UpdateMerge(panel); } } #region RefreshCellEditor private void RefreshCellEditor() { if (SuperGrid != null) { IGridCellEditControl editor = GetInternalEditControl(true); if (editor != null) { if (SuperGrid.NonModalEditorCell == this) RefreshNonModalEditor(); else if (SuperGrid.EditorCell == this) RefreshEditor(editor); switch (editor.ValueChangeBehavior) { case ValueChangeBehavior.InvalidateLayout: GridColumn.NeedsResized = true; GridRow.NeedsMeasured = true; InvalidateLayout(); break; default: InvalidateRender(); break; } } } } #region RefreshEditor private void RefreshEditor(IGridCellEditControl editor) { editor.SuspendUpdate = true; try { CellVisualStyle style = GetEffectiveStyle(); editor.InitializeContext(this, style); } finally { editor.SuspendUpdate = false; } } #endregion #region RefreshNonModalEditor private void RefreshNonModalEditor() { if (SuperGrid.ActiveNonModalEditor != null) { SuperGrid.ActiveNonModalEditor.EditorValue = _Value; CellVisualStyle style = GetEffectiveStyle(); InitializeContext(DataContext.CellValueLoad, SuperGrid.ActiveNonModalEditor, style); } } #endregion #endregion #region UpdateMerge private void UpdateMerge(GridPanel panel) { CellRange cr = GetCellRange(); if (cr != null && cr.Suspended == true) { Modified = true; cr.Modified = true; } else { if (CellCanMerge(panel) == true) { MergeUpdateCount--; if (RowContainer.IsMergeSuspended == true) RowContainer.MergeUpdateCount++; RowContainer.NeedMergeLayout = true; RowContainer.InvalidateLayout(); } } } #region CellCanMerge private bool CellCanMerge(GridPanel panel) { if (panel != null && panel.EnableCellMerging == true) { CellMergeMode cMode = GridColumn.CellMergeMode; if (cMode == CellMergeMode.NotSet) cMode = panel.CellMergeMode; return (cMode != CellMergeMode.None); } return (false); } #endregion #endregion #endregion #region UpdateCellExp internal void UpdateCellExp( GridPanel panel, object oldValue, object value) { string oldExp = oldValue as string; string newExp = value as string; if (oldExp != null) { oldExp = oldExp.Trim(); if (oldExp.StartsWith("=")) { panel.ExpDictionary.Remove(this); InfoText = null; } } IsValueExpression = false; if (newExp != null) { newExp = newExp.Trim(); if (newExp.StartsWith("=")) SetCellExp(panel, newExp); } RefreshExpressions(panel, this, new List()); } #region RefreshExpressions private void RefreshExpressions( GridPanel panel, GridCell gridCell, List usedCells) { foreach (KeyValuePair item in panel.ExpDictionary) { List cells = item.Value.GetCellReferences(); if (cells != null) { if (cells.Contains(gridCell) == true) { item.Key.InvalidateRender(); if (usedCells.Contains(item.Key) == false) { usedCells.Add(item.Key); RefreshExpressions(panel, item.Key, usedCells); usedCells.Remove(item.Key); } } } } } #endregion #region SetCellExp internal void SetCellExp(GridPanel panel, string newExp) { if (panel.EnableCellExpressions == true) { IsValueExpression = false; while (true) { try { EEval eval = new EEval(this, newExp); panel.ExpDictionary[this] = eval; InfoText = null; IsValueExpression = true; break; } catch (Exception exp) { bool retry = false; bool throwException = false; if (SuperGrid.HasDataErrorHandler == true) { object value = newExp; if (SuperGrid.DoDataErrorEvent(GridPanel, this, exp, DataContext.CellExpressionParse, ref value, ref throwException, ref retry) == true) { return; } } if (throwException == true) throw; InfoText = exp.Message; if (retry == false) break; } } } } #endregion #endregion #endregion #endregion #region TestState private bool TestState(Cs state) { return ((_States & state) == state); } #endregion #region SetState private void SetState(Cs state, bool value) { if (value == true) _States |= state; else _States &= ~state; } #endregion #region MeasureOverride //private int _MeasureCount; /// /// 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) { //_MeasureCount++; MeasureCell(layoutInfo.Graphics, stateInfo.GridPanel, stateInfo.IndentLevel, constraintSize); } #region MeasureCell private void MeasureCell(Graphics g, GridPanel panel, int indentLevel, Size constraintSize) { Size sizeNeeded = Size.Empty; if (ColumnIndex < panel.Columns.Count) { CellVisualStyle style = GetSizingStyle(panel); Size imageSize = style.GetFigureSize(panel); Alignment imageAlignment = style.ImageAlignment; if (style.IsOverlayImage == true) imageAlignment = Alignment.MiddleCenter; int width = constraintSize.Width; Size borderSize = style.GetBorderSize(true); int bwidth = borderSize.Width + Dpi.Width2; int bheight = borderSize.Height + Dpi.Height2; if (constraintSize.Width > 1) { switch (imageAlignment) { case Alignment.TopCenter: case Alignment.MiddleCenter: case Alignment.BottomCenter: break; default: width -= imageSize.Width; break; } width -= bwidth; if (BoundsRelative.X == GridPanel.Bounds.X) width -= Dpi.Width1; } _ContentSize = GetProposedSize(g, style, new Size(width, 0)); switch (imageAlignment) { case Alignment.MiddleCenter: sizeNeeded.Height = Math.Max(imageSize.Height, _ContentSize.Height) + bheight; sizeNeeded.Width = Math.Max(_ContentSize.Width, imageSize.Width) + bwidth; break; case Alignment.TopCenter: case Alignment.BottomCenter: sizeNeeded.Width = Math.Max(_ContentSize.Width, imageSize.Width) + bwidth; sizeNeeded.Height = _ContentSize.Height + imageSize.Height + bheight; break; default: sizeNeeded.Width = _ContentSize.Width + imageSize.Width + bwidth; sizeNeeded.Height = Math.Max(imageSize.Height, _ContentSize.Height) + bheight; break; } if (panel.GroupColumns.Count > 0) { if (panel.Columns.FirstVisibleColumn == GridColumn) sizeNeeded.Width += Dpi.Width(panel.LevelIndentSize.Width * (indentLevel + 1)); } if (GridRow != null && (GridRow.Rows.Count > 0 || GridRow.RowsUnresolved == true)) { if (panel.ExpandImage != null) { sizeNeeded.Height = Math.Max(sizeNeeded.Height, Dpi.Height(panel.ExpandImage.Height + 4)); } if (panel.CollapseImage != null) { sizeNeeded.Height = Math.Max(sizeNeeded.Height, Dpi.Height(panel.CollapseImage.Height + 4)); } } if (panel.CheckBoxes == true) { sizeNeeded.Height = Math.Max(sizeNeeded.Height, Dpi.Height(panel.CheckBoxSize.Height)); sizeNeeded.Width += Dpi.Width(CheckBoxSpacing * 2); } } sizeNeeded.Width += Dpi.Width3; sizeNeeded.Height += Dpi.Width3; if (constraintSize.Width > 0) sizeNeeded.Width = constraintSize.Width; _MeasuredSize = sizeNeeded; Size = sizeNeeded; } #endregion #endregion #region ArrangeOverride /// /// Performs the arrange pass layout of the item /// when final position and size of the item has been set. /// /// Layout information. /// /// protected override void ArrangeOverride(GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Rectangle layoutBounds) { GridPanel panel = stateInfo.GridPanel; Rectangle r = layoutBounds; r.X += _IndentLevel * Dpi.Width(panel.LevelIndentSize.Width); r.Width = panel.TreeButtonIndent; ArrangeExpandButton(panel, ref r); ArrangeCheckBox(panel, r); _toolTipText = null; } #region ArrangeExpandButton private void ArrangeExpandButton(GridPanel panel, ref Rectangle r) { if (IsPrimaryCell == true) { Rectangle t = Rectangle.Empty; if (panel.ShowTreeButtons == true) { if (NeedsExpandButton() == true) { t = r; Size size = panel.GetTreeButtonSize(); t.X += (r.Width - size.Width) / 2; t.Y += (r.Height - size.Height) / 2 - 1; t.Size = size; } int tbi = panel.TreeButtonIndent; r.X += tbi; r.Width -= tbi; } else { if (panel.CheckBoxes == true) { int cbs = Dpi.Width(CheckBoxSpacing); r.X += cbs; r.Width -= cbs; } } GridRow.ExpandButtonBounds = t; } } #region NeedsExpandButton private bool NeedsExpandButton() { GridRow row = GridRow; if (row != null) { if (row.ShowTreeButton == true) { if (row.RowsUnresolved || row.HasVisibleItems) return (true); } } return (false); } #endregion #endregion #region ArrangeCheckBox private void ArrangeCheckBox(GridPanel panel, Rectangle r) { if (IsPrimaryCell == true) { if (GridRow.HasCheckBox == true) { Size cbSize = Dpi.Size(panel.CheckBoxSize); int n = Math.Max(cbSize.Width, cbSize.Height); r.Y += (r.Height - n) / 2; r.Width = n; r.Height = n; GridRow.CheckBoxBounds = r; } else { GridRow.CheckBoxBounds = Rectangle.Empty; } } } #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) { Graphics g = renderInfo.Graphics; CheckMeasure(panel, g); CellRange cr = GetStateCellRange(); bool rendered = (cr != null && (cr.RenderCount == panel.RenderCount)); Rectangle backBounds = (cr != null) ? cr.BackBounds : BackBounds; Rectangle bounds = GetBounds(panel, backBounds); if (backBounds.IntersectsWith(SuperGrid.ViewRectEx) == true) { if (rendered == false) { CellHighlightMode mode = GetCellHighlightMode(panel); CellVisualStyle style = GetEffectiveStyle(); RenderCellBackground(g, panel, backBounds, mode); RenderGridBorder(g, panel, backBounds); int n = RenderLevelData(g, panel); Rectangle r = bounds; r.X += n; r.Width -= n; RenderCellBorder(g, panel, r, style); RenderImageAndValue(g, panel, bounds, mode, style); if (this.IsDataError == true) RenderDataError(g); else if (GridRow.IsDeleted == true) RenderDeleted(g); RenderFocusRect(g, panel, cr, backBounds); if (cr != null) cr.RenderCount = panel.RenderCount; } else { RenderLevelData(g, panel); } } } } #region CheckMeasure private void CheckMeasure(GridPanel panel, Graphics g) { if (NeedsMeasured == true) { NeedsMeasured = false; Size size = new Size(GridColumn.Size.Width, GridRow.Size.Height); if (panel.VirtualMode == false) MeasureCell(g, panel, IndentLevel, size); size.Height = GridRow.FixedRowHeight; Size = size; UpdateBoundingRects(); } } #endregion #region RenderCellBackground private void RenderCellBackground(Graphics g, GridPanel panel, Rectangle r, CellHighlightMode mode) { if (SuperGrid.DoPreRenderCellEvent(g, this, RenderParts.Background, r) == false) { RenderCellBackgroundEx(panel, g, r, mode); SuperGrid.DoPostRenderCellEvent(g, this, RenderParts.Background, r); } } #region RenderCellBackgroundEx private void RenderCellBackgroundEx(GridPanel panel, Graphics g, Rectangle r, CellHighlightMode type) { if (SuperGrid.EditorCell == this) { TextBox tb = GetInternalEditControl() as TextBox; if (tb != null) { using (Brush br = new SolidBrush(tb.BackColor)) RenderBackground(g, r, type, br); return; } } using (Brush br = GetContentBrush(panel, r, type)) RenderBackground(g, r, type, br); } #region RenderBackground private void RenderBackground( Graphics g, Rectangle r, CellHighlightMode type, Brush br) { if (type == CellHighlightMode.Partial || type == CellHighlightMode.Content) { r = RenderPartialBackground(g, r, type); } if (r.Width > 0 && r.Height > 0) g.FillRectangle(br, r); } #endregion #region RenderPartialBackground private Rectangle RenderPartialBackground( Graphics g, Rectangle r, CellHighlightMode type) { CellVisualStyle defaultStyle = GetEffectiveStyle(StyleType.Default); using (Brush br = defaultStyle.Background.GetBrush(r)) g.FillRectangle(br, r); r = GetAdjustedBounds(ContentBounds); if (type == CellHighlightMode.Content) { IGridCellEditControl editor = GetInternalRenderControl(); r = GetEditPanelBounds(editor, r); } r.Inflate(1, 1); return (r); } #endregion #region GetContentBrush private Brush GetContentBrush( GridPanel panel, Rectangle r, CellHighlightMode type) { if (IsEmptyCell == true && panel.AllowEmptyCellSelection == false) { CellVisualStyle style = GetEffectiveStyle(StyleType.Empty); return (style.Background.GetBrush(r)); } if (IsSelectable == false) { CellVisualStyle style = GetEffectiveStyle(StyleType.NotSelectable); return (style.Background.GetBrush(r)); } if (type == CellHighlightMode.None) { CellVisualStyle style = GetEffectiveStyle(false); return (style.Background.GetBrush(r)); } CellVisualStyle contentStyle = GetContentStyle(panel); return (contentStyle.Background.GetBrush(r)); } #endregion #region GetContentStyle private CellVisualStyle GetContentStyle(GridPanel panel) { if (panel.SelectionGranularity == SelectionGranularity.Row) { StyleState cellState = StyleState.Default; if (IsReadOnly == true) cellState |= StyleState.ReadOnly; Rectangle t = ViewRect; Rectangle r = GridRow.Bounds; CellRange cr = GetCellRange(); if (cr != null) r = Rectangle.Union(r, cr.BackBounds); r.Intersect(t); if (SuperGrid.ScrollBarScrolling == false) { if (panel.RowHighlightType == RowHighlightType.Full) { if (GridRow.IsMouseOver == true) cellState |= StyleState.MouseOver; } else { if (r.Contains(SuperGrid.PointToClient(Control.MousePosition))) cellState |= StyleState.MouseOver; } } if (IsSelected == true) cellState |= StyleState.Selected; return (GetEffectiveStyle(cellState)); } return (GetEffectiveStyle()); } #endregion #region GetCellHighlightMode private CellHighlightMode GetCellHighlightMode(GridPanel panel) { if (panel.SelectionGranularity != SelectionGranularity.Cell) { switch (panel.RowHighlightType) { case RowHighlightType.None: return (CellHighlightMode.None); case RowHighlightType.PrimaryColumnOnly: return (IsPrimaryCell == true ? CellHighlightMode.Full : CellHighlightMode.None); default: return (CellHighlightMode.Full); } } if (GridRow.IsSelected == true) return (CellHighlightMode.Full); return (GridColumn.CellHighlightMode); } #endregion #endregion #endregion #region RenderGridBorder private void RenderGridBorder( Graphics g, GridPanel panel, Rectangle r) { if (SuperGrid.DoPreRenderCellEvent(g, this, RenderParts.Border, r) == false) { RenderGridBorderEx(g, panel, r); SuperGrid.DoPostRenderCellEvent(g, this, RenderParts.Border, r); } } private void RenderGridBorderEx( Graphics g, GridPanel panel, Rectangle r) { if (panel.GridLines != GridLines.None) { GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); if (panel.GridLines == GridLines.Both) RenderBothGridBorders(g, pstyle, r); else if (panel.GridLines == GridLines.Vertical) RenderVGridBorder(g, pstyle, r); else if (panel.GridLines == GridLines.Horizontal) RenderHGridBorder(g, pstyle, r); } } #region RenderBothGridBorders private void RenderBothGridBorders( Graphics g, GridPanelVisualStyle pstyle, Rectangle r) { RenderHGridBorder(g, pstyle, r); RenderVGridBorder(g, pstyle, r); } #endregion #region RenderHGridBorder private void RenderHGridBorder(Graphics g, GridPanelVisualStyle pstyle, Rectangle r) { if (pstyle.HorizontalLinePattern != LinePattern.None && pstyle.HorizontalLinePattern != LinePattern.NotSet) { 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 RenderVGridBorder private void RenderVGridBorder(Graphics g, GridPanelVisualStyle pstyle, Rectangle r) { if (pstyle.VerticalLinePattern != LinePattern.None && pstyle.VerticalLinePattern != LinePattern.NotSet) { using (Pen pen = new Pen(pstyle.VerticalLineColor, Dpi.Width1)) { pen.DashStyle = (DashStyle)pstyle.VerticalLinePattern; pen.DashOffset = r.Top % 2; g.DrawLine(pen, r.Right - 1, r.Top, r.Right - 1, r.Bottom); } } } #endregion #endregion #region RenderLevelData private int RenderLevelData(Graphics g, GridPanel panel) { int n = 0; if (IsPrimaryCell == true) { Rectangle r = BackBounds; int x = r.X; RenderCellTreeData(g, panel, ref r); RenderCellCheckBox(g, panel, ref r); n = r.X - x; } else { if (panel.GroupColumns.Count > 0) { if (panel.Columns.FirstVisibleColumn == GridColumn) n = Dpi.Width(panel.LevelIndentSize.Width * _IndentLevel); } } return (n); } #region RenderCellTreeData private void RenderCellTreeData( Graphics g, GridPanel panel, ref Rectangle r) { int liw = Dpi.Width(panel.LevelIndentSize.Width); if (panel.ShowTreeButtons == true || panel.ShowTreeLines == true) { GridRow row = GridRow; Rectangle t = row.ExpandButtonBounds; if (row.IsVFrozen == false) t.Y -= VScrollOffset; if (panel.IsSubPanel == true || GridColumn.IsHFrozen == false) t.X -= HScrollOffset; bool hasExpandButton = (panel.ShowTreeButtons == true && row.ExpandButtonBounds.IsEmpty == false); int tbi = panel.TreeButtonIndent; if (panel.ShowTreeLines == true) { Rectangle p = r; p.Y--; p.Height++; TreeDisplay.RenderLines(g, panel, p, row, _IndentLevel, liw, tbi, hasExpandButton); } if (hasExpandButton == true) { Point pt = Control.MousePosition; pt = SuperGrid.PointToClient(pt); bool hot = t.Contains(pt); Image image = (row.Expanded == true) ? panel.GetCollapseButton(g, hot) : panel.GetExpandButton(g, hot); ExpandDisplay.RenderButton(g, image, t, r); } r.X += tbi; r.Width -= tbi; } int n = liw * _IndentLevel; r.X += n; r.Width -= n; } #endregion #region RenderCellCheckBox private void RenderCellCheckBox( Graphics g, GridPanel panel, ref Rectangle r) { if (GridRow.HasCheckBox == true) { Rectangle t = CheckBoxBounds; if (GridRow.IsVFrozen == false) t.Y -= VScrollOffset; if (panel.IsSubPanel == true || GridColumn.IsHFrozen == false) t.X -= HScrollOffset; Region clip = null; if (t.Right >= r.Right || t.Height >= r.Height) { Rectangle z = r; z.Width--; z.Height--; clip = g.Clip; g.SetClip(z, CombineMode.Intersect); } if (GridRow.Checked == true) { CheckDisplay.RenderCheckbox(g, t, CheckBoxState.CheckedNormal, ButtonState.Checked); } else { CheckDisplay.RenderCheckbox(g, t, CheckBoxState.UncheckedNormal, ButtonState.Normal); } if (clip != null) g.Clip = clip; r.X += panel.CheckBoxSize.Width + (CheckBoxSpacing * 2); r.Width -= (panel.CheckBoxSize.Width + (CheckBoxSpacing * 2)); } } #endregion #endregion #region RenderCellBorder private void RenderCellBorder(Graphics g, GridPanel panel, Rectangle r, CellVisualStyle style) { if (SuperGrid.DoPreRenderCellEvent(g, this, RenderParts.Border, r) == false) { RenderCellBorderEx(g, panel, r, style); SuperGrid.DoPostRenderCellEvent(g, this, RenderParts.Border, r); } } #region RenderCellBorderEx private void RenderCellBorderEx( Graphics g, GridPanel panel, Rectangle r, CellVisualStyle style) { Rectangle t = GetBorderRect(panel, r, style); style.RenderBorder(g, t); } #region GetBorderRect private Rectangle GetBorderRect( GridPanel panel, Rectangle r, CellVisualStyle style) { r.X += Dpi.Width(style.Margin.Left); r.Width -= Dpi.Width(style.Margin.Horizontal); r.Y += Dpi.Height(style.Margin.Top); r.Height -= Dpi.Height(style.Margin.Vertical); if (panel.GridLines == GridLines.Horizontal || panel.GridLines == GridLines.Both) r.Height -= Dpi.Height1; if (panel.GridLines == GridLines.Vertical || panel.GridLines == GridLines.Both) r.Width -= Dpi.Width1; return (r); } #endregion #endregion #endregion #region RenderImageAndValue private void RenderImageAndValue(Graphics g, GridPanel panel, Rectangle bounds, CellHighlightMode mode, CellVisualStyle style) { Rectangle r = GetAdjustedBounds(GetContentBounds(panel, bounds)); if (style.ImageOverlay != ImageOverlay.Top) RenderCellImage(g, panel, style, bounds, r, mode); if (CanRenderCellValue() == true) { if (SuperGrid.DoPreRenderCellEvent(g, this, RenderParts.Content, r) == false) { RenderCellValue(g, style, r); SuperGrid.DoPostRenderCellEvent(g, this, RenderParts.Content, r); } } else { if (SuperGrid.EditorCell == this && Visible == true && IsEmptyCell == false) RenderCellInfo(g, panel); } if (style.ImageOverlay == ImageOverlay.Top) RenderCellImage(g, panel, style, bounds, r, mode); } #region RenderCellImage private void RenderCellImage(Graphics g, GridPanel panel, CellVisualStyle style, Rectangle bounds, Rectangle r, CellHighlightMode type) { object figure = style.GetFigure(panel); if (figure != null) { r = style.GetFigureBounds(panel, r); r.Intersect(bounds); if (r.Width > 0 && r.Height > 0) { if (figure is Image) { if (CanHighlightCell(style, type) == true) DrawHighlightImage(g, (Image)figure, style, r); else g.DrawImageUnscaledAndClipped((Image)figure, r); } else { SymbolDef sd = (SymbolDef)figure; using (Brush br = new SolidBrush(sd.SymbolColor)) g.DrawString(sd.SymbolRealized, sd.SymbolFont, br, r); } } } } #region CanHighlightCell private bool CanHighlightCell( CellVisualStyle style, CellHighlightMode type) { switch (style.ImageHighlightMode) { case ImageHighlightMode.Always: return (true); case ImageHighlightMode.Never: return (false); default: if (IsSelected == false) return (false); return (type == CellHighlightMode.Content || type == CellHighlightMode.Partial); } } #endregion #region DrawHighlightImage private void DrawHighlightImage(Graphics g, Image image, CellVisualStyle style, Rectangle r) { Color color = GetSimpleColor(style); float[][] ptsArray = { new float[] {(float)color.R / 255, 0, 0, 0, 0}, new float[] {0, (float)color.G / 255, 0, 0, 0}, new float[] {0, 0, (float)color.B / 255, 0, 0}, new float[] {0f, 0, 0, 1, 0}, new float[] {.15f, .15f, .15f, 0, 1} }; ColorMatrix clrMatrix = new ColorMatrix(ptsArray); ImageAttributes imgAttribs = new ImageAttributes(); imgAttribs.SetColorMatrix(clrMatrix, ColorMatrixFlag.Default, ColorAdjustType.Default); g.DrawImage(image, r, 0, 0, style.Image.Width, image.Height, GraphicsUnit.Pixel, imgAttribs); } #endregion #region GetSimpleColor private Color GetSimpleColor(CellVisualStyle style) { Color color1; Color color2; if (style.Background.BackColorBlend.Colors != null && style.Background.BackColorBlend.Colors.Length > 0) { Color[] colors = style.Background.BackColorBlend.Colors; color1 = colors[0]; color2 = colors[colors.Length - 1]; } else { color1 = style.Background.Color1; color2 = style.Background.Color2; } if (color2.IsEmpty == true) return (color1); switch (style.Alignment) { case Alignment.TopLeft: case Alignment.TopCenter: case Alignment.TopRight: return (color1); case Alignment.MiddleLeft: case Alignment.MiddleCenter: case Alignment.MiddleRight: return (Color.FromArgb((color1.R + color2.R) / 2, (color1.G + color2.G) / 2, (color1.B + color2.B) / 2)); default: return (color2); } } #endregion #endregion #region CanRenderCellValue private bool CanRenderCellValue() { if (Visible == false || IsEmptyCell == true || SuperGrid.EditorCell == this) return (false); if (SuperGrid.NonModalEditorCell == this) return (false); return (true); } #endregion #region RenderCellValue //private int _RenderCount; private void RenderCellValue( Graphics g, CellVisualStyle style, Rectangle r) { if (r.Width > 0) { GridColumn column = GridColumn; if (column != null) { IGridCellEditControl renderer; if (SuperGrid.ActiveEditor != null || (MouseRenderer == null || MouseRenderer.EditorCell != this)) { renderer = GetInternalRenderControl(); } else { renderer = MouseRenderer; } if (renderer != null && ((Control)renderer).IsDisposed == false) { CellRender(g, style, renderer); //using (StringFormat sf = new StringFormat()) //{ // sf.Alignment = StringAlignment.Far; // sf.LineAlignment = StringAlignment.Far; // sf.Trimming = StringTrimming.EllipsisCharacter; // g.DrawString((++_RenderCount).ToString(), // SystemFonts.DefaultFont, Brushes.Red, r, sf); // //sf.LineAlignment = StringAlignment.Near; // //g.DrawString((_MeasureCount).ToString(), // // SystemFonts.DefaultFont, Brushes.Blue, r, sf); //} } } } } #endregion #endregion #region RenderDataError private void RenderDataError(Graphics g) { Rectangle r = Bounds; int w = Dpi.Width5; int h = Dpi.Width5; if (r.Width > w && r.Height > h) r.Inflate(-w, -h); using (SolidBrush br = new SolidBrush(Color.FromArgb(64, Color.Crimson))) g.FillRectangle(br, r); } #endregion #region RenderDeleted private void RenderDeleted(Graphics g) { using (SolidBrush br = new SolidBrush(Color.FromArgb(128, Color.LightGray))) g.FillRectangle(br, Bounds); } #endregion #region RenderFocusRect private void RenderFocusRect(Graphics g, GridPanel panel, CellRange cr, Rectangle backBounds) { if (panel.FocusCuesEnabled == true) { if (IsFocused() == true) { if (panel.EnableCellMerging == true && IsFocusedRow(cr) == true) RenderRowFocusRect(g, panel, backBounds, cr); else if (IsFocusedCell(cr) == true) { Rectangle r; if (cr != null) { r = backBounds; if (r.X <= 0) { r.X++; r.Width--; } r.Width -= Dpi.Width1; r.Height -= Dpi.Height1; } else { r = HighLightBounds; } RenderCellFocusRect(g, r); } } } } #region IsFocused private bool IsFocused() { if (IsDesignerHosted == true) return (false); return (SuperGrid.ContainsFocus == true); } #endregion #region IsFocusedRow private bool IsFocusedRow(CellRange cr) { if (SuperGrid.ActiveElement is GridRow) { GridRow arow = SuperGrid.ActiveElement as GridRow; if (cr == null) return (arow == GridRow); if (arow.Parent == GridRow.Parent) return (arow.RowIndex >= cr.RowStart && arow.RowIndex < cr.RowEnd); } return (false); } #endregion #region IsFocusedCell private bool IsFocusedCell(CellRange cr) { GridCell acell = SuperGrid.ActiveElement as GridCell; if (acell == null) return (false); if (cr != null) return (cr == acell.GetCellRange()); return (IsSameCell(acell)); } #region IsSameCell internal bool IsSameCell(GridCell cell) { if (cell != null) { return (ColumnIndex == cell.ColumnIndex && GridRow == cell.GridRow); } return (false); } #endregion #endregion #region RenderRowFocusRect private void RenderRowFocusRect( Graphics g, GridPanel panel, Rectangle r, CellRange cr) { if (IsEmptyCell == false) { SmoothingMode sm = g.SmoothingMode; g.SmoothingMode = SmoothingMode.None; Rectangle t = (IsVFrozen == true ? r : SViewRect); Rectangle lc = GetLeftCell(panel, t, cr); Rectangle rc = GetRightCell(panel, t, cr); if (lc.IsEmpty == true && rc.IsEmpty == true) { RenderCellFocusRect(g, r); } else { using (Pen pen = new Pen(Color.Black, 1)) { pen.DashStyle = DashStyle.Dot; r.Width -= Dpi.Width1 + 1; r.Height -= Dpi.Height1 + 1; r.Intersect(t); RenderVertFocus(g, r, lc, rc, pen); RenderHorzFocus(g, r, lc, rc, pen); } } g.SmoothingMode = sm; } } #region RenderVertFocus private void RenderVertFocus(Graphics g, Rectangle r, Rectangle lc, Rectangle rc, Pen pen) { pen.DashOffset = (r.X % 2); if (lc.IsEmpty == false) { if (r.Width > 1) { if (r.Y < lc.Y - pen.DashOffset) g.DrawLine(pen, r.X, r.Y, r.X, lc.Y); if (lc.Bottom < r.Bottom - pen.DashOffset) g.DrawLine(pen, r.X, lc.Bottom, r.X, r.Bottom); } } else { if (r.Height > 1) g.DrawLine(pen, r.X, r.Y, r.X, r.Bottom); } if (rc.IsEmpty == false) { if (r.Width > 1) { if (r.Y < rc.Y - pen.DashOffset) g.DrawLine(pen, r.Right, rc.Y, r.Right, r.Y); if (rc.Bottom < r.Bottom - pen.DashOffset) g.DrawLine(pen, r.Right, rc.Bottom, r.Right, r.Bottom); } } else { if (r.Height > 1) g.DrawLine(pen, r.Right, r.Y, r.Right, r.Bottom); } } #endregion #region RenderHorzFocus private void RenderHorzFocus(Graphics g, Rectangle r, Rectangle lc, Rectangle rc, Pen pen) { if (r.Width > 1) { int x1 = 0; int x2 = 0; if (lc.IsEmpty == false) { if (lc.Y <= r.Y) x1 = r.X - lc.Right; } if (rc.IsEmpty == false) { if (rc.Y <= r.Y) { if (rc.X > r.Right) x2 = rc.X - r.Right + 1; } } pen.DashOffset = ((r.X - x1) % 2); if (r.Right + x2 - (r.X - x1) > pen.DashOffset) g.DrawLine(pen, r.X - x1, r.Y, r.Right + x2, r.Y); x1 = 0; x2 = 0; if (lc.IsEmpty == false) { if (lc.Bottom >= r.Bottom) { x1 = r.X - lc.Right; x2 = x1 - 1; } } if (rc.IsEmpty == false) { if (rc.Bottom >= r.Bottom) { if (rc.X > r.Right) x2 = rc.X - r.Right + 1; } } pen.DashOffset = ((r.X - x1) % 2); if (r.Right + x2 - (r.X - x1) > pen.DashOffset) g.DrawLine(pen, r.X - x1, r.Bottom, r.Right + x2, r.Bottom); } } #endregion #region GetLeftCell private Rectangle GetLeftCell(GridPanel panel, Rectangle t, CellRange cr) { GridColumnCollection columns = panel.Columns; GridColumn col = (cr != null) ? columns.GetPrevVisibleColumn(columns.ColumnAtDisplayIndex(cr.ColumnStart)) : columns.GetPrevVisibleColumn(GridColumn); Rectangle r = GetCellRect(col); r.Width -= Dpi.Width1 + 1; r.Height -= Dpi.Height1 + 1; t.Intersect(r); return (t); } #endregion #region GetRightCell private Rectangle GetRightCell(GridPanel panel, Rectangle t, CellRange cr) { GridColumnCollection columns = panel.Columns; GridColumn col = (cr != null) ? columns.GetNextVisibleColumn(columns.ColumnAtDisplayIndex(cr.ColumnEnd - 1)) : columns.GetNextVisibleColumn(GridColumn); while (col != null) { if (col.IsOnScreen == true) break; col = columns.GetNextVisibleColumn(col); } Rectangle r = GetCellRect(col); r.Width -= Dpi.Width1 + 1; r.Height -= Dpi.Height1 + 1; t.Intersect(r); return (t); } #endregion #region GetCellRect private Rectangle GetCellRect(GridColumn col) { if (col != null) { GridRow arow = SuperGrid.ActiveElement as GridRow; if (arow != null) { GridCell cell = arow.GetCell(col.ColumnIndex); if (cell != null) { CellRange cr2 = cell.GetStateCellRange(); if (cr2 != null) return (cr2.BackBounds); return (cell.Bounds); } } } return (Rectangle.Empty); } #endregion #endregion #region RenderCellFocusRect private void RenderCellFocusRect(Graphics g, Rectangle bounds) { SmoothingMode sm = g.SmoothingMode; g.SmoothingMode = SmoothingMode.None; ControlPaint.DrawFocusRectangle(g, bounds); g.SmoothingMode = sm; } #endregion #endregion #endregion #region GetCellRange /// ///Gets the CellRange, if any, that the cell is a member of. /// ///CellRange or null. public CellRange GetCellRange() { GridContainer cont = RowContainer; if (cont != null) return (cont.GetCellRange(this)); return (null); } internal CellRange GetStateCellRange() { CellRange cr = GetCellRange(); if (cr != null) { if (cr.Suspended == true) cr = null; } Merged = (cr != null); return (cr); } #endregion #region SuspendMerge /// ///If the cell is currently participating in a merged range of ///cells, then the merge will be suspended until the user clicks ///away from the merged range (or ResumeMerge is called for the cell). /// ///If true, cell will be made the active cell. public bool SuspendMerge(bool activate) { CellRange cr = GetStateCellRange(); if (cr != null) SuspendMerge(cr); if (cr == null || cr.Suspended == true) { if (activate == true) { if (CanSetActiveCell(GridPanel) == true) { _needsMouseEnter = true; SetActive(true); } } return (true); } return (false); } internal void SuspendMerge(CellRange cr) { GridContainer cont = RowContainer; if (cont != null) cont.SuspendMerge(cr); } #endregion #region ResumeMerge /// ///Resumes the suspended merge where the cell is a participant /// public void ResumeMerge(GridCell aCell) { GridContainer cont = RowContainer; if (cont != null) { if (ShouldResumeMerge(cont, aCell) == true) RowContainer.ResumeMerge(); } } private bool ShouldResumeMerge(GridContainer cont, GridCell aCell) { if (aCell == null) return (true); GridContainer aCont = aCell.RowContainer; if (aCont != cont) return (true); CellRange cr = cont.SuspendedRange; if (cr != null) { if (cr.Equals(aCont.GetCellRange(aCell)) == true) return (false); } return (true); } #endregion #region GetProposedSize private Size GetProposedSize(Graphics g, CellVisualStyle style, Size constraintSize) { return (GetProposedSize(g, style, constraintSize, null, CellSizingSource.ActualAndFormattedValues)); } private Size GetProposedSize(Graphics g, CellVisualStyle style, Size constraintSize, IGridCellEditControl editor, CellSizingSource sizingSource) { Size size = Size.Empty; if (IsValueExpression == true && ExpValue != null) { size = GetModalSize(g, ExpValue.ToString(), style, constraintSize); } else { if (editor == null) { if (CellEditMode != CellEditMode.Modal) { if (MouseRenderer == null || MouseRenderer.EditorCell == this) editor = GetInternalEditControl(); if (editor != null && editor.EditorCell != this) { if (SuperGrid.ActiveNonModalEditor == editor) editor = null; } if (editor == null) editor = GetInternalRenderControl(); } else { editor = SuperGrid.EditorCell == this ? GetInternalEditControl() : GetInternalRenderControl(); } } if (editor != null) { bool suspended = editor.SuspendUpdate; try { editor.SuspendUpdate = true; if (SuperGrid.EditorCell != this) InitializeContext(DataContext.CellProposedSize, editor, style); if (editor.CellEditMode == CellEditMode.Modal) { Size sizeActual = Size.Empty; Size sizeFormatted = Size.Empty; string s = editor.EditorFormattedValue; SuperGrid.DoGetCellFormattedValueEvent(this, ref s, ref sizingSource); if ((sizingSource & CellSizingSource.ActualValue) == CellSizingSource.ActualValue) sizeActual = editor.GetProposedSize(g, this, style, constraintSize); if ((sizingSource & CellSizingSource.FormattedValue) == CellSizingSource.FormattedValue) sizeFormatted = GetModalSize(g, s, style, constraintSize); size.Height = Math.Max(sizeActual.Height, sizeFormatted.Height); size.Width = Math.Max(sizeActual.Width, sizeFormatted.Width); } else { size = editor.GetProposedSize(g, this, style, constraintSize); } } finally { editor.SuspendUpdate = suspended; } } } return (size); } #region GetModalSize private Size GetModalSize(Graphics g, string text, CellVisualStyle style, Size constraintSize) { eTextFormat tf = style.GetTextFormatFlags(); string s = String.IsNullOrEmpty(text) ? " " : text; Size size = (constraintSize.IsEmpty == true) ? TextHelper.MeasureText(g, s, style.Font) : TextHelper.MeasureText(g, s, style.Font, constraintSize, tf); return (size); } #endregion #endregion #region Mouse support #region InternalMouseEnter internal override void InternalMouseEnter(EventArgs e) { base.InternalMouseEnter(e); if (GridColumn != null) { GridColumn.IsMouseOver = true; DoRendererMouseEnter(); SuperGrid.ToolTipText = ""; _toolTipText = null; if (GridPanel.SelectionGranularity != SelectionGranularity.Cell) GridRow.InvalidateRender(GridRow.Bounds); SuperGrid.DoCellMouseEnterEvent(this); } } #region DoRendererMouseEnter private void DoRendererMouseEnter() { if (CellEditMode != DotNetBar.SuperGrid.CellEditMode.Modal) { CellRange cr = GetStateCellRange(); if (cr != null && cr.Suspended == false) return; } _needsMouseEnter = true; if (SuperGrid.ActiveEditor == null) { _needsMouseEnter = false; if (IsEmptyCell == false) { CellVisualStyle style = GetEffectiveStyle(); MouseRenderer = null; if (CellEditMode != CellEditMode.Modal) MouseRenderer = GetInternalEditControl(); if (MouseRenderer == null) MouseRenderer = GetInternalRenderControl(); if (MouseRenderer != null) { switch (CellEditMode) { case CellEditMode.InPlace: InitializeContext(DataContext.CellMouseEvent, MouseRenderer, style); GetCurrentContentSize(style, MouseRenderer); break; case CellEditMode.NonModal: if (CanModifyMerge == true) { if (SuperGrid.ActiveNonModalEditor == null || SuperGrid.ActiveNonModalEditor.CanInterrupt == true) { if (SuperGrid.ActiveNonModalEditor != null) { SuperGrid.DeactivateNonModalEditor(); if (MouseRenderer == null) _needsMouseEnter = true; } if (MouseRenderer != null) { InitializeContext(DataContext.CellMouseEvent, MouseRenderer, style); PositionEditControl(MouseRenderer); MouseRenderer.BeginEdit(false); MouseRenderer.OnCellMouseEnter(EventArgs.Empty); SuperGrid.ActivateNonModalEditor(MouseRenderer, this); } } else { MouseRenderer = null; _needsMouseEnter = true; } } break; } if (MouseRenderer != null) InvalidateRender(); } } else { InvalidateRender(); } } } #endregion #endregion #region InternalMouseLeave internal override void InternalMouseLeave(EventArgs e) { if (GridColumn != null) { DoRendererMouseLeave(e); GridColumn.IsMouseOver = false; if (_lastHitArea == CellArea.InCellInfo) ProcessCellInfoLeave(); if (GridPanel != null) { if (GridPanel.SelectionGranularity != SelectionGranularity.Cell) GridRow.InvalidateRender(GridRow.Bounds); else InvalidateRender(); } SuperGrid.DoCellMouseLeaveEvent(this); SuperGrid.ToolTipText = ""; _toolTipText = null; _lastHitArea = CellArea.NoWhere; } base.InternalMouseLeave(e); } #region DoRendererMouseLeave internal void DoRendererMouseLeave(EventArgs e) { if (MouseRenderer != null && ((Control) MouseRenderer).IsDisposed == false) { if (CellEditMode != CellEditMode.InPlace || _mouseInItem == true) MouseRenderer.OnCellMouseLeave(e); } _mouseInItem = false; MouseRenderer = null; _needsMouseEnter = false; InvalidateRender(); } #endregion #endregion #region InternalMouseMove internal override void InternalMouseMove(MouseEventArgs e) { GridPanel panel = GridPanel; if (panel != null) { if (CapturedItem != null && e.Button != MouseButtons.None) ProcessMouseDownMove(e, panel); ProcessMouseMove(e); base.InternalMouseMove(e); DoRendererMouseMove(e); SuperGrid.DoCellMouseMoveEvent(this, e); } } #region DoRendererMouseMove private void DoRendererMouseMove(MouseEventArgs e) { if (_needsMouseEnter == true) DoRendererMouseEnter(); if (MouseRenderer != null && ((Control)MouseRenderer).IsDisposed == false) { if (CellEditMode == CellEditMode.InPlace) { DoInPlaceMouseMove(e); } else { if (CanModify == true) { Rectangle r = GetAdjustedBounds(EditBounds); Point pt = SuperGrid.PointToClient(Control.MousePosition); if (r.Contains(pt) == true) MouseRenderer.OnCellMouseMove(GetControlMouseArgs(e)); } } } } #region DoInPlaceMouseMove private void DoInPlaceMouseMove(MouseEventArgs e) { if (IsMouseDown == false || _mouseDownInItem == true) { if (MouseRenderer != null) { if (MouseRenderer.EditorCell != this) InitializeContext(DataContext.CellMouseEvent, MouseRenderer, null); Rectangle r = GetAdjustedBounds(ContentBounds); r = GetEditPanelBounds(MouseRenderer, r); bool inItem = r.Contains(e.Location); if (_mouseInItem != inItem) { if (inItem == true) MouseRenderer.OnCellMouseEnter(EventArgs.Empty); else MouseRenderer.OnCellMouseLeave(EventArgs.Empty); _mouseInItem = inItem; } if (_mouseInItem == true) MouseRenderer.OnCellMouseMove(GetControlMouseArgs(e, r)); } } } #endregion #endregion #region ProcessMouseDownMove private void ProcessMouseDownMove(MouseEventArgs e, GridPanel panel) { if (_mouseDownHitCell != null) { if (_mouseDownHitArea == CellArea.InContent) { Rectangle r = ViewRect; if (MouseDownPoint.Y < r.Y) { int n = SuperGrid.PrimaryGrid.FixedRowHeight - SuperGrid.PrimaryGrid.FixedHeaderHeight; r.Y -= n; r.Height += n; } if ((e.Y >= r.Y && e.Y < r.Bottom) && (e.X >= r.X && e.X < r.Right)) { SuperGrid.DisableAutoScrolling(); ProcessInContent(panel, e); } else { SuperGrid.EnableAutoScrolling( AutoScrollEnable.Horizontal | AutoScrollEnable.Vertical, r); } } } } #region ProcessInContent private void ProcessInContent(GridPanel panel, MouseEventArgs e) { Point pt = e.Location; Rectangle t = SViewRect; pt.X = Math.Min(t.Right - 1, pt.X); pt.X = Math.Max(t.X, pt.X); Rectangle v = panel.BoundsRelative; v.Location = panel.PointToScroll(v.Location); pt.X = Math.Min(v.Right - 1, pt.X); pt.X = Math.Max(v.X, pt.X); GridCell lastCell = _hitCell; _hitCell = GetCellAt(panel, pt); if (DragStarted(panel, pt, e) == false) { if (_hitCell != null && _hitArea == CellArea.InContent) { if (panel.MultiSelect == true) { if (lastCell != null) lastCell.IsMouseOver = false; _hitCell.IsMouseOver = true; if (panel.CellDragBehavior == CellDragBehavior.ExtendSelection) { if (panel.LastProcessedItem is GridCell && _hitCell != panel.LastProcessedItem) { if (SuperGrid.ActiveEditor == null) ProcessExtendSelection(panel, true); } } } } } } #region DragStarted private bool DragStarted(GridPanel panel, Point pt, MouseEventArgs e) { if (IsDragSelection == true) { if (IsDragStarted == false) { if (DragDrop.DragStarted(_mouseDownPoint, pt) == true) { IsDragStarted = true; if (SuperGrid.DoItemDragEvent(this, e) == true) { IsDragSelection = false; ExtendSelection(panel); } } } return (true); } return (false); } #endregion #region GetCellAt private GridCell GetCellAt(GridPanel panel, Point pt) { Rectangle t = ViewRect; pt.X = Math.Min(t.Right - 1, pt.X); pt.X = Math.Max(t.X, pt.X); Rectangle v = panel.BoundsRelative; v.Location = panel.PointToScroll(v.Location); pt.X = Math.Min(v.Right - 1, pt.X); pt.X = Math.Max(v.X, pt.X); GridRow row = panel.InternalGetElementAt(pt.X, pt.Y) as GridRow; while (row != null) { GridElement item = row.InternalGetElementAt(pt.X, pt.Y); if (item is GridCell) return (item as GridCell); row = item as GridRow; } return (null); } #endregion #endregion #endregion #region ProcessMouseMove private void ProcessMouseMove(MouseEventArgs e) { _hitArea = GetCellAreaAt(e); _hitCell = this; if (_hitArea == CellArea.InContent) SuperGrid.GridCursor = Cursors.Default; if (_hitArea != _lastHitArea) { ProcessToolTipText(e); _lastHitArea = _hitArea; InvalidateRender(); } base.InternalMouseMove(e); } #region ProcessToolTipText private void ProcessToolTipText(MouseEventArgs e) { if (_hitArea == CellArea.InContent) ProcessCellToolTip(); else if (_hitArea == CellArea.InCellInfo) ProcessCellInfoEnter(e); if (_lastHitArea == CellArea.InCellInfo) ProcessCellInfoLeave(); } #region ProcessCellToolTip private void ProcessCellToolTip() { SetToolTip(GridPanel.ShowToolTips ? GetToolTipText() : string.Empty); } #region GetToolTipText private string GetToolTipText() { if (_toolTipText == null) { CellRange cr = GetStateCellRange(); if (cr != null) { _toolTipText = cr.ToolTip ?? ""; } else { string s = ""; if (SuperGrid.DoGetCellToolTipEvent(GridPanel, this, ref s) == false) { _toolTipText = ""; if (IsEmptyCell == false) { CellVisualStyle style = GetEffectiveStyle(); Rectangle r = GetAdjustedBounds(ContentBounds); if (MouseRenderer != null && ((Control)MouseRenderer).IsDisposed == false) { Size size = new Size(style.AllowWrap == Tbool.True ? r.Width : 0, 0); using (Graphics g = SuperGrid.CreateGraphics()) size = GetProposedSize(g, style, size, MouseRenderer, CellSizingSource.FormattedValue); if (size.Width > r.Width || size.Height > r.Height) _toolTipText = String.IsNullOrEmpty(s) ? GetFormattedValue(MouseRenderer) : s; } } } else { _toolTipText = s; } } } return (_toolTipText); } #endregion #endregion #region ProcessCellInfoEnter private void ProcessCellInfoEnter(MouseEventArgs e) { SetToolTip(SuperGrid.DoCellInfoEnterEvent(this, SuperGrid, SuperGrid.ToolTip, e.Location) ? "" : InfoText); } #endregion #region ProcessCellInfoLeave private void ProcessCellInfoLeave() { SuperGrid.DoCellInfoLeaveEvent(this, SuperGrid, SuperGrid.ToolTip); } #endregion #region SetToolTip private void SetToolTip(string toolTipText) { if (SuperGrid.ToolTipText != _toolTipText) SuperGrid.ToolTip.Hide(SuperGrid); SuperGrid.ToolTipText = toolTipText; } #endregion #endregion #endregion #endregion #region InternalMouseDown internal override void InternalMouseDown(MouseEventArgs e) { GridPanel panel = GridPanel; if (panel != null) { SuperGrid.DoCellMouseDownEvent(this, e); _mouseDownPoint = e.Location; IsDragSelection = false; IsDragStarted = false; if (_hitArea == CellArea.InContent || _hitArea == CellArea.InCellInfo) { _mouseDownHitArea = CellArea.NoWhere; if (_hitCell != null && _hitCell.CanSetActiveCell(panel) == true) { _mouseDownHitArea = _hitArea; _mouseDownHitCell = _hitCell; if (panel.SelectionGranularity == SelectionGranularity.Cell) { panel.LastProcessedItem = _hitCell; InitSelectOrDrag(panel); } DoRendererMouseDown(e); } } } base.InternalMouseDown(e); } #region DoRendererMouseDown private void DoRendererMouseDown(MouseEventArgs e) { if (CanModifyMerge == true) { if (_needsMouseEnter == true) DoRendererMouseEnter(); if (MouseRenderer != null) { if (_mouseInItem == true) { _mouseDownInItem = true; if (MouseRenderer.EditorCell != this) InitializeContext(DataContext.CellMouseEvent, MouseRenderer, null); MouseRenderer.OnCellMouseDown(GetControlMouseArgs(e)); } } } } #endregion #region CanSetActiveCell internal bool CanSetActiveCell(GridPanel panel) { GridCell acell = SuperGrid.ActiveCell; if (acell != this) { if (IsSelectable == false || (IsEmptyCell == true && panel.AllowEmptyCellSelection == false)) { if (SuperGrid.DoPlayingSoundEvent(panel, this, PlaySoundContext.CellActivate) == false) SystemSounds.Beep.Play(); return (false); } GridCell ecell = SuperGrid.EditorCell; if (ecell != null) { if (ecell.EndEdit() == false) return (false); } if (acell != null) acell.ResumeMerge(this); if (GridRow.IsActive == false) { if (GridRow.CanSetActiveRow(false) == false) return (false); if (panel.SetActiveRow(GridRow, true) == false) return (false); } if (panel.SelectionGranularity != SelectionGranularity.Row) { if (SuperGrid.DoCellActivatingEvent(panel, acell, this) == true) return (false); SuperGrid.ActiveCell = this; if (panel.SelectionGranularity == SelectionGranularity.Cell) { SuperGrid.ActiveElement = this; panel.LastProcessedItem = this; } } } return (true); } #endregion #region ProcessExtendSelection private 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 = _hitCell; } #region ProcessControlExtend private void ProcessControlExtend(GridPanel panel, bool extend) { GridCell cell = panel.LastProcessedItem as GridCell; if (cell != null) { int startRowIndex = cell.GridRow.GridIndex; int startColumnIndex = panel.Columns.GetDisplayIndex(cell.GridColumn); int[] map = panel.Columns.DisplayIndexMap; if (extend == false) { int columnIndex = map[startColumnIndex]; SetSelectedMerge(panel, startRowIndex, startColumnIndex, startRowIndex, startColumnIndex, 0); panel.SetSelectedCells(startRowIndex, columnIndex, 1, 1, !panel.IsCellSelected(startRowIndex, columnIndex)); cell.InvalidateRender(); panel.ColumnHeader.InvalidateRowHeader(); } else { int endRowIndex = _hitCell.GridRow.GridIndex; int endColumnIndex = panel.Columns.GetDisplayIndex(_hitCell.GridColumn); if (endColumnIndex - startColumnIndex != 0) { SelectControlColumn(panel, map, startColumnIndex, endColumnIndex, startRowIndex); } if (endRowIndex - startRowIndex != 0) { SelectControlRow(panel, map, startRowIndex, endRowIndex, endColumnIndex); } } } } #region SelectControlColumn private void SelectControlColumn(GridPanel panel, int[] map, int startColumnIndex, int endColumnIndex, int startRowIndex) { int endRowIndex = startRowIndex; panel.NormalizeIndices(true, _anchorColumnIndex, ref startColumnIndex, ref endColumnIndex); panel.NormalizeIndices(false, _anchorRowIndex, ref startRowIndex, ref endRowIndex); if (endRowIndex > _anchorRowIndex) startRowIndex = _anchorRowIndex; else if (startRowIndex < _anchorRowIndex) endRowIndex = _anchorRowIndex; for (int i = startRowIndex; i <= endRowIndex; i++) { for (int j = startColumnIndex; j <= endColumnIndex; j++) { if (j != _anchorColumnIndex) { int columnIndex = map[j]; panel.SetSelectedCells(i, columnIndex, 1, 1, !panel.IsCellSelected(i, columnIndex)); } } } panel.InvalidateCells(startRowIndex, endRowIndex, startColumnIndex, endColumnIndex); } #endregion #region SelectControlRow private void SelectControlRow(GridPanel panel, int[] map, int startRowIndex, int endRowIndex, int endColumnIndex) { int startColumnIndex = endColumnIndex; panel.NormalizeIndices(false, _anchorColumnIndex, ref startColumnIndex, ref endColumnIndex); panel.NormalizeIndices(true, _anchorRowIndex, ref startRowIndex, ref endRowIndex); if (endColumnIndex > _anchorColumnIndex) startColumnIndex = _anchorColumnIndex; else if (startColumnIndex < _anchorColumnIndex) endColumnIndex = _anchorColumnIndex; for (int i = startRowIndex; i <= endRowIndex; i++) { for (int j = startColumnIndex; j <= endColumnIndex; j++) { if (i != _anchorRowIndex) { int columnIndex = map[j]; panel.SetSelectedCells(i, columnIndex, 1, 1, !panel.IsCellSelected(i, columnIndex)); } } } panel.InvalidateCells(startRowIndex, endRowIndex, startColumnIndex, endColumnIndex); } #endregion #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.SelectionColumnAnchor == null) { panel.SelectionRowAnchor = _mouseDownHitCell.GridRow; panel.SelectionColumnAnchor = _mouseDownHitCell.GridColumn; } ExtendSelection(panel, _hitCell, extend); } #endregion #endregion #region InitSelectOrDrag private void InitSelectOrDrag(GridPanel panel) { if (panel.SuperGrid.HasItemDragHandler == false || panel.IsItemSelected(this) == false || ((Control.ModifierKeys & (Keys.Control | Keys.Shift)) != Keys.None)) { ExtendSelection(panel); } else if (IsMouseDown == true) { IsDragSelection = true; Capture = true; } } #endregion #endregion #region InternalMouseUp internal override void InternalMouseUp(MouseEventArgs e) { if (GridColumn != null) { if (CanModifyMerge == true) DoRendererMouseUp(e); _mouseDownInItem = false; SuperGrid.DoCellMouseUpEvent(this, e); if (InfoImageBounds.Contains(e.X, e.Y) == true) { SuperGrid.DoCellInfoClickEvent(this, e); } else { if (_mouseDownHitCell == this && IsMouseOver == true) { if (SuperGrid.DoCellClickEvent(this, e) == false) { GridPanel panel = GridPanel; if (panel != null) { if ((e.Button & MouseButtons.Left) == MouseButtons.Left) { if (IsDragSelection == true) ExtendSelectionEx(panel); if (_hitArea == CellArea.InContent) { if (panel.MouseEditMode == MouseEditMode.SingleClick) { //if (Bounds.Contains(e.X, e.Y) == true) { if (CanSetActiveCell(GridPanel) == true) BeginEdit(true); } } } } } } } } } IsDragSelection = false; base.InternalMouseUp(e); } #region DoRendererMouseUp private void DoRendererMouseUp(MouseEventArgs e) { if (MouseRenderer != null) { if (_mouseDownInItem == true) { if (MouseRenderer.EditorCell != this) InitializeContext(DataContext.CellMouseEvent, MouseRenderer, null); MouseRenderer.OnCellMouseUp(GetControlMouseArgs(e)); SuperGrid.Focus(); } } } #endregion #endregion #region InternalMouseDoubleClick internal override void InternalMouseDoubleClick(MouseEventArgs e) { GridPanel panel = GridPanel; if (InfoImageBounds.Contains(e.X, e.Y) == true) { SuperGrid.DoCellInfoDoubleClickEvent(this, e); } else { if (SuperGrid.DoCellDoubleClickEvent(this, e) == false) { if (_hitArea == CellArea.InContent && panel.MouseEditMode == MouseEditMode.DoubleClick) { if (CanSetActiveCell(panel) == true) { CellRange cr = GetStateCellRange(); if (cr != null && cr.Suspended == false) { if (cr.AllowSuspend == true) { SuspendMerge(cr); if (_mouseDownHitCell != null) { _needsMouseEnter = true; _mouseDownHitCell.SetActive(true); } } else { if (SuperGrid.DoPlayingSoundEvent(panel, cr, PlaySoundContext.CellActivate) == false) SystemSounds.Beep.Play(); } } else { BeginEdit(true); } } } _mouseDownHitCell = null; } } } #region DoRendererMouseDoubleClick private void DoRendererMouseDoubleClick(MouseEventArgs e) { if (CanModify == true) { if (MouseRenderer != null) { if (_mouseDownInItem == true) { if (MouseRenderer.EditorCell != this) InitializeContext(DataContext.CellMouseEvent, MouseRenderer, null); MouseRenderer.OnCellMouseDown(GetControlMouseArgs(e)); } } } } #endregion #endregion #endregion #region GetControlMouseArgs private MouseEventArgs GetControlMouseArgs(MouseEventArgs e) { Rectangle r = GetAdjustedBounds(ContentBounds); r = GetEditPanelBounds(MouseRenderer, r); return (GetControlMouseArgs(e, r)); } private MouseEventArgs GetControlMouseArgs(MouseEventArgs e, Rectangle r) { int x = e.X - r.X; int y = e.Y - r.Y; MouseEventArgs args = new MouseEventArgs(e.Button, e.Clicks, x, y, e.Delta); return (args); } #endregion #region ExtendSelection internal void ExtendSelection(GridPanel panel, GridCell endCell, bool extend) { if (panel.SelectionColumnAnchor is GridColumn) { int startRowIndex = panel.SelectionRowAnchor.GridIndex; int startColumnIndex = panel.Columns.GetDisplayIndex((GridColumn)(panel.SelectionColumnAnchor)); int endRowIndex = endCell.GridRow.GridIndex; int endColumnIndex = panel.Columns.GetDisplayIndex(endCell.GridColumn); if (startRowIndex < 0) startRowIndex = endRowIndex; panel.NormalizeIndices(false, 0, ref startRowIndex, ref endRowIndex); panel.NormalizeIndices(false, 0, ref startColumnIndex, ref endColumnIndex); if (startColumnIndex < 0) startColumnIndex = 0; if (endColumnIndex < 0) endColumnIndex = 0; if (panel.OnlyCellsSelected( startRowIndex, startColumnIndex, endRowIndex, endColumnIndex) == false) { ClearSelected(panel, extend); if (startRowIndex >= 0 && endRowIndex >= 0) { SetSelected(panel, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex); InvalidateSelected(panel, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex); } } } } #region InvalidateSelected private void InvalidateSelected(GridPanel panel, int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) { GridCell lastCell = (Control.MouseButtons == MouseButtons.None) ? SuperGrid.LastActiveCell : panel.LastProcessedItem as GridCell; if (lastCell != null) { int lastIndex = panel.Columns.GetDisplayIndex(lastCell.ColumnIndex); if (lastIndex < startColumnIndex) startColumnIndex = lastIndex; else if (lastIndex > endColumnIndex) endColumnIndex =lastIndex; if (lastCell.GridRow.GridIndex < startRowIndex) startRowIndex = lastCell.GridRow.GridIndex; else if (lastCell.GridRow.GridIndex > endRowIndex) endRowIndex = lastCell.GridRow.GridIndex; } panel.InvalidateCells(startRowIndex, endRowIndex, startColumnIndex, endColumnIndex); } #endregion #region SetSelected private void SetSelected(GridPanel panel, int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) { SetSelectedMerge(panel, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex, 1); int[] map = panel.Columns.DisplayIndexMap; for (int i = startColumnIndex; i <= endColumnIndex; i++) { panel.SetSelectedCells(startRowIndex, map[i], endRowIndex - startRowIndex + 1, 1, true); } } #region SetSelectedMerge private void SetSelectedMerge(GridPanel panel, int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex, int selected) { if (panel.EnableCellMerging == true) { GridContainer cont = RowContainer; if (cont != null) { GridContainer srow = panel.GetRowFromIndex(startRowIndex); GridContainer erow = panel.GetRowFromIndex(endRowIndex); if (srow != null && erow != null) { int sRowIndex = panel.GetRowFromIndex(startRowIndex).RowIndex; int eRowIndex = panel.GetRowFromIndex(endRowIndex).RowIndex; cont.SetMergeSelection(sRowIndex, eRowIndex, startColumnIndex, endColumnIndex, selected); } } } } #endregion #endregion #region ClearSelected private void ClearSelected(GridPanel panel, bool extend) { if (panel.IsGrouped == false && (panel.SelectedCellCount < 50 && panel.SelectedRowCount < 10 && panel.SelectedColumnCount < 10)) { foreach (GridCell cell in panel.SelectedCells) cell.IsSelected = false; foreach (GridColumn col in panel.SelectedColumns) col.IsSelected = false; foreach (GridContainer row in panel.SelectedRows) { if (row != null) row.IsSelected = false; } RowContainer.ClearAllMergeSelected(); } else { panel.ClearAll(extend == false); } panel.SelectionClearCount++; } #endregion #endregion #region GetNextCell internal GridCell GetNextCell(bool canSelect) { return (GetNextCell(canSelect, true)); } internal GridCell GetNextCell(bool canSelect, bool multiRow) { GridPanel panel = GridPanel; if (panel != null) { int[] map = panel.Columns.DisplayIndexMap; int index = panel.Columns.GetDisplayIndex(GridColumn); int anchor = index; GridRow row = GridRow; while (row != null) { if (row.AllowSelection == true) { while (++index < map.Length) { if (multiRow == false && index == anchor) return (null); GridColumn column = panel.Columns[map[index]]; if (column.Visible == true && (canSelect == false || column.AllowSelection == true)) { GridCell cell = row.GetCell( column.ColumnIndex, panel.AllowEmptyCellSelection); if (cell != null) { if (canSelect == false || cell.AllowSelection == true) return (cell); } } } } if (multiRow == true) row = row.NextVisibleRow as GridRow; else break; index = -1; } } return (null); } #endregion #region GetPreviousCell internal GridCell GetPreviousCell(bool canSelect) { return (GetPreviousCell(canSelect, true)); } internal GridCell GetPreviousCell(bool canSelect, bool multiRow) { GridPanel panel = GridPanel; if (panel != null) { int[] map = panel.Columns.DisplayIndexMap; int index = panel.Columns.GetDisplayIndex(GridColumn); int anchor = index; GridRow row = GridRow; while (row != null) { if (row.AllowSelection == true) { while (--index >= 0) { if (multiRow == false && index == anchor) return (null); GridColumn column = panel.Columns[map[index]]; if (column.Visible == true && (canSelect == false || column.AllowSelection == true)) { GridCell cell = row.GetCell( column.ColumnIndex, panel.AllowEmptyCellSelection); if (cell != null) { if (canSelect == false || cell.AllowSelection == true) return (cell); } } } } if (multiRow == true) row = row.PrevVisibleRow as GridRow; else break; index = map.Length; } } return (null); } #endregion #region GetCellAreaAt /// /// Returns element at specified mouse coordinates /// /// Mouse event arguments /// Reference to child Cell element or null /// if no element at specified coordinates protected virtual CellArea GetCellAreaAt(MouseEventArgs e) { return GetCellAreaAt(e.X, e.Y); } /// /// Returns element at specified mouse coordinates /// /// Horizontal position /// Vertical position /// Reference to child element or null /// if no element at specified coordinates protected virtual CellArea GetCellAreaAt(int x, int y) { GridPanel panel = GridPanel; if (panel != null) { if (InfoImageBounds.Contains(x, y) == true) return (CellArea.InCellInfo); if (IsPrimaryCell == true) { GridRow cellRow = GridRow; if (cellRow != null) { Rectangle r = cellRow.ExpandButtonBounds; if (cellRow.IsVFrozen == false) r.Y -= VScrollOffset; if (panel.IsSubPanel == true || GridColumn.IsHFrozen == false) r.X -= HScrollOffset; if (r.Contains(x, y) == true) return (CellArea.InExpandButton); r = cellRow.CheckBoxBounds; if (cellRow.IsVFrozen == false) r.Y -= VScrollOffset; if (panel.IsSubPanel == true || GridColumn.IsHFrozen == false) r.X -= HScrollOffset; if (r.Contains(x, y) == true) return (CellArea.InCheckBox); } } } return (CellArea.InContent); } #endregion #region EnsureVisible /// /// Ensures that the given cell is visibly centered /// (as much as possible) in the grid display. /// /// public override void EnsureVisible(bool center) { if (GridRow.Visible == true && GridColumn.Visible == true) { if (IsVFrozen == false) GridRow.EnsureVisible(center); GridColumn column = GridColumn; if (column != null && column.IsHFrozen == false) column.EnsureVisible(center); } } #endregion #region SetActive /// /// Sets the given cell as Active /// ///true - if successful public bool SetActive() { return (SetActive(false)); } /// /// Makes the given cell active and /// optionally selects the given cell /// ///true, if successful public bool SetActive(bool select) { GridPanel panel = GridPanel; if (panel != null) { if (panel.SetActiveCell(this) == true) { if (select == true) { panel.ClearAll(); IsSelected = true; } return (true); } } return (false); } #endregion #region Editor support #region GetEditControl internal IGridCellEditControl GetEditControl(Type type, object[] args) { if (type != null) { IGridCellEditControl editor = Activator.CreateInstance(type, args) as IGridCellEditControl; if (editor is Control == false) throw new Exception("Edit/Render Type must be based on 'Control'."); editor.EditorPanel = new EditorPanel(); editor.EditorPanel.Visible = false; editor.EditorPanel.Controls.Add((Control) editor); return (editor); } return (null); } #endregion #region GetInternalEditControl internal IGridCellEditControl GetInternalEditControl() { return (GetInternalEditControl(CanModify)); } internal IGridCellEditControl GetInternalEditControl(bool canModify) { if (canModify == true) { if (SuperGrid.EditorCell != this) { Type editorType = _EditorInfo != null ? _EditorInfo.EditorType : null; object[] editorParams = _EditorInfo != null ? _EditorInfo.EditorParams : null; SuperGrid.DoGetEditorEvent(GridPanel, this, ref editorType, ref editorParams); EditorType = editorType; EditorParams = editorParams; } return (EditControl ?? (GridColumn != null ? GridColumn.EditControl : null)); } return (null); } #endregion #region GetInternalRenderControl private IGridCellEditControl GetInternalRenderControl() { GridPanel panel = GridPanel; if (panel != null) { Type renderType = _EditorInfo != null ? _EditorInfo.RenderType : null; object[] renderParams = _EditorInfo != null ? _EditorInfo.RenderParams : null; SuperGrid.DoGetRendererEvent(panel, this, ref renderType, ref renderParams); RenderType = renderType; RenderParams = renderParams; return (RenderControl ?? (GridColumn != null ? GridColumn.RenderControl : null)); } return (null); } #endregion #region BeginEdit /// /// Begins a Modal cell edit operation using /// the defined column or cell Modal EditControl. /// /// /// public IGridCellEditControl BeginEdit(bool selectAll) { return (BeginEdit(selectAll, null)); } /// /// Begins a Modal cell edit operation using the defined column /// or cell Modal EditControl. If a KeyEvent is provided then /// the event will be presented to the editor control. /// ///Cell edit control public IGridCellEditControl BeginEdit(bool selectAll, KeyEventArgs e) { GridCell ecell = SuperGrid.EditorCell; if (ecell == this) return (GetInternalEditControl()); if (ecell != null) throw new Exception("Modal Cell edit is already in process."); if (Visible == true && CanModify == true) { GridPanel.FlushSelected(); IGridCellEditControl editor = GetInternalEditControl(); if (editor != null && editor.CellEditMode == CellEditMode.Modal) { if (SuspendMerge(false) == true) { CellVisualStyle style = GetEffectiveStyle(StyleState.Default); SuperGrid.DeactivateNonModalEditor(); DoRendererMouseLeave(EventArgs.Empty); EnsureVisible(); GetCurrentContentSize(style, editor); InitializeContext(DataContext.CellEdit, editor, style); if (SuperGrid.DoBeginEditEvent(GridPanel, this, editor) == false) { SuperGrid.ActiveEditor = editor; SuperGrid.EditorCell = this; PositionEditPanel(editor); editor.EditorPanel.Show(); editor.EditorPanel.BringToFront(); if (editor.BeginEdit(selectAll) == false) { UpdateInfoWindow(); FocusEditor(editor); if (e != null) SuperGrid.PressKeyDown((ushort) e.KeyCode); return (editor); } CloseEdit(editor); } } } } return (null); } #endregion #region EndEdit /// /// This routine ends an in-progress Modal cell edit operation. /// ///true if ended public bool EndEdit() { IGridCellEditControl editor = SuperGrid.ActiveEditor; if (editor != null && CellEditMode == CellEditMode.Modal) { if (editor.EditorCell == this) { if (GridRow.EditorDirty == true) { if (ValidateCellEdit(editor) == false) return (false); GridRow.EditorDirty = false; object value = Value; if (UpdateCellValue(editor) == true) Value = value; } if (SuperGrid.DoEndEditEvent(GridPanel, this, editor) == false) { if (editor.EndEdit() == false) { CloseEdit(editor); return (true); } } return (false); } } return (true); } #region UpdateCellValue /// /// Used by IGridCellEditControl editors to update the /// cell Value from the EditorValue, performing any needed /// data conversions for proper data typing. /// /// /// public bool UpdateCellValue(IGridCellEditControl editor) { object value = editor.EditorValue; while (true) { try { ConvertValueToType(editor, value); return (false); } catch (Exception exp) { bool throwException = true; bool retry = false; if (SuperGrid.HasDataErrorHandler == true) { if (SuperGrid.DoDataErrorEvent(GridPanel, this, exp, DataContext.CellValueStore, ref value, ref throwException, ref retry) == true) { return (true); } } if (throwException == true) { MessageBoxEx.Show(exp.ToString()); throw; } if (retry == false) break; } } return (true); } #region ConvertValueToType private void ConvertValueToType(IGridCellEditControl editor, object value) { Type dataType = GridColumn.DataType; if (editor is IGridCellConvertTo) { IGridCellConvertTo cvtEditor = (IGridCellConvertTo)editor; object result; if (cvtEditor.TryConvertTo(value, dataType, out result) == true) { Value = result; return; } } if (dataType == null && Value != null) dataType = Value.GetType(); if (dataType == typeof (SqlDateTime)) Value = SetSqlDateTime(value); else if (dataType == typeof (SqlBoolean)) Value = SetSqlBoolean(value); else if (dataType == typeof (SqlString)) Value = SetSqlString(value); else if (dataType == typeof (SqlSingle)) Value = SetSqlSingle(value); else if (dataType == typeof (SqlDouble)) Value = SetSqlDouble(value); else if (dataType == typeof(SqlDecimal)) Value = SetSqlDecimal(value); else if (dataType == typeof (SqlInt16)) Value = SetSqlInt16(value); else if (dataType == typeof (SqlInt32)) Value = SetSqlInt32(value); else if (dataType == typeof (SqlInt64)) Value = SetSqlInt64(value); else if (dataType != null) Value = ConvertValue.ConvertTo(value, dataType); else Value = value; } #region SetSqlDateTime private object SetSqlDateTime(object value) { if (value == null) return (new SqlDateTime()); if (value is DateTime) return (new SqlDateTime((DateTime)value)); return (new SqlDateTime(Convert.ToDateTime(value))); } #endregion #region SetSqlBoolean private object SetSqlBoolean(object value) { if (value == null) return (new SqlBoolean()); if (value is CheckState) { CheckState cs = (CheckState)value; if (cs == CheckState.Checked) return (new SqlBoolean(true)); if (cs == CheckState.Unchecked) return (new SqlBoolean(false)); return (new SqlBoolean()); } return (new SqlBoolean(Convert.ToBoolean(value))); } #endregion #region SetSqlBoolean private object SetSqlString(object value) { if (value == null) return (new SqlString()); return (new SqlString(Convert.ToString(value))); } #endregion #region SetSqlSingle private object SetSqlSingle(object value) { if (value == null) return (new SqlSingle()); return (new SqlSingle(Convert.ToSingle(value))); } #endregion #region SetSqlDouble private object SetSqlDouble(object value) { if (value == null) return (new SqlDouble()); return (new SqlSingle(Convert.ToDouble(value))); } #endregion #region SetSqlDecimal private object SetSqlDecimal(object value) { if (value == null) return (new SqlDecimal()); return (new SqlDecimal(Convert.ToDecimal(value))); } #endregion #region SetSqlInt16 private object SetSqlInt16(object value) { if (value == null) return (new SqlInt16()); return (new SqlInt16(Convert.ToInt16(value))); } #endregion #region SetSqlInt32 private object SetSqlInt32(object value) { if (value == null) return (new SqlInt32()); return (new SqlInt32(Convert.ToInt32(value))); } #endregion #region SetSqlInt64 private object SetSqlInt64(object value) { if (value == null) return (new SqlInt64()); return (new SqlInt64(Convert.ToInt64(value))); } #endregion #endregion #endregion #region ValidateCellEdit private bool ValidateCellEdit(IGridCellEditControl editor) { try { object value = editor.EditorValue; object formattedValue = GetFormattedValue(editor); if (SuperGrid.DoCellValidatingEvent(this, ref value, formattedValue) == true) { if (SuperGrid.DoPlayingSoundEvent(GridPanel, this, PlaySoundContext.CellValidate) == false) SystemSounds.Beep.Play(); return (false); } editor.EditorValue = value; SuperGrid.DoCellValidatedEvent(this); } catch { if (SuperGrid.DoPlayingSoundEvent(GridPanel, this, PlaySoundContext.CellValidate) == false) SystemSounds.Beep.Play(); return (false); } return (true); } #endregion #endregion #region CancelEdit /// /// Cancels the current in-progress Modal cell edit operation. /// ///true if canceled public bool CancelEdit() { IGridCellEditControl editor = SuperGrid.ActiveEditor; if (editor == null || CellEditMode != CellEditMode.Modal) throw new Exception("Bad CancelEdit - Modal edit not in progress."); if (SuperGrid.DoCancelEditEvent(GridPanel, this, editor) == false) { if (editor.CancelEdit() == false) { bool rowDirty = GridRow.RowDirty; bool needsStored = GridRow.RowNeedsStored; CloseEdit(editor); GridRow.RowDirty = rowDirty; GridRow.RowNeedsStored = needsStored; return (true); } } return (true); } #endregion #region CloseEdit private void CloseEdit(IGridCellEditControl editor) { CloseCellInfoWindow(); IsMouseOver = false; bool wasFocused = ((Control)editor).ContainsFocus; editor.EditorPanel.Hide(); editor.EditorPanel.GridCell = null; GridRow.EditorDirty = false; SuperGrid.ActiveEditor = null; SuperGrid.EditorCell = null; if (wasFocused == true) SuperGrid.Focus(); SuperGrid.DoCloseEditEvent(GridPanel, this); if (GridPanel == null || GridPanel.NeedToUpdateDataFilter == true) InvalidateLayout(); else InvalidateRender(); SuperGrid.Update(); } #endregion #region PositionEditPanel internal void PositionEditPanel(IGridCellEditControl editor) { PositionEditControl(editor); UpdateCellInfoWindowPos(); ((Control)editor).Update(); editor.EditorPanel.Update(); } #endregion #region PostCellKeyDown /// /// PostCellKeyDown /// /// internal void PostCellKeyDown(Keys keyData) { if (CanModifyMerge == true) { SuperGrid.DeactivateNonModalEditor(); IGridCellEditControl editor = GetInternalEditControl(); if (editor != null) { KeyEventArgs e = new KeyEventArgs(keyData); CellVisualStyle style = GetEffectiveStyle(); InitializeContext(DataContext.CellKeyEvent, editor, style); editor.CellKeyDown(e); } PostInternalMouseMove(); } } #endregion #region PositionEditControl /// /// PositionEditControl /// /// private void PositionEditControl(IGridCellEditControl editor) { if (GridColumn != null) { GridPanel panel = GridPanel; if (panel != null) { Control c = (Control) editor; Rectangle r = GetAdjustedBounds(ContentBounds); Rectangle e = GetEditPanelBounds(editor, r); e = GetClippedBounds(panel, e); switch (editor.CellEditMode) { case CellEditMode.Modal: case CellEditMode.NonModal: if (GetCellHighlightMode(panel) == CellHighlightMode.Content) { r = GetEditPanelBounds(editor, r); e = GetClippedBounds(panel, r); } editor.EditorPanel.Bounds = e; c.Bounds = GetEditorBounds(editor, r, e); editor.EditorPanel.SizeEx = Bounds.Size; editor.EditorPanel.OffsetEx = new Point(Bounds.X - e.X, Bounds.Y - e.Y); if (editor.CellEditMode == CellEditMode.NonModal) { editor.EditorPanel.BringToFront(); editor.EditorPanel.Show(); } break; case CellEditMode.InPlace: r.Intersect(SuperGrid.SViewRect); r.Location = Point.Empty; c.Bounds = r; break; } } } } #region GetEditPanelBounds private Rectangle GetEditPanelBounds(IGridCellEditControl editor, Rectangle r) { CellVisualStyle style = GetEffectiveStyle(); int n = r.Right; if (SuperGrid.EditorCell != this) { AlignHorizontally(editor, style, ref r); } else { if (GetCellHighlightMode(GridPanel) == CellHighlightMode.Content) n -= 2; } if (r.Right > n) r.Width -= (r.Right - n); n = r.Bottom - 1; AlignVertically(editor, style, ref r); if (r.Bottom > n) r.Height -= (r.Bottom - n); return (r); } #endregion #region AlignHorizontally private void AlignHorizontally( IGridCellEditControl editor, CellVisualStyle style, ref Rectangle r) { Size size = _ContentSize; switch (editor.StretchBehavior) { case StretchBehavior.Both: case StretchBehavior.HorizontalOnly: size.Width = r.Width; break; default: if (size.Width <= 0) { GetCurrentContentSize(style, editor); size = _ContentSize; } if (size.Width <= 0) { size.Width = r.Width; } else if (r.Width > size.Width) { switch (style.Alignment) { case Alignment.TopCenter: case Alignment.MiddleCenter: case Alignment.BottomCenter: r.X += ((r.Width - size.Width) / 2); break; case Alignment.TopRight: case Alignment.MiddleRight: case Alignment.BottomRight: r.X += (r.Width - size.Width - 1); break; } } break; } r.Width = size.Width; } #endregion #region AlignVertically private void AlignVertically( IGridCellEditControl editor, CellVisualStyle style, ref Rectangle r) { Size size = _ContentSize; switch (editor.StretchBehavior) { case StretchBehavior.Both: case StretchBehavior.VerticalOnly: size.Height = r.Height; break; default: if (size.Height <= 0) { size.Height = r.Height; } else if (r.Height > size.Height) { switch (style.Alignment) { case Alignment.MiddleLeft: case Alignment.MiddleCenter: case Alignment.MiddleRight: r.Y += ((r.Height - size.Height)/2); break; case Alignment.BottomLeft: case Alignment.BottomCenter: case Alignment.BottomRight: r.Y += r.Height - size.Height; break; } } break; } r.Height = size.Height; } #endregion #region GetEditorBounds private Rectangle GetEditorBounds( IGridCellEditControl editor, Rectangle r, Rectangle e) { if (GetCellHighlightMode(GridPanel) == CellHighlightMode.Content) { r.X = 0; r.Y = 0; } else { r.X = (r.X - e.X); r.Y = (r.Y - e.Y); r = GetEditPanelBounds(editor, r); } return (r); } #endregion #endregion #region FocusEditor internal void FocusEditor(IGridCellEditControl editor) { if (((Control)editor).Focused == false) ((Control)editor).Focus(); if (editor is IGridCellEditorFocus) ((IGridCellEditorFocus)editor).FocusEditor(); } #endregion #region CellRender /// /// This routine can be called by a cell editor / renderer to /// perform default cell rendering provided by the grid. /// /// /// public void CellRender(IGridCellEditControl editor, Graphics g) { GridPanel panel = GridPanel; if (panel != null) { CellVisualStyle style = GetEffectiveStyle(); CellRange cr = GetStateCellRange(); Rectangle bounds = (cr != null) ? GetBounds(panel, cr.BackBounds) : Bounds; Rectangle rc = GetAdjustedBounds(GetContentBounds(panel, bounds)); if (rc.Height > 0 && rc.Width > 0) { RenderContent(g, panel, editor, style, rc, cr); RenderCellInfo(g, panel); } } } #region RenderContent private void RenderContent(Graphics g, GridPanel panel, IGridCellEditControl editor, CellVisualStyle style, Rectangle rc, CellRange cr) { if (cr != null && (editor.CellEditMode == CellEditMode.Modal || cr.AlwaysDisplayFormattedValue == true)) RenderRangeContent(g, panel, style, rc, cr); else RenderCellContent(g, editor, style, rc); } #region RenderRangeContent private void RenderRangeContent(Graphics g, GridPanel panel, CellVisualStyle style, Rectangle rc, CellRange cr) { string s = cr.FormattedValue; if (string.IsNullOrEmpty(s) == false) { if (panel.EnableCellRangeMarkup == true) { if (MarkupParser.IsMarkup(s) == true) { BodyElement markup = MarkupParser.Parse(s); RenderTextMarkup(g, markup, style, rc); } } else { eTextFormat tf = style.GetTextFormatFlags(); TextDrawing.DrawString(g, s, style.Font, style.TextColor, rc, tf); } } } #region RenderTextMarkup private void RenderTextMarkup(Graphics g, BodyElement textMarkup, CellVisualStyle style, Rectangle r) { MarkupDrawContext d = new MarkupDrawContext(g, style.Font, style.TextColor, false); textMarkup.Arrange(new Rectangle(r.Location, r.Size), d); Size size = textMarkup.Bounds.Size; switch (style.Alignment) { case Alignment.MiddleLeft: case Alignment.MiddleCenter: case Alignment.MiddleRight: if (r.Height > size.Height) r.Y += (r.Height - size.Height) / 2; break; default: if (r.Height > size.Height) r.Y = r.Bottom - size.Height; break; } textMarkup.Bounds = new Rectangle(r.Location, size); Region oldClip = g.Clip; try { g.SetClip(r, CombineMode.Intersect); textMarkup.Render(d); } finally { g.Clip = oldClip; } } #endregion #endregion #region RenderCellContent private void RenderCellContent(Graphics g, IGridCellEditControl editor, CellVisualStyle style, Rectangle rc) { switch (editor.CellEditMode) { case CellEditMode.Modal: string s = GetFormattedValueEx(editor); eTextFormat tf = style.GetTextFormatFlags(); if (string.IsNullOrEmpty(s) == false) TextDrawing.DrawString(g, s, style.Font, style.TextColor, rc, tf); break; case CellEditMode.NonModal: case CellEditMode.InPlace: Rectangle re = GetEditPanelBounds(editor, rc); if (re.Width > 0 && re.Height > 0) { Bitmap bm = GetCellBitmap(editor, rc); if (bm != null) { PaintButtonContent(editor, bm, rc, re); g.DrawImageUnscaledAndClipped(bm, re); } } break; } } #endregion #endregion #region RenderCellInfo private void RenderCellInfo(Graphics g, GridPanel panel) { if (ShowInfoCellImage(panel) == true) { Image image = GetInfoImage(); if (image != null) { Rectangle rc = InfoImageBounds; if (rc.Width > 0 && rc.Height > 0) g.DrawImageUnscaledAndClipped(image, rc); } } } #region ShowInfoCellImage private bool ShowInfoCellImage(GridPanel panel) { if (panel.ShowCellInfo == false || _InfoText == null) return (false); if (_InfoText.Equals("") == false) return (true); return (panel.ShowCellInfoDisplayMode == ShowCellInfoDisplayMode.ShowWithEmptyText); } #endregion #endregion #region GetExpValue /// /// Gets the resultant value of the evaluated Cell Expression, if /// applicable. Otherwise returns the given value. /// /// /// public string GetExpValue(string source) { GridPanel panel = GridPanel; if (IsValueExpression == true && panel.EnableCellExpressions == true) { EEval eval = panel.ExpDictionary[this]; if (eval != null) { while (true) { try { _ExpValue = eval.Evaluate(); string s = (_ExpValue != null) ? _ExpValue.ToString() : ""; InfoText = null; return (s); } catch (Exception exp) { bool retry = false; bool throwException = false; if (SuperGrid.HasDataErrorHandler == true) { object value = _Value; if (SuperGrid.DoDataErrorEvent(panel, this, exp, DataContext.CellExpressionEval, ref value, ref throwException, ref retry) == true) { return (source); } } if (throwException == true) throw; InfoText = exp.Message; if (retry == false) return ("####!"); } } } } return (source); } #endregion #region GetCellBitmap /// /// Gets the cell paint bitmap /// /// /// /// private Bitmap GetCellBitmap(IGridCellEditControl editor, Rectangle r) { Bitmap bm = editor.EditorCellBitmap; if (bm == null || bm.Size != r.Size) { if (bm != null) bm.Dispose(); bm = new Bitmap(r.Width, r.Height); editor.EditorCellBitmap = bm; } return (bm); } #endregion #region PaintButtonContent /// /// Paints the button background and content /// private void PaintButtonContent(IGridCellEditControl editor, Bitmap bm, Rectangle rc, Rectangle re) { Control c = (Control)editor; // SizeEx is the size of the Adjusted Content size of the cell // OffsetEx is the offset from the Editor panel to the cell ContentBounds. editor.EditorPanel.Size = re.Size; editor.EditorPanel.SizeEx = rc.Size; editor.EditorPanel.OffsetEx = new Point(rc.X - re.X, rc.Y - re.Y); // Set the control bounds and initiate the // transfer of the control image to our bitmap. re.Location = Point.Empty; editor.SuspendUpdate = true; if (editor.EditorPanel.IsHandleCreated == false) { editor.EditorPanel.Show(); editor.EditorPanel.BringToFront(); editor.EditorPanel.Hide(); } c.Bounds = re; c.DrawToBitmap(bm, re); editor.SuspendUpdate = false; } #endregion #endregion #region PaintEditorBackground /// /// Performs default cell background painting for the cell. /// /// /// public void PaintEditorBackground(PaintEventArgs e, IGridCellEditControl editor) { Rectangle r = new Rectangle(); r.Size = editor.EditorPanel.SizeEx; r.Location = Point.Empty; if (r.Width > 0 && r.Height > 0) { Graphics g = e.Graphics; if (SuperGrid.DoPreRenderCellEvent(g, this, RenderParts.Background, r) == false) { GridPanel panel = GridPanel; CellHighlightMode mode = GetCellHighlightMode(panel); using (Brush br = GetContentBrush(panel, r, mode)) g.FillRectangle(br, r); SuperGrid.DoPostRenderCellEvent(g, this, RenderParts.Background, r); } } } #endregion #region ExtendSelection /// /// ExtendSelection /// internal void ExtendSelection(GridPanel panel) { if (IsMouseSelectable() == true) { Capture = true; ExtendSelectionEx(panel); } } private void ExtendSelectionEx(GridPanel panel) { _mouseDownHitCell = this; _mouseDownHitArea = CellArea.InContent; if (panel.SelectionRowAnchor == null) panel.SelectionRowAnchor = GridRow; if (_hitCell != null) { _anchorRowIndex = _hitCell.GridRow.GridIndex; _anchorColumnIndex = panel.Columns.GetDisplayIndex(GridColumn); ProcessExtendSelection(panel, false); if (panel.LastProcessedItem != _hitCell) GridRow.EditorDirty = false; if (SuperGrid.ActiveNonModalEditor != null) { SuperGrid.Update(); if (SuperGrid.ActiveNonModalEditor != null) SuperGrid.ActiveNonModalEditor.EditorPanel.Invalidate(true); } } } #region IsMouseSelectable private bool IsMouseSelectable() { if ((Control.MouseButtons & MouseButtons.Left) == MouseButtons.Left) return (true); return (IsSelected == false); } #endregion #endregion #region InitializeContext private void InitializeContext(DataContext dataContext, IGridCellEditControl editor, CellVisualStyle style) { if (((Control) editor).Handle != null) { object value = Value; if (InitializeContextEx(dataContext, editor, style) == true) Value = value; } } private bool InitializeContextEx(DataContext dataContext, IGridCellEditControl editor, CellVisualStyle style) { object value = Value; while (true) { bool suspended = editor.SuspendUpdate; try { IsDataError = false; editor.SuspendUpdate = true; editor.EditorPanel.GridCell = this; editor.InitializeContext(this, style); SuperGrid.DoInitEditContextEvent(this, editor); return (false); } catch (Exception exp) { bool retry = false; bool throwException = false; if (SuperGrid.HasDataErrorHandler == true) { if (SuperGrid.DoDataErrorEvent(GridPanel, this, exp, dataContext, ref value, ref throwException, ref retry) == true) { return (true); } } else { IsDataError = true; return (false); } if (throwException == true) throw; if (retry == false) break; Value = value; } finally { editor.SuspendUpdate = suspended; } } return (true); } #endregion #region CellRender private void CellRender(Graphics g, CellVisualStyle style, IGridCellEditControl renderer) { if (renderer.CellEditMode != CellEditMode.Modal) { try { renderer.SuspendUpdate = true; InitializeContext(DataContext.CellRender, renderer, style); renderer.CellRender(g); } finally { renderer.SuspendUpdate = false; } } else { InitializeContext(DataContext.CellRender, renderer, style); renderer.CellRender(g); } } #endregion #region SetEditorDirty /// /// Called by the cell editor to conditionally set /// the cells row level EditorDirty state. /// /// public void SetEditorDirty(IGridCellEditControl editor) { if (GridColumn.MarkRowDirtyOnCellValueChange == true) { if (SuperGrid.DoRowMarkedDirtyEvent(this, editor) == false) EditorDirty = true; } } #endregion #region EditorValueChanged /// /// This routine is called by cell editors to signal to the grid /// that the editor has changed the cell Value. /// /// public void EditorValueChanged(IGridCellEditControl editor) { if (editor.SuspendUpdate == false) { SuperGrid.DoEditorValueChangedEvent(this, editor); editor.EditorValueChanged = true; } } #endregion #endregion #region UpdateBoundingRects private void UpdateBoundingRects() { GridPanel panel = GridPanel; if (panel != null) { _BoundsUpdateCount = SuperGrid.BoundsUpdateCount; _BackBounds = GetBackBounds(panel); _Bounds = GetBounds(panel); } } #region GetBackBounds /// /// Gets the scroll adjusted background bounding rectangle /// /// /// internal Rectangle GetBackBounds(GridPanel panel) { Rectangle r = BoundsRelative; if (panel.IsSubPanel == false) { GridColumn column = GridColumn; if (column != null) { if (column.IsHFrozen == false) r.X -= HScrollOffset; } } else { r.X -= HScrollOffset; } if (GridRow.IsVFrozen == false) r.Y -= VScrollOffset; return (r); } #endregion #region GetBounds internal Rectangle GetBounds(GridPanel panel) { return (GetBounds(panel, BackBounds)); } /// /// Gets the scroll adjusted bounding rectangle /// /// /// /// internal Rectangle GetBounds(GridPanel panel, Rectangle backBounds) { Rectangle r = backBounds; r.Y += GridRow.EffectivePreDetailRowHeight; r.Height -= (GridRow.EffectivePreDetailRowHeight + GridRow.EffectivePostDetailRowHeight); return (r); } #endregion #region GetCellBounds /// /// Gets the SViewRect clipped Bounds /// /// /// private Rectangle GetCellBounds(GridPanel panel) { return (GetClippedBounds(panel, Bounds)); } #endregion #region GetContentBounds internal Rectangle GetContentBounds(GridPanel panel) { return (GetContentBounds(panel, Bounds)); } /// /// Gets the cell content (excludes image) bounding rectangle /// /// /// /// internal Rectangle GetContentBounds(GridPanel panel, Rectangle bounds) { Rectangle r = bounds; int n = Dpi.Width(panel.LevelIndentSize.Width * _IndentLevel); CellRange cr = GetStateCellRange(); if (HasPrimaryCell(panel, cr) == true) { if (panel.ShowTreeButtons == true || panel.ShowTreeLines == true) n += panel.TreeButtonIndent; if (panel.CheckBoxes == true) n += Dpi.Width(panel.CheckBoxSize.Width + (CheckBoxSpacing * 2)); if (Merged == true) { GridColumn col = panel.Columns.ColumnAtDisplayIndex(cr.ColumnStart); n = Math.Max(n - (r.X - col.Bounds.X), 0); } r.X += n; r.Width -= n; } else if (panel.GroupColumns.Count > 0) { if (panel.Columns.FirstVisibleColumn == GridColumn) { r.X += n; r.Width -= n; } } CellVisualStyle style = GetEffectiveStyle(); object figure = style.GetFigure(panel); if (figure != null) r = style.GetNonFigureBounds(panel, r); if (GridColumn.InfoImageOverlay == false) { if (string.IsNullOrEmpty(InfoText) == false) { Image image = GetInfoImage(); if (image != null) { switch (GridColumn.InfoImageAlignment) { case Alignment.MiddleLeft: r.X += (image.Size.Width + 4); r.Width -= (image.Size.Width + 4); break; case Alignment.MiddleRight: r.Width -= (image.Size.Width + 4); break; } } } } r.Inflate(-1, -1); return (r); } #region IsPrimaryCell private bool HasPrimaryCell(GridPanel panel, CellRange cr) { if (cr != null) return (cr.ColumnStart == panel.Columns.GetDisplayIndex(panel.PrimaryColumn)); return (panel.PrimaryColumnIndex == _ColumnIndex); } #endregion #endregion #region GetEditBounds /// /// Gets /// /// /// private Rectangle GetEditBounds(GridPanel panel) { Rectangle r = GetClippedBounds(panel, ContentBounds); r.Inflate(-1, -1); return (r); } #endregion #region GetClippedBounds private Rectangle GetClippedBounds(GridPanel panel, Rectangle r) { Rectangle v = SViewRect; if (IsVFrozen == true) { int n = panel.FixedRowHeight - panel.FixedHeaderHeight; v.Y -= n; v.Height += n; } if (GridColumn.IsHFrozen == false) { GridColumn pcol = panel.Columns.GetLastVisibleFrozenColumn(); if (pcol != null) { int n = Dpi.Width(pcol.BoundsRelative.Right - v.X); v.X += n; v.Width -= n; } } r.Intersect(v); return (r); } #endregion #endregion #region GetAdjustedBounds #region GetAdjustedBounds() private Rectangle GetAdjustedBounds() { Rectangle r = Bounds; 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; } return (r); } #endregion #region GetAdjustedBounds(r) private Rectangle GetAdjustedBounds(Rectangle r) { CellVisualStyle style = GetEffectiveStyle(); r.X += Dpi.Width(style.BorderThickness.Left + style.Margin.Left + style.Padding.Left); r.Width -= Dpi.Width(style.BorderThickness.Horizontal + style.Margin.Horizontal + style.Padding.Horizontal); r.Y += Dpi.Height(style.BorderThickness.Top + style.Margin.Top + style.Padding.Top); r.Height -= Dpi.Height(style.BorderThickness.Vertical + style.Margin.Vertical + style.Padding.Vertical); r.Width--; return (r); } #endregion #endregion #region GetCurrentContentSize private void GetCurrentContentSize( CellVisualStyle style, IGridCellEditControl editor) { GridPanel panel = GridPanel; if (panel != null) { Size oldSize = _ContentSize; int width = Bounds.Size.Width; object figure = style.GetFigure(panel); if (figure != null) { Alignment alignment = style.ImageAlignment; if (style.IsOverlayImage == true) alignment = Alignment.MiddleCenter; switch (alignment) { case Alignment.TopLeft: case Alignment.TopRight: case Alignment.MiddleLeft: case Alignment.MiddleRight: case Alignment.BottomLeft: case Alignment.BottomRight: width -= style.GetFigureSize(panel).Width; break; } } width -= (style.GetBorderSize(true).Width + 2); Size constraintSize = new Size(width, 0); using (Graphics g = SuperGrid.CreateGraphics()) _ContentSize = GetProposedSize(g, style, constraintSize, editor, CellSizingSource.ActualAndFormattedValues); if (_ContentSize != oldSize) _BoundsUpdateCount = (ushort)(SuperGrid.BoundsUpdateCount - 1); } } #endregion #region GetCellEditBounds /// /// Get the CellEditBounds for the cell. /// /// /// public Rectangle GetCellEditBounds(IGridCellEditControl editor) { Rectangle r = GetAdjustedBounds(ContentBounds); r = GetEditPanelBounds(editor, r); return (r); } #endregion #region GetFormattedValue internal string GetFormattedValue() { IGridCellEditControl editor = SuperGrid.EditorCell == this ? GetInternalEditControl() : GetInternalRenderControl(); return (GetFormattedValue(editor)); } internal string GetFormattedValue(IGridCellEditControl editor) { string s = null; if (editor == null || IsDataError == true) { if (_Value != null) s = _Value.ToString(); } else { bool suspended = editor.SuspendUpdate; try { editor.SuspendUpdate = true; if (SuperGrid.EditorCell != this) InitializeContext(DataContext.CellGetFormattedValue, editor, null); s = editor.EditorFormattedValue; } finally { editor.SuspendUpdate = suspended; } if (s != null && s.TrimStart().StartsWith("=") == true) s = GetExpValue(s); } CellSizingSource sizingSource = CellSizingSource.ActualAndFormattedValues; SuperGrid.DoGetCellFormattedValueEvent(this, ref s, ref sizingSource); return (s ?? ""); } internal string GetFormattedValueEx(IGridCellEditControl editor) { string s = null; if (editor == null || IsDataError == true) { if (_Value != null) s = _Value.ToString(); } else { s = editor.EditorFormattedValue; if (s != null && s.TrimStart().StartsWith("=") == true) s = GetExpValue(s); } CellSizingSource sizingSource = CellSizingSource.ActualAndFormattedValues; SuperGrid.DoGetCellFormattedValueEvent(this, ref s, ref sizingSource); return (s ?? ""); } #endregion #region CellInfoWindow support #region UpdateInfoWindow private void UpdateInfoWindow() { GridPanel panel = GridPanel; if (panel != null) { if (SuperGrid.EditorCell != this) { CloseCellInfoWindow(); } else { if (GridColumn.InfoImageOverlay == false) { if (SuperGrid.ActiveEditor != null) PositionEditPanel(SuperGrid.ActiveEditor); } else { if (CanShowCellInfo(panel) == true) { if (_cellInfoWindow == null) OpenCellInfoWindow(); UpdateCellInfoWindowPos(); _cellInfoWindow.Show(); _cellInfoWindow.BringToFront(); } else { CloseCellInfoWindow(); } } } } } #endregion #region CanShowCellInfo private bool CanShowCellInfo(GridPanel panel) { if (ShowInfoCellImage(panel) == true) return (GetInfoImage() != null); return (false); } #endregion #region UpdateCellInfoWindowPos private void UpdateCellInfoWindowPos() { if (_cellInfoWindow != null) { if (_cellInfoWindow != null) { Point pt = InfoImageBounds.Location; pt = SuperGrid.PointToScreen(pt); if (SuperGrid.ActiveEditor != null) pt = SuperGrid.ActiveEditor.EditorPanel.PointToClient(pt); else if (SuperGrid.ActiveNonModalEditor != null) pt = SuperGrid.ActiveNonModalEditor.EditorPanel.PointToClient(pt); _cellInfoWindow.Location = pt; } } } #endregion #region OpenCellInfoWindow private void OpenCellInfoWindow() { _cellInfoWindow = new CellInfoWindow(SuperGrid, this); _cellInfoWindow.Parent = SuperGrid.ActiveEditor.EditorPanel; SuperGrid.ActiveEditor.EditorPanel.Controls.Add(_cellInfoWindow); } #endregion #region CloseCellInfoWindow private void CloseCellInfoWindow() { if (_cellInfoWindow != null) { SuperGrid.ToolTipText = ""; _cellInfoWindow.Dispose(); _cellInfoWindow = null; } } #endregion #endregion #region Style support #region GetEffectiveStyle /// /// Gets the EffectiveStyle for the cell. The effective /// style is the cached, composite style definition for the /// given cell, composed from panel, row, column, and cell styles. /// /// public CellVisualStyle GetEffectiveStyle() { bool selected = IsSelected; StyleState cellState = GetCellState(selected); CellVisualStyle style = GetEffectiveStyle(cellState); return (style); } /// /// Gets the EffectiveStyle for the cell- for the given StyleType. /// The effective style is the cached, composite style definition for the /// given cell, composed from panel, row, column, and cell styles. /// /// /// public CellVisualStyle GetEffectiveStyle(StyleType type) { ValidateStyle(); return (GetStyle(type)); } internal CellVisualStyle GetEffectiveStyle(bool selected) { StyleState cellState = GetCellState(selected); return (GetEffectiveStyle(cellState)); } private CellVisualStyle GetEffectiveStyle(StyleState cellState) { ValidateStyle(); if (IsDesignerHosted == true) cellState &= ~(StyleState.MouseOver | StyleState.Selected); CellRange cr = GetStateCellRange(); if (cr != null) return (cr.GetEffectiveStyle(RowContainer, cellState)); if (IsEmptyCell == true && (GridPanel.AllowEmptyCellSelection == false || cellState == StyleState.Default)) { return (GetStyle(StyleType.Empty)); } if (IsSelectable == false) return (GetStyle(StyleType.NotSelectable)); switch (cellState) { case StyleState.MouseOver: return (GetStyle(StyleType.MouseOver)); case StyleState.Selected: return (GetStyle(StyleType.Selected)); case StyleState.Selected | StyleState.MouseOver: return (GetStyle(StyleType.SelectedMouseOver)); case StyleState.ReadOnly: return (GetStyle(StyleType.ReadOnly)); case StyleState.ReadOnly | StyleState.MouseOver: return (GetStyle(StyleType.ReadOnlyMouseOver)); case StyleState.ReadOnly | StyleState.Selected: return (GetStyle(StyleType.ReadOnlySelected)); case StyleState.ReadOnly | StyleState.MouseOver | StyleState.Selected: return (GetStyle(StyleType.ReadOnlySelectedMouseOver)); default: return (GetStyle(StyleType.Default)); } } #endregion #region GetCellState private StyleState GetCellState(bool selected) { StyleState cellState = StyleState.Default; if (IsReadOnly == true) cellState |= StyleState.ReadOnly; if (SuperGrid.EditorCell != null || SuperGrid.NonModalEditorCell != null) { if (SuperGrid.EditorCell == this || SuperGrid.NonModalEditorCell == this) cellState |= StyleState.MouseOver; } else { if (CapturedItem == null || CapturedItem is GridCell) { Point pt = SuperGrid.PointToClient(Control.MousePosition); Rectangle r = Bounds; GridPanel panel = GridPanel; if (Merged == true) { CellRange cr = GetStateCellRange(); if (cr != null) r = GetBounds(panel, cr.BackBounds); } Rectangle t = ViewRect; r.Intersect(t); if (r.Contains(pt) == true) cellState |= StyleState.MouseOver; } } if (selected == true) cellState |= StyleState.Selected; return (cellState); } #endregion #region GetStyle private CellVisualStyle GetStyle(StyleType e) { CellVisualStyles cvs = _EffectiveStyles; if (cvs == null) cvs = new CellVisualStyles(); if (cvs.IsValid(e) == false) { CellVisualStyle style = new CellVisualStyle(); StyleType[] css = style.GetApplyStyleTypes(e); if (css != null) { foreach (StyleType cs in css) { GridColumn.ApplyCellStyle(style, cs); GridRow.ApplyCellStyle(style, cs); style.ApplyStyle(CellStyles[cs]); } } SuperGrid.DoGetCellStyleEvent(this, e, ref style); if (style.Background == null || style.Background.IsEmpty == true) style.Background = new Background(Color.White); if (style.Font == null) style.Font = SystemFonts.DefaultFont; style.ApplyDefaults(); cvs[e] = style; _EffectiveStyles = cvs; } return (cvs[e]); } #endregion #region GetSizingStyle private CellVisualStyle GetSizingStyle(GridPanel panel) { StyleType style = panel.GetSizingStyle(); if (style == StyleType.NotSet) { style = (IsReadOnly == true) ? StyleType.ReadOnly : StyleType.Default; } return (GetEffectiveStyle(style)); } #endregion #region StyleVisualChangeHandler private void StyleVisualChangeHandler( INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) { //NeedsMeasured = true; if (oldValue != null) oldValue.PropertyChanged -= StyleChanged; if (newValue != null) newValue.PropertyChanged += StyleChanged; } #endregion #region StyleChanged /// /// Occurs when one of element visual styles has property changes. /// Default implementation invalidates visual appearance of element. /// /// VisualStyle that changed. /// Event arguments. protected virtual void StyleChanged(object sender, PropertyChangedEventArgs e) { ClearEffectiveStyles(); VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType; if (changeType == VisualChangeType.Layout) { NeedsMeasured = true; if (GridColumn != null) GridColumn.NeedsMeasured = true; InvalidateLayout(); } else { InvalidateRender(); } } #endregion #region ValidateStyle private void ValidateStyle() { if (_StyleUpdateCount != SuperGrid.StyleUpdateCount) { ClearEffectiveStyles(); _StyleUpdateCount = SuperGrid.StyleUpdateCount; } } #endregion #region InvalidateStyle /// ///Invalidates the cached Style ///definition for all defined StyleTypes /// public void InvalidateStyle() { ClearEffectiveStyles(); InvalidateLayout(); } /// ///Invalidate the cached Style ///definition for the given StyleType /// /// public void InvalidateStyle(StyleType type) { if (_EffectiveStyles != null) { if (_EffectiveStyles[type] != null) { _EffectiveStyles[type].Dispose(); _EffectiveStyles[type] = null; InvalidateLayout(); } } } #endregion #region ClearEffectiveStyles internal void ClearEffectiveStyles() { if (_EffectiveStyles != null) { _EffectiveStyles.Dispose(); _EffectiveStyles = null; } } #endregion #endregion #region InvalidateRender /// /// InvalidateRender /// public override void InvalidateRender() { if (SuperGrid != null && GridColumn != null) { if (Merged == true) { CellRange cr = GetStateCellRange(); if (cr != null) InvalidateRender(cr.BackBounds); } else { base.InvalidateRender(BackBounds); } } } #endregion #region IComparable Members /// /// CompareTo /// /// /// public int CompareTo(GridCell other) { int sval = 0; if (SuperGrid.DoCompareElementsEvent(GridPanel, this, other, ref sval) == true) return (sval); if (GridPanel.SortUsingHiddenColumns == false) { if (Visible == false) return (other.Visible == false ? 0 : -1); if (other.Visible == false) return (1); } object val1 = IsValueExpression ? ExpValue : Value; object val2 = other.IsValueExpression ? other.ExpValue : other.Value; return (CompareVal.CompareTo(val1, val2)); } #endregion #region ToString /// /// ToString /// /// public override string ToString() { string s = "GridCell " + ColumnIndex + ": {" + (Value ?? "") + "}"; return (s); } #endregion #region Dispose /// /// Dispose /// public void Dispose() { MouseRenderer = null; EditControl = null; RenderControl = null; CellStyles = null; ClearEffectiveStyles(); if (SuperGrid != null) { if (SuperGrid.ActiveElement == this) SuperGrid.ActiveElement = null; } } #endregion #region EditorInfo private class EditorInfo { #region Public variables public Type EditorType; public Type RenderType; public IGridCellEditControl EditControl; public IGridCellEditControl RenderControl; public object[] EditorParams; public object[] RenderParams; #endregion #region Public properties public bool IsEmpty { get { return (EditorType == null && RenderType == null && (EditorParams == null && RenderParams == null)); } } #endregion } #endregion #region CellStates [Flags] private enum Cs { AllowEdit = (1 << 0), DataError = (1 << 1), EmptyCell = (1 << 2), ReadOnly = (1 << 3), Selected = (1 << 4), AnySelected = (1 << 5), ValueExpression = (1 << 6), MergedTop = (1 << 7), MergedLeft = (1 << 8), MergedBottom = (1 << 9), MergedRight = (1 << 10), Merged = (1 << 11), Modified = (1 << 12), } #endregion } #region CompareVal internal class CompareVal { public static int CompareTo(object val1, object val2) { if (val1 != null && val1 != DBNull.Value) { if (val2 != null && val2 != DBNull.Value) { if (val1.GetType() == val2.GetType()) { IComparable icompa = val1 as IComparable; if (icompa != null) return (icompa.CompareTo(val2)); } return (-1); } return (1); } if (val2 != null && val2 != DBNull.Value) return (-1); return (0); } } #endregion #region enums #region CellArea /// /// CellArea /// public enum CellArea { /// /// NoWhere /// NoWhere, /// /// InContent /// InContent, /// /// InExpandButton /// InExpandButton, /// /// InCheckBox /// InCheckBox, /// /// InCellInfo /// InCellInfo, } #endregion #region CellMergeMode /// /// Specifies the type of merging that is permitted /// for cells in the given row or column /// [Flags] public enum CellMergeMode { /// /// Not set /// NotSet = (0 << 0), /// /// No merging /// None = (1 << 0), /// /// Cells can merge horizontally Left /// HorizontalLeft = (1 << 1), /// /// Cells can merge horizontally Right /// HorizontalRight = (1 << 2), /// /// Cells can merge horizontally (both left and right) /// Horizontal = (HorizontalLeft | HorizontalRight), /// /// Cells can merge vertically /// Vertical = (1 << 3), /// /// Cells can merge both horizontally and vertically /// HorizontalAndVertical = (Horizontal | Vertical), } /// /// Specifies the type of merging that is permitted /// for cells in the given row or column /// public enum CellMergeOrder { /// /// Cells can merge horizontally, then vertically /// HorizontalThenVertical, /// /// Cells can merge vertically, then horizontally (this is the default /// if CellMergeMode enables both vertical and horizontal merging) /// VerticalThenHorizontal, } #endregion #region CellSizingSource /// /// Specifies the cell value source for the cell /// sizing operation (either the actual value, formatted value, /// or both) /// public enum CellSizingSource { ActualValue = (1 << 0), // The actual, unformatted cell value FormattedValue = (1 << 1), // The formatted cell value ActualAndFormattedValues = (ActualValue | FormattedValue), // The actual and formatted cell values // (the maximum width/height of the two is used). } #endregion #endregion #region ValueTypeConverter /// /// ValueTypeConverter /// public class ValueTypeConverter : TypeConverter { #region CanConvertTo /// /// CanConvertTo /// /// /// /// public override bool CanConvertTo( ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(string)) return (true); return (base.CanConvertTo(context, destinationType)); } #endregion #region ConvertTo /// /// ConvertTo /// /// /// /// /// /// public override object ConvertTo( ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string)) { string s = value as string; if (s != null) return (s); } return (base.ConvertTo(context, culture, value, destinationType)); } #endregion #region CanConvertFrom /// /// CanConvertFrom /// /// /// /// public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof(string)) return (true); return (base.CanConvertFrom(context, sourceType)); } #endregion #region ConvertFrom /// /// ConvertFrom /// /// /// /// /// public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string) { GridCell cell = context.Instance as GridCell; if (cell != null) { Type type = GetEditType(cell); if (type == typeof (GridDoubleInputEditControl)) return (ConvertFromToDouble((string)value)); if (type == typeof (GridIntegerInputEditControl) || type == typeof (GridProgressBarXEditControl) || type == typeof (GridSliderEditControl) || type == typeof (GridTrackBarEditControl)) { return (ConvertFromToInteger((string) value)); } if (type == typeof (GridNumericUpDownEditControl)) return (ConvertFromToDecimal((string)value)); if (type == typeof (GridCheckBoxXEditControl) || type == typeof (GridCheckBoxEditControl) || type == typeof(GridSwitchButtonEditControl)) { return (ConvertFromToBool((string) value)); } } return (value); } return base.ConvertFrom(context, culture, value); } #region ConvertFromToDouble private double ConvertFromToDouble(string value) { try { return (double.Parse(value)); } catch (Exception) { throw new ArgumentException("Invalid value to convert to 'double'."); } } #endregion #region ConvertFromToInteger private int ConvertFromToInteger(string value) { try { return (int.Parse(value)); } catch (Exception) { throw new ArgumentException("Invalid value to convert to 'int'."); } } #endregion #region ConvertFromToDecimal private decimal ConvertFromToDecimal(string value) { try { return (decimal.Parse(value)); } catch (Exception) { throw new ArgumentException("Invalid value to convert to 'decimal'."); } } #endregion #region ConvertFromToBool private bool ConvertFromToBool(string value) { switch (value.ToLower()) { case "y": case "yes": case "t": case "true": case "1": return (true); case "": case "0": case "n": case "no": case "f": case "false": case null: return (false); default: throw new ArgumentException("Invalid value to convert to 'bool'."); } } #endregion #endregion #region GetEditType private Type GetEditType(GridCell cell) { if (cell.EditorType != null) return (cell.EditorType); if (cell.GridColumn != null) return (cell.GridColumn.EditorType); return (null); } #endregion } #endregion }