8015 lines
226 KiB
C#
8015 lines
226 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// Represents grid cell.
|
|
/// </summary>
|
|
public class GridCell : GridElement, IComparable<GridCell>, 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
|
|
|
|
///<summary>
|
|
/// GridCell
|
|
///</summary>
|
|
public GridCell()
|
|
{
|
|
SetState(Cs.AllowEdit, true);
|
|
}
|
|
|
|
///<summary>
|
|
/// GridCell
|
|
///</summary>
|
|
///<param name="value"></param>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Gets or sets whether the cell can be edited by the user.
|
|
/// </summary>
|
|
[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
|
|
|
|
///<summary>
|
|
/// Gets the scroll adjusted background bounds of the cell
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public Rectangle BackBounds
|
|
{
|
|
get
|
|
{
|
|
if (_BoundsUpdateCount != SuperGrid.BoundsUpdateCount)
|
|
UpdateBoundingRects();
|
|
|
|
return (_BackBounds);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Bounds
|
|
|
|
///<summary>
|
|
/// Gets the scroll adjusted bounds of the cell
|
|
///</summary>
|
|
[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
|
|
|
|
/// <summary>
|
|
/// Gets or sets the relative bounds of the cell
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public override Rectangle BoundsRelative
|
|
{
|
|
get { return (base.BoundsRelative); }
|
|
|
|
internal set
|
|
{
|
|
base.BoundsRelative = value;
|
|
|
|
_BoundsUpdateCount = 0;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region CellBounds
|
|
|
|
///<summary>
|
|
/// Gets the clipped, scroll adjusted, bounding rectangle of the cell
|
|
///</summary>
|
|
[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
|
|
|
|
/// <summary>
|
|
/// Gets or sets the visual styles assigned to the cell
|
|
/// </summary>
|
|
[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
|
|
|
|
/// <summary>
|
|
/// Gets the associated Column index for the cell
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public int ColumnIndex
|
|
{
|
|
get { return (_ColumnIndex); }
|
|
internal set { _ColumnIndex = value; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ContentBounds
|
|
|
|
///<summary>
|
|
/// Gets the scroll adjusted, content only, bounding rectangle of the cell
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public Rectangle ContentBounds
|
|
{
|
|
get
|
|
{
|
|
GridPanel panel = GridPanel;
|
|
|
|
if (panel != null)
|
|
return (GetContentBounds(panel));
|
|
|
|
return (Rectangle.Empty);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region EditBounds
|
|
|
|
///<summary>
|
|
/// Gets the clipped, scroll adjusted, edit bounding rectangle of the cell
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public Rectangle EditBounds
|
|
{
|
|
get
|
|
{
|
|
GridPanel panel = GridPanel;
|
|
|
|
if (panel != null)
|
|
return (GetEditBounds(panel));
|
|
|
|
return (Rectangle.Empty);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region EditControl
|
|
|
|
///<summary>
|
|
/// 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.
|
|
///</summary>
|
|
[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
|
|
|
|
///<summary>
|
|
/// Gets or sets whether the value
|
|
/// being edited has been changed in the editor
|
|
///</summary>
|
|
[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
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
[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
|
|
|
|
///<summary>
|
|
/// Indicates the cell editor type. This is the control type
|
|
/// used to perform the actual modification of the cell value
|
|
///</summary>
|
|
[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
|
|
|
|
///<summary>
|
|
/// Gets the last evaluated expression value for the cell.
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public object ExpValue
|
|
{
|
|
get { return (_ExpValue); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region FormattedValue
|
|
|
|
/// <summary>
|
|
/// Gets the associated Formatted Value for the cell
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public string FormattedValue
|
|
{
|
|
get { return (GetFormattedValue()); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GridColumn
|
|
|
|
/// <summary>
|
|
/// Gets the GridColumn associated with the cell
|
|
/// </summary>
|
|
[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
|
|
|
|
///<summary>
|
|
/// Gets the GridRow associated with the cell.
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public GridRow GridRow
|
|
{
|
|
get { return (Parent as GridRow); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region HighLightBounds
|
|
|
|
///<summary>
|
|
/// Gets the scroll adjusted, bounding rectangle used
|
|
/// to highlight the cell contents when selected.
|
|
///</summary>
|
|
[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
|
|
|
|
/// <summary>
|
|
/// Gets or sets the cell informational Image (the image
|
|
/// to display when InfoText is non-empty)
|
|
/// </summary>
|
|
[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
|
|
|
|
///<summary>
|
|
/// Gets the scroll adjusted, bounding
|
|
/// rectangle for the current set info image
|
|
///</summary>
|
|
[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
|
|
|
|
///<summary>
|
|
/// 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.
|
|
///</summary>
|
|
[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
|
|
|
|
///<summary>
|
|
/// Gets whether the cell is the Active cell.
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool IsActiveCell
|
|
{
|
|
get
|
|
{
|
|
if (SuperGrid != null)
|
|
return (SuperGrid.ActiveCell == this);
|
|
|
|
return(false);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IsCellVisible
|
|
|
|
///<summary>
|
|
/// Gets whether the cell is visible (taking row visibility,
|
|
/// column visibility, and expanded row state into account).
|
|
///</summary>
|
|
[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
|
|
|
|
///<summary>
|
|
/// Gets whether setting the cell Value has caused a Data Error
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool IsDataError
|
|
{
|
|
get { return (TestState(Cs.DataError)); }
|
|
internal set { SetState(Cs.DataError, value); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IsEditorCell
|
|
|
|
///<summary>
|
|
/// Gets whether the cell is the cell being edited.
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool IsEditorCell
|
|
{
|
|
get
|
|
{
|
|
if (SuperGrid != null)
|
|
return (SuperGrid.EditorCell == this);
|
|
|
|
return (false);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IsEmptyCell
|
|
|
|
///<summary>
|
|
/// Gets whether the cell is an Empty cell.
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool IsEmptyCell
|
|
{
|
|
get { return (TestState(Cs.EmptyCell)); }
|
|
internal set { SetState(Cs.EmptyCell, value); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IsHFrozen
|
|
|
|
///<summary>
|
|
/// Gets whether the cell is horizontally frozen
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool IsHFrozen
|
|
{
|
|
get
|
|
{
|
|
GridColumn column = GridColumn;
|
|
|
|
if (column != null)
|
|
return (column.IsHFrozen);
|
|
|
|
return (false);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IsPrimaryCell
|
|
|
|
///<summary>
|
|
/// Gets whether the cell is the defined PrimaryCell
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool IsPrimaryCell
|
|
{
|
|
get
|
|
{
|
|
GridPanel panel = GridPanel;
|
|
|
|
if (panel != null)
|
|
return (panel.PrimaryColumnIndex == _ColumnIndex);
|
|
|
|
return (false);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IsReadOnly
|
|
|
|
///<summary>
|
|
/// Gets whether the cell is ReadOnly due to
|
|
/// row, column, or cell ReadOnly property status.
|
|
///</summary>
|
|
[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
|
|
|
|
///<summary>
|
|
/// Gets whether the cell is selectable due to
|
|
/// row, column, or cell AllowSelection property status.
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool IsSelectable
|
|
{
|
|
get
|
|
{
|
|
return (AllowSelection == true &&
|
|
GridRow.AllowSelection == true &&
|
|
GridColumn.AllowSelection == true);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IsSelected
|
|
|
|
///<summary>
|
|
/// Gets or sets whether the cell is selected.
|
|
///</summary>
|
|
[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
|
|
|
|
///<summary>
|
|
/// Gets whether the cell Value is an expression.
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool IsValueExpression
|
|
{
|
|
get { return (TestState(Cs.ValueExpression)); }
|
|
internal set { SetState(Cs.ValueExpression, value); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IsValueNull
|
|
|
|
///<summary>
|
|
/// Gets whether the cell Value is null.
|
|
///</summary>
|
|
[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
|
|
|
|
///<summary>
|
|
///Gets whether the cell is merged
|
|
///</summary>
|
|
[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
|
|
|
|
///<summary>
|
|
///Gets or sets whether the cell is Merged at the Bottom
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool MergedBottom
|
|
{
|
|
get { return (TestState(Cs.MergedBottom)); }
|
|
set { SetState(Cs.MergedBottom, value); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region MergedLeft
|
|
|
|
///<summary>
|
|
///Gets or sets whether the cell is Merged to the Left
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool MergedLeft
|
|
{
|
|
get { return (TestState(Cs.MergedLeft)); }
|
|
set { SetState(Cs.MergedLeft, value); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region MergedRight
|
|
|
|
///<summary>
|
|
///Gets or sets whether the cell is Merged to the Right
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool MergedRight
|
|
{
|
|
get { return (TestState(Cs.MergedRight)); }
|
|
set { SetState(Cs.MergedRight, value); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region MergedTop
|
|
|
|
///<summary>
|
|
///Gets or sets whether the cell is Merged at the Top
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool MergedTop
|
|
{
|
|
get { return (TestState(Cs.MergedTop)); }
|
|
set { SetState(Cs.MergedTop, value); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region MergeSuspended
|
|
|
|
///<summary>
|
|
///Gets whether the cell is merged and suspended.
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool MergeSuspended
|
|
{
|
|
get
|
|
{
|
|
CellRange cr = GetCellRange();
|
|
|
|
return (cr != null && cr.Suspended == true);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region NullString
|
|
|
|
/// <summary>
|
|
/// Gets how null values are displayed
|
|
/// </summary>
|
|
[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
|
|
|
|
/// <summary>
|
|
/// Gets or sets whether the user can change cell contents
|
|
/// </summary>
|
|
[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
|
|
|
|
///<summary>
|
|
/// Gets the current set Render Control for the cell
|
|
///</summary>
|
|
[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
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
[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
|
|
|
|
///<summary>
|
|
/// Gets or sets the cell render type. This is the control
|
|
/// type used to perform the default rendering of the cell value
|
|
///</summary>
|
|
[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
|
|
|
|
/// <summary>
|
|
/// Gets the associated Row index for the cell
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public int RowIndex
|
|
{
|
|
get
|
|
{
|
|
GridRow row = GridRow;
|
|
|
|
return (row != null ? row.RowIndex : -1);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region UnMergedBounds
|
|
|
|
///<summary>
|
|
/// Gets the scroll adjusted un-merged bounds of the cell
|
|
///</summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public Rectangle UnMergedBounds
|
|
{
|
|
get
|
|
{
|
|
if (_BoundsUpdateCount != SuperGrid.BoundsUpdateCount)
|
|
UpdateBoundingRects();
|
|
|
|
return (_Bounds);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Value
|
|
|
|
/// <summary>
|
|
/// Gets or sets the cell value
|
|
/// </summary>
|
|
[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
|
|
|
|
/// <summary>
|
|
/// GetValue
|
|
/// </summary>
|
|
/// <param name="panel"></param>
|
|
/// <returns></returns>
|
|
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
|
|
|
|
/// <summary>
|
|
/// SetValue
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
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<GridCell>());
|
|
}
|
|
|
|
#region RefreshExpressions
|
|
|
|
private void RefreshExpressions(
|
|
GridPanel panel, GridCell gridCell, List<GridCell> usedCells)
|
|
{
|
|
foreach (KeyValuePair<GridCell, EEval> item in panel.ExpDictionary)
|
|
{
|
|
List<GridCell> 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;
|
|
|
|
/// <summary>
|
|
/// Performs the layout of the item and sets
|
|
/// the Size property to size that item will take.
|
|
/// </summary>
|
|
/// <param name="layoutInfo">Layout information.</param>
|
|
/// <param name="stateInfo"></param>
|
|
/// <param name="constraintSize"></param>
|
|
protected override void MeasureOverride(
|
|
GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize)
|
|
{
|
|
//_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
|
|
|
|
/// <summary>
|
|
/// Performs the arrange pass layout of the item
|
|
/// when final position and size of the item has been set.
|
|
/// </summary>
|
|
/// <param name="layoutInfo">Layout information.</param>
|
|
/// <param name="stateInfo"></param>
|
|
/// <param name="layoutBounds"></param>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Performs drawing of the item and its children.
|
|
/// </summary>
|
|
/// <param name="renderInfo">Holds contextual rendering information.</param>
|
|
protected override void RenderOverride(GridRenderInfo renderInfo)
|
|
{
|
|
GridPanel panel = GridPanel;
|
|
|
|
if (panel != null)
|
|
{
|
|
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
|
|
|
|
///<summary>
|
|
///Gets the CellRange, if any, that the cell is a member of.
|
|
///</summary>
|
|
///<returns>CellRange or null.</returns>
|
|
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
|
|
|
|
///<summary>
|
|
///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).
|
|
///</summary>
|
|
///<param name="activate">If true, cell will be made the active cell.</param>
|
|
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
|
|
|
|
///<summary>
|
|
///Resumes the suspended merge where the cell is a participant
|
|
///</summary>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Returns element at specified mouse coordinates
|
|
/// </summary>
|
|
/// <param name="e">Mouse event arguments</param>
|
|
/// <returns>Reference to child Cell element or null
|
|
/// if no element at specified coordinates</returns>
|
|
protected virtual CellArea GetCellAreaAt(MouseEventArgs e)
|
|
{
|
|
return GetCellAreaAt(e.X, e.Y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns element at specified mouse coordinates
|
|
/// </summary>
|
|
/// <param name="x">Horizontal position</param>
|
|
/// <param name="y">Vertical position</param>
|
|
/// <returns>Reference to child element or null
|
|
/// if no element at specified coordinates</returns>
|
|
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
|
|
|
|
///<summary>
|
|
/// Ensures that the given cell is visibly centered
|
|
/// (as much as possible) in the grid display.
|
|
///</summary>
|
|
///<param name="center"></param>
|
|
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
|
|
|
|
///<summary>
|
|
/// Sets the given cell as Active
|
|
///</summary>
|
|
///<returns>true - if successful</returns>
|
|
public bool SetActive()
|
|
{
|
|
return (SetActive(false));
|
|
}
|
|
|
|
///<summary>
|
|
/// Makes the given cell active and
|
|
/// optionally selects the given cell
|
|
///</summary>
|
|
///<returns>true, if successful</returns>
|
|
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
|
|
|
|
///<summary>
|
|
/// Begins a Modal cell edit operation using
|
|
/// the defined column or cell Modal EditControl.
|
|
///</summary>
|
|
///<param name="selectAll"></param>
|
|
///<returns></returns>
|
|
public IGridCellEditControl BeginEdit(bool selectAll)
|
|
{
|
|
return (BeginEdit(selectAll, null));
|
|
}
|
|
|
|
///<summary>
|
|
/// 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.
|
|
///</summary>
|
|
///<returns>Cell edit control</returns>
|
|
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
|
|
|
|
///<summary>
|
|
/// This routine ends an in-progress Modal cell edit operation.
|
|
///</summary>
|
|
///<returns>true if ended</returns>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Used by IGridCellEditControl editors to update the
|
|
/// cell Value from the EditorValue, performing any needed
|
|
/// data conversions for proper data typing.
|
|
/// </summary>
|
|
/// <param name="editor"></param>
|
|
/// <returns></returns>
|
|
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
|
|
|
|
///<summary>
|
|
/// Cancels the current in-progress Modal cell edit operation.
|
|
///</summary>
|
|
///<returns>true if canceled</returns>
|
|
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
|
|
|
|
///<summary>
|
|
/// PostCellKeyDown
|
|
///</summary>
|
|
///<returns></returns>
|
|
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
|
|
|
|
///<summary>
|
|
/// PositionEditControl
|
|
///</summary>
|
|
///<param name="editor"></param>
|
|
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
|
|
|
|
///<summary>
|
|
/// This routine can be called by a cell editor / renderer to
|
|
/// perform default cell rendering provided by the grid.
|
|
///</summary>
|
|
///<param name="editor"></param>
|
|
///<param name="g"></param>
|
|
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
|
|
|
|
///<summary>
|
|
/// Gets the resultant value of the evaluated Cell Expression, if
|
|
/// applicable. Otherwise returns the given value.
|
|
///</summary>
|
|
///<param name="source"></param>
|
|
///<returns></returns>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Gets the cell paint bitmap
|
|
/// </summary>
|
|
/// <param name="editor"></param>
|
|
/// <param name="r"></param>
|
|
/// <returns></returns>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Paints the button background and content
|
|
/// </summary>
|
|
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
|
|
|
|
///<summary>
|
|
/// Performs default cell background painting for the cell.
|
|
///</summary>
|
|
///<param name="e"></param>
|
|
///<param name="editor"></param>
|
|
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
|
|
|
|
///<summary>
|
|
/// ExtendSelection
|
|
///</summary>
|
|
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
|
|
|
|
///<summary>
|
|
/// Called by the cell editor to conditionally set
|
|
/// the cells row level EditorDirty state.
|
|
///</summary>
|
|
///<param name="editor"></param>
|
|
public void SetEditorDirty(IGridCellEditControl editor)
|
|
{
|
|
if (GridColumn.MarkRowDirtyOnCellValueChange == true)
|
|
{
|
|
if (SuperGrid.DoRowMarkedDirtyEvent(this, editor) == false)
|
|
EditorDirty = true;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region EditorValueChanged
|
|
|
|
///<summary>
|
|
/// This routine is called by cell editors to signal to the grid
|
|
/// that the editor has changed the cell Value.
|
|
///</summary>
|
|
///<param name="editor"></param>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Gets the scroll adjusted background bounding rectangle
|
|
/// </summary>
|
|
/// <param name="panel"></param>
|
|
/// <returns></returns>
|
|
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));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the scroll adjusted bounding rectangle
|
|
/// </summary>
|
|
/// <param name="panel"></param>
|
|
/// <param name="backBounds"></param>
|
|
/// <returns></returns>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Gets the SViewRect clipped Bounds
|
|
/// </summary>
|
|
/// <param name="panel"></param>
|
|
/// <returns></returns>
|
|
private Rectangle GetCellBounds(GridPanel panel)
|
|
{
|
|
return (GetClippedBounds(panel, Bounds));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetContentBounds
|
|
|
|
internal Rectangle GetContentBounds(GridPanel panel)
|
|
{
|
|
return (GetContentBounds(panel, Bounds));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the cell content (excludes image) bounding rectangle
|
|
/// </summary>
|
|
/// <param name="panel"></param>
|
|
/// <param name="bounds"></param>
|
|
/// <returns></returns>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Gets
|
|
/// </summary>
|
|
/// <param name="panel"></param>
|
|
/// <returns></returns>
|
|
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
|
|
|
|
///<summary>
|
|
/// Get the CellEditBounds for the cell.
|
|
///</summary>
|
|
///<param name="editor"></param>
|
|
///<returns></returns>
|
|
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
|
|
|
|
///<summary>
|
|
/// 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.
|
|
///</summary>
|
|
///<returns></returns>
|
|
public CellVisualStyle GetEffectiveStyle()
|
|
{
|
|
bool selected = IsSelected;
|
|
|
|
StyleState cellState = GetCellState(selected);
|
|
CellVisualStyle style = GetEffectiveStyle(cellState);
|
|
|
|
return (style);
|
|
}
|
|
|
|
///<summary>
|
|
/// 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.
|
|
///</summary>
|
|
///<param name="type"></param>
|
|
///<returns></returns>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Occurs when one of element visual styles has property changes.
|
|
/// Default implementation invalidates visual appearance of element.
|
|
/// </summary>
|
|
/// <param name="sender">VisualStyle that changed.</param>
|
|
/// <param name="e">Event arguments.</param>
|
|
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
|
|
|
|
///<summary>
|
|
///Invalidates the cached Style
|
|
///definition for all defined StyleTypes
|
|
///</summary>
|
|
public void InvalidateStyle()
|
|
{
|
|
ClearEffectiveStyles();
|
|
|
|
InvalidateLayout();
|
|
}
|
|
|
|
///<summary>
|
|
///Invalidate the cached Style
|
|
///definition for the given StyleType
|
|
///</summary>
|
|
///<param name="type"></param>
|
|
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
|
|
|
|
/// <summary>
|
|
/// InvalidateRender
|
|
/// </summary>
|
|
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<GridCell> Members
|
|
|
|
/// <summary>
|
|
/// CompareTo
|
|
/// </summary>
|
|
/// <param name="other"></param>
|
|
/// <returns></returns>
|
|
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
|
|
|
|
/// <summary>
|
|
/// ToString
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override string ToString()
|
|
{
|
|
string s = "GridCell " + ColumnIndex +
|
|
": {" + (Value ?? "<null>") + "}";
|
|
|
|
return (s);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Dispose
|
|
|
|
/// <summary>
|
|
/// Dispose
|
|
/// </summary>
|
|
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
|
|
|
|
///<summary>
|
|
/// CellArea
|
|
///</summary>
|
|
public enum CellArea
|
|
{
|
|
///<summary>
|
|
/// NoWhere
|
|
///</summary>
|
|
NoWhere,
|
|
|
|
///<summary>
|
|
/// InContent
|
|
///</summary>
|
|
InContent,
|
|
|
|
///<summary>
|
|
/// InExpandButton
|
|
///</summary>
|
|
InExpandButton,
|
|
|
|
///<summary>
|
|
/// InCheckBox
|
|
///</summary>
|
|
InCheckBox,
|
|
|
|
///<summary>
|
|
/// InCellInfo
|
|
///</summary>
|
|
InCellInfo,
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region CellMergeMode
|
|
|
|
///<summary>
|
|
/// Specifies the type of merging that is permitted
|
|
/// for cells in the given row or column
|
|
///</summary>
|
|
[Flags]
|
|
public enum CellMergeMode
|
|
{
|
|
///<summary>
|
|
/// Not set
|
|
///</summary>
|
|
NotSet = (0 << 0),
|
|
|
|
///<summary>
|
|
/// No merging
|
|
///</summary>
|
|
None = (1 << 0),
|
|
|
|
///<summary>
|
|
/// Cells can merge horizontally Left
|
|
///</summary>
|
|
HorizontalLeft = (1 << 1),
|
|
|
|
///<summary>
|
|
/// Cells can merge horizontally Right
|
|
///</summary>
|
|
HorizontalRight = (1 << 2),
|
|
|
|
///<summary>
|
|
/// Cells can merge horizontally (both left and right)
|
|
///</summary>
|
|
Horizontal = (HorizontalLeft | HorizontalRight),
|
|
|
|
///<summary>
|
|
/// Cells can merge vertically
|
|
///</summary>
|
|
Vertical = (1 << 3),
|
|
|
|
///<summary>
|
|
/// Cells can merge both horizontally and vertically
|
|
///</summary>
|
|
HorizontalAndVertical = (Horizontal | Vertical),
|
|
}
|
|
|
|
///<summary>
|
|
/// Specifies the type of merging that is permitted
|
|
/// for cells in the given row or column
|
|
///</summary>
|
|
public enum CellMergeOrder
|
|
{
|
|
///<summary>
|
|
/// Cells can merge horizontally, then vertically
|
|
///</summary>
|
|
HorizontalThenVertical,
|
|
|
|
///<summary>
|
|
/// Cells can merge vertically, then horizontally (this is the default
|
|
/// if CellMergeMode enables both vertical and horizontal merging)
|
|
///</summary>
|
|
VerticalThenHorizontal,
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region CellSizingSource
|
|
|
|
/// <summary>
|
|
/// Specifies the cell value source for the cell
|
|
/// sizing operation (either the actual value, formatted value,
|
|
/// or both)
|
|
/// </summary>
|
|
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
|
|
|
|
///<summary>
|
|
/// ValueTypeConverter
|
|
///</summary>
|
|
public class ValueTypeConverter : TypeConverter
|
|
{
|
|
#region CanConvertTo
|
|
|
|
/// <summary>
|
|
/// CanConvertTo
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="destinationType"></param>
|
|
/// <returns></returns>
|
|
public override bool CanConvertTo(
|
|
ITypeDescriptorContext context, Type destinationType)
|
|
{
|
|
if (destinationType == typeof(string))
|
|
return (true);
|
|
|
|
return (base.CanConvertTo(context, destinationType));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ConvertTo
|
|
|
|
/// <summary>
|
|
/// ConvertTo
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="culture"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="destinationType"></param>
|
|
/// <returns></returns>
|
|
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
|
|
|
|
/// <summary>
|
|
/// CanConvertFrom
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="sourceType"></param>
|
|
/// <returns></returns>
|
|
public override bool CanConvertFrom(
|
|
ITypeDescriptorContext context, Type sourceType)
|
|
{
|
|
if (sourceType == typeof(string))
|
|
return (true);
|
|
|
|
return (base.CanConvertFrom(context, sourceType));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ConvertFrom
|
|
|
|
/// <summary>
|
|
/// ConvertFrom
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="culture"></param>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
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
|
|
}
|