private DataGridViewCellStyle defaultCellStyle;
//private Control editingControl;
private DataGridViewEditMode editMode;
- private bool enableHeadersVisualStyles;
+ private bool enableHeadersVisualStyles = true;
private DataGridViewCell firstDisplayedCell;
private int firstDisplayedScrollingColumnHiddenWidth;
private int firstDisplayedScrollingColumnIndex;
private HScrollBar horizontalScrollBar;
private VScrollBar verticalScrollBar;
private Control editingControl;
-
+ private bool new_row_commited = true;
+
// These are used to implement selection behaviour with SHIFT pressed.
private int selected_row = -1;
private int selected_column = -1;
+ // Stuff for error Tooltips
+ private Timer tooltip_timer;
+ private ToolTip tooltip_window;
+ private DataGridViewCell tooltip_currently_showing;
+
private DataGridViewSelectedRowCollection selected_rows;
private DataGridViewSelectedColumnCollection selected_columns;
private DataGridViewRow editing_row;
private int gridWidth;
private int gridHeight;
+ DataGridViewHeaderCell pressed_header_cell;
+ DataGridViewHeaderCell entered_header_cell;
+
+ // For column/row resizing via mouse
+ private bool column_resize_active = false;
+ private bool row_resize_active = false;
+ private int resize_band = -1;
+ private int resize_band_start = 0;
+ private int resize_band_delta = 0;
+
public DataGridView ()
{
SetStyle (ControlStyles.Opaque, true);
backColor = Control.DefaultBackColor;
backgroundColor = SystemColors.AppWorkspace;
borderStyle = BorderStyle.FixedSingle;
- cellBorderStyle = DataGridViewCellBorderStyle.None;
+ cellBorderStyle = DataGridViewCellBorderStyle.Single;
clipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithAutoHeaderText;
columnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
columnHeadersDefaultCellStyle = new DataGridViewCellStyle();
defaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
defaultCellStyle.WrapMode = DataGridViewTriState.False;
editMode = DataGridViewEditMode.EditOnKeystrokeOrF2;
+ firstDisplayedScrollingColumnHiddenWidth = 0;
+ isCurrentCellDirty = false;
multiSelect = true;
readOnly = false;
rowHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
allowUserToAddRows = value;
OnAllowUserToAddRowsChanged(EventArgs.Empty);
PrepareEditingRow (false, false);
+ Invalidate ();
}
}
}
}
}
}
+
autoSizeColumnsMode = value;
+ AutoResizeColumns (value);
+ Invalidate ();
}
}
throw new InvalidOperationException("Cant set this property to AllHeaders or DisplayedHeaders in this DataGridView.");
}
autoSizeRowsMode = value;
+
+ if (value == DataGridViewAutoSizeRowsMode.None)
+ foreach (DataGridViewRow row in Rows)
+ row.ResetToExplicitHeight ();
+ else
+ AutoResizeRows (value);
+
OnAutoSizeRowsModeChanged(new DataGridViewAutoSizeModeEventArgs(false));
+ Invalidate ();
////////////////////////////////////////////////////////////////
}
}
get { return cellBorderStyle; }
set {
if (cellBorderStyle != value) {
+ if (value == DataGridViewCellBorderStyle.Custom)
+ throw new ArgumentException ("CellBorderStyle cannot be set to Custom.");
+
cellBorderStyle = value;
- OnCellBorderStyleChanged(EventArgs.Empty);
+
+ DataGridViewAdvancedBorderStyle border = new DataGridViewAdvancedBorderStyle ();
+
+ switch (cellBorderStyle) {
+ case DataGridViewCellBorderStyle.Single:
+ border.All = DataGridViewAdvancedCellBorderStyle.Single;
+ break;
+ case DataGridViewCellBorderStyle.Raised:
+ case DataGridViewCellBorderStyle.RaisedVertical:
+ border.Bottom = DataGridViewAdvancedCellBorderStyle.None;
+ border.Top = DataGridViewAdvancedCellBorderStyle.None;
+ border.Left = DataGridViewAdvancedCellBorderStyle.Outset;
+ border.Right = DataGridViewAdvancedCellBorderStyle.Outset;
+ break;
+ case DataGridViewCellBorderStyle.Sunken:
+ border.All = DataGridViewAdvancedCellBorderStyle.Inset;
+ break;
+ case DataGridViewCellBorderStyle.None:
+ border.All = DataGridViewAdvancedCellBorderStyle.None;
+ break;
+ case DataGridViewCellBorderStyle.SingleVertical:
+ border.Bottom = DataGridViewAdvancedCellBorderStyle.None;
+ border.Top = DataGridViewAdvancedCellBorderStyle.None;
+ border.Left = DataGridViewAdvancedCellBorderStyle.None;
+ border.Right = DataGridViewAdvancedCellBorderStyle.Single;
+ break;
+ case DataGridViewCellBorderStyle.SunkenVertical:
+ border.Bottom = DataGridViewAdvancedCellBorderStyle.None;
+ border.Top = DataGridViewAdvancedCellBorderStyle.None;
+ border.Left = DataGridViewAdvancedCellBorderStyle.Inset;
+ border.Right = DataGridViewAdvancedCellBorderStyle.Inset;
+ break;
+ case DataGridViewCellBorderStyle.SingleHorizontal:
+ case DataGridViewCellBorderStyle.SunkenHorizontal:
+ border.Bottom = DataGridViewAdvancedCellBorderStyle.Inset;
+ border.Top = DataGridViewAdvancedCellBorderStyle.Inset;
+ border.Left = DataGridViewAdvancedCellBorderStyle.None;
+ border.Right = DataGridViewAdvancedCellBorderStyle.None;
+ break;
+ case DataGridViewCellBorderStyle.RaisedHorizontal:
+ border.Bottom = DataGridViewAdvancedCellBorderStyle.Outset;
+ border.Top = DataGridViewAdvancedCellBorderStyle.Outset;
+ border.Left = DataGridViewAdvancedCellBorderStyle.None;
+ border.Right = DataGridViewAdvancedCellBorderStyle.None;
+ break;
+ }
+
+ advancedCellBorderStyle = border;
+
+ OnCellBorderStyleChanged (EventArgs.Empty);
}
}
}
/// to the data cache, or the new cell is in a hidden
/// row.
/////////////////////////////////////////////////////
- if (value.DataGridView != this) {
+ if (value.DataGridView != this)
throw new ArgumentException("The cell is not in this DataGridView.");
- }
- currentCell = value;
- currentRow = currentCell.OwningRow;
+
+ if (value != null)
+ MoveCurrentCell (value.OwningColumn.Index, value.OwningRow.Index, true, false, false, true);
+ else
+ MoveCurrentCell (-1, -1, true, false, false, true);
}
}
[Browsable (false)]
public DataGridViewRow CurrentRow {
- get { return currentRow; }
+ get {
+ if (currentCell != null)
+ return currentCell.OwningRow;
+ return null;
+ }
}
[DefaultValue ("")]
get { return dataMember; }
set {
if (dataMember != value) {
+ ClearBinding ();
+
dataMember = value;
OnDataMemberChanged(EventArgs.Empty);
+
+ DoBinding ();
}
}
}
public object DataSource {
get { return dataSource; }
set {
- if (dataSource != value) {
- /* The System.Windows.Forms.DataGridView class supports the standard Windows Forms data-binding model. This means the data source can be of any type that implements:
- - the System.Collections.IList interface, including one-dimensional arrays.
- - the System.ComponentModel.IListSource interface, such as the System.Data.DataTable and System.Data.DataSet classes.
- - the System.ComponentModel.IBindingList interface, such as the System.ComponentModel.Collections.BindingList<> class.
- - the System.ComponentModel.IBindingListView interface, such as the System.Windows.Forms.BindingSource class.
- */
- if (!(value == null || value is IList || value is IListSource || value is IBindingList || value is IBindingListView)) {
- throw new NotSupportedException("Type cant be binded.");
- }
- if (dataSource != null) {
- columns.Clear();
- rows.Clear();
- if (dataSource is DataView) {
- (dataSource as DataView).ListChanged -= OnListChanged;
- }
- if (dataSource is DataTable) {
- ((dataSource as IListSource).GetList() as DataView).ListChanged -= OnListChanged;
- }
- }
- dataSource = value;
- OnDataSourceChanged(EventArgs.Empty);
- if (dataSource != null) {
- // DataBinding
- if (value is IList) {
- BindIList(value as IList);
- }
- else if (value is IListSource) {
- BindIListSource(value as IListSource);
- }
- else if (value is IBindingList) {
- BindIBindingList(value as IBindingList);
- }
- else if (value is IBindingListView) {
- BindIBindingListView(value as IBindingListView);
- //bool cosa = ((value as IBindingListView).SortDescriptions as IList).IsFixedSize;
- }
- OnDataBindingComplete(new DataGridViewBindingCompleteEventArgs(ListChangedType.Reset));
- }
- Invalidate();
- }
+ /* The System.Windows.Forms.DataGridView class supports the standard Windows Forms data-binding model. This means the data source can be of any type that implements:
+ - the System.Collections.IList interface, including one-dimensional arrays.
+ - the System.ComponentModel.IListSource interface, such as the System.Data.DataTable and System.Data.DataSet classes.
+ - the System.ComponentModel.IBindingList interface, such as the System.ComponentModel.Collections.BindingList<> class.
+ - the System.ComponentModel.IBindingListView interface, such as the System.Windows.Forms.BindingSource class.
+ */
+ if (!(value == null || value is IList || value is IListSource || value is IBindingList || value is IBindingListView))
+ throw new NotSupportedException ("Type cannot be bound.");
+
+ ClearBinding ();
+
+ dataSource = value;
+ OnDataSourceChanged (EventArgs.Empty);
+
+ DoBinding ();
}
}
set { enableHeadersVisualStyles = value; }
}
+ internal DataGridViewHeaderCell EnteredHeaderCell {
+ get { return entered_header_cell; }
+ set {
+ if (entered_header_cell == value)
+ return;
+ if (ThemeEngine.Current.DataGridViewHeaderCellHasHotStyle (this)) {
+ Region area_to_invalidate = new Region ();
+ area_to_invalidate.MakeEmpty ();
+ if (entered_header_cell != null)
+ area_to_invalidate.Union (GetHeaderCellBounds (entered_header_cell));
+ entered_header_cell = value;
+ if (entered_header_cell != null)
+ area_to_invalidate.Union (GetHeaderCellBounds (entered_header_cell));
+ Invalidate (area_to_invalidate);
+ area_to_invalidate.Dispose ();
+ } else
+ entered_header_cell = value;
+ }
+ }
+
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public DataGridViewCell FirstDisplayedCell {
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public int NewRowIndex {
get {
- if (!allowUserToAddRows) {
+ if (!allowUserToAddRows || ColumnCount == 0) {
return -1;
}
return rows.Count - 1;
set { }
}
+ internal DataGridViewHeaderCell PressedHeaderCell {
+ get { return pressed_header_cell; }
+ }
+
[Browsable (true)]
[DefaultValue (false)]
public bool ReadOnly {
ColumnCount = 1;
for (int i = rows.Count; i < value; i++) {
- DataGridViewRow row = (DataGridViewRow) RowTemplate.Clone ();
+ DataGridViewRow row = (DataGridViewRow) RowTemplateFull;
rows.AddInternal (row, false);
foreach (DataGridViewColumn col in columns)
}
}
+ // RowTemplate is just the row, it does not contain Cells
[Browsable (true)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
public DataGridViewRow RowTemplate {
get {
- if (rowTemplate == null) {
- return new DataGridViewRow();
- }
+ if (rowTemplate == null)
+ rowTemplate = new DataGridViewRow ();
+
return rowTemplate;
}
set {
}
}
+ // Take the RowTemplate, clone it, and add Cells
+ // Note this is not stored, so you don't need to Clone it
internal DataGridViewRow RowTemplateFull {
get {
DataGridViewRow row = (DataGridViewRow) RowTemplate.Clone ();
public DataGridViewSelectionMode SelectionMode {
get { return selectionMode; }
set {
- if (!Enum.IsDefined(typeof(DataGridViewSelectionMode), value)) {
- throw new InvalidEnumArgumentException("Value is not valid DataGridViewSelectionMode.");
- }
+ if (!Enum.IsDefined (typeof(DataGridViewSelectionMode), value))
+ throw new InvalidEnumArgumentException ("Value is not valid DataGridViewSelectionMode.");
+
+ if (value == DataGridViewSelectionMode.ColumnHeaderSelect || value == DataGridViewSelectionMode.FullColumnSelect)
+ foreach (DataGridViewColumn col in Columns)
+ if (col.SortMode == DataGridViewColumnSortMode.Automatic)
+ throw new InvalidOperationException (string.Format ("Cannot set SelectionMode to {0} because there are Automatic sort columns.", value));
+
selectionMode = value;
}
}
get { return verticalScrollingOffset; }
}
+ [MonoTODO ("VirtualMode is not supported.")]
[EditorBrowsable (EditorBrowsableState.Advanced)]
[DefaultValue (false)]
public bool VirtualMode {
public void AutoResizeRow (int rowIndex)
{
- AutoResizeRow (rowIndex, DataGridViewAutoSizeRowMode.AllCells);
+ AutoResizeRow (rowIndex, DataGridViewAutoSizeRowMode.AllCells, true);
}
public void AutoResizeRow (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode)
{
- if (autoSizeRowMode == DataGridViewAutoSizeRowMode.RowHeader && !rowHeadersVisible)
- throw new InvalidOperationException ("row headers are not visible");
- if (rowIndex < 0 || rowIndex > Rows.Count - 1)
- throw new ArgumentOutOfRangeException ("rowIndex");
-
- DataGridViewRow row = GetRowInternal (rowIndex);
-
- if (autoSizeRowMode == DataGridViewAutoSizeRowMode.RowHeader) {
- row.Height = row.HeaderCell.PreferredSize.Width;
- return;
- }
-
- int row_height = 0;
-
- foreach (DataGridViewCell cell in row.Cells)
- row_height = Math.Max (row_height, cell.PreferredSize.Height);
-
- if (autoSizeRowMode == DataGridViewAutoSizeRowMode.AllCellsExceptHeader)
- row.Height = row_height;
- else
- row.Height = Math.Max (row_height, row.HeaderCell.PreferredSize.Width);
+ AutoResizeRow (rowIndex, autoSizeRowMode, true);
}
public void AutoResizeRowHeadersWidth (DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode)
public void AutoResizeRows (DataGridViewAutoSizeRowsMode autoSizeRowsMode)
{
if (!Enum.IsDefined(typeof(DataGridViewAutoSizeRowsMode), autoSizeRowsMode))
- throw new InvalidEnumArgumentException ("Parameter AutoSizeRowsMode is not valid DataGridViewRowsMode.");
+ throw new InvalidEnumArgumentException ("Parameter autoSizeRowsMode is not a valid DataGridViewRowsMode.");
if ((autoSizeRowsMode == DataGridViewAutoSizeRowsMode.AllHeaders || autoSizeRowsMode == DataGridViewAutoSizeRowsMode.DisplayedHeaders) && rowHeadersVisible == false)
- throw new InvalidOperationException ("Parameter AutoSizeRowsMode cant be AllHeaders or DisplayedHeaders in this DataGridView.");
+ throw new InvalidOperationException ("Parameter autoSizeRowsMode cannot be AllHeaders or DisplayedHeaders in this DataGridView.");
if (autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None)
- throw new ArgumentException ("Parameter AutoSieRowsMode cant be None.");
+ throw new ArgumentException ("Parameter autoSizeRowsMode cannot be None.");
AutoResizeRows (autoSizeRowsMode, false);
}
public virtual bool BeginEdit (bool selectAll) {
if (currentCell == null || currentCell.IsInEditMode)
return false;
-
+
if (currentCell.RowIndex >= 0) {
if ((currentCell.InheritedState & DataGridViewElementStates.ReadOnly) == DataGridViewElementStates.ReadOnly) {
return false;
DataGridViewCell cell = currentCell;
Type editType = cell.EditType;
- if (editType == null)
+
+ if (editType == null && !(cell is IDataGridViewEditingCell))
return false;
// Give user a chance to cancel the edit
if (e.Cancel)
return false;
-
- cell.SetIsInEditMode (true);
- Control ctrl = EditingControlInternal;
- bool isCorrectType = ctrl != null && ctrl.GetType () == editType;
- if (ctrl != null && !isCorrectType) {
- ctrl = null;
+
+ // If the user begins an edit in the NewRow, add a new row
+ if (CurrentCell.RowIndex == NewRowIndex) {
+ new_row_commited = false;
+ OnUserAddedRow (new DataGridViewRowEventArgs (Rows[NewRowIndex]));
}
- if (ctrl == null) {
- ctrl = (Control) Activator.CreateInstance (editType);
- EditingControlInternal = ctrl;
+
+ cell.SetIsInEditMode (true);
+
+ // The cell has an editing control we need to setup
+ if (editType != null) {
+ Control ctrl = EditingControlInternal;
+
+ // Check if we can reuse the one we already have
+ bool isCorrectType = ctrl != null && ctrl.GetType () == editType;
+
+ if (!isCorrectType)
+ ctrl = null;
+
+ // We couldn't use the existing one, create a new one
+ if (ctrl == null) {
+ ctrl = (Control) Activator.CreateInstance (editType);
+ EditingControlInternal = ctrl;
+ }
+
+ // Call some functions that allows the editing control to get setup
+ DataGridViewCellStyle style = cell.RowIndex == -1 ? DefaultCellStyle : cell.InheritedStyle;
+
+ cell.InitializeEditingControl (cell.RowIndex, cell.FormattedValue, style);
+ cell.PositionEditingControl (true, true, this.GetCellDisplayRectangle (cell.ColumnIndex, cell.RowIndex, false), bounds, style, false, false, (columns [cell.ColumnIndex].DisplayIndex == 0), (cell.RowIndex == 0));
+
+ // Show the editing control
+ EditingControlInternal.Visible = true;
+
+ IDataGridViewEditingControl dgvEditingControl = (IDataGridViewEditingControl) EditingControlInternal;
+ if (dgvEditingControl != null) {
+ dgvEditingControl.EditingControlDataGridView = this;
+ dgvEditingControl.EditingControlRowIndex = currentCell.OwningRow.Index;
+ dgvEditingControl.ApplyCellStyleToEditingControl (style);
+ dgvEditingControl.PrepareEditingControlForEdit (selectAll);
+ dgvEditingControl.EditingControlFormattedValue = currentCell.EditedFormattedValue;
+ }
+ return true;
}
- IDataGridViewEditingControl edControl = ctrl as IDataGridViewEditingControl;
- DataGridViewCellStyle style = cell.RowIndex == -1 ? DefaultCellStyle : cell.InheritedStyle;
- cell.InitializeEditingControl (cell.RowIndex, cell.FormattedValue, style);
-
- cell.PositionEditingControl (true, true, this.GetCellDisplayRectangle (cell.ColumnIndex, cell.RowIndex, false), bounds, style, false, false, (columns [cell.ColumnIndex].DisplayIndex == 0), (cell.RowIndex == 0));
- EditingControlInternal.Visible = true;
-
- if (edControl != null)
- (EditingControlInternal as IDataGridViewEditingControl).PrepareEditingControlForEdit (selectAll);
+ // If we are here, it means we have a cell that does not have an editing control
+ // and simply implements IDataGridViewEditingCell itself.
+ (cell as IDataGridViewEditingCell).PrepareEditingCellForEdit (selectAll);
return true;
}
public bool CancelEdit ()
{
if (currentCell != null && currentCell.IsInEditMode) {
+ // The user's typing caused a new row to be created, but
+ // now they are canceling that typing, we have to remove
+ // the new row we added.
+ if (!new_row_commited) {
+ DataGridViewRow delete_row = EditingRow;
+ Rows.RemoveInternal (delete_row);
+ editing_row = Rows[currentCell.RowIndex];
+ OnUserDeletedRow (new DataGridViewRowEventArgs (delete_row));
+ new_row_commited = true;
+ }
+
currentCell.SetIsInEditMode (false);
currentCell.DetachEditingControl ();
OnCellEndEdit (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
public bool CommitEdit (DataGridViewDataErrorContexts context)
{
- if (currentCell != null && currentCell.IsInEditMode) {
- IDataGridViewEditingControl ctrl = EditingControl as IDataGridViewEditingControl;
- ctrl.GetEditingControlFormattedValue (DataGridViewDataErrorContexts.Commit);
- currentCell.Value = ctrl.GetEditingControlFormattedValue (DataGridViewDataErrorContexts.Commit);
- return true;
+ if (currentCell != null && currentCell.OwningRow.DataBoundItem != null) {
+ Object ob = currentCell.OwningRow.DataBoundItem;
+ PropertyDescriptor property = TypeDescriptor.GetProperties (ob)[currentCell.OwningColumn.DataPropertyName];
+ if (property != null && !property.IsReadOnly) {
+ try {
+ object value = currentCell.Value;
+ if (property.Converter != null &&
+ property.Converter.CanConvertFrom (value.GetType()))
+ value = property.Converter.ConvertFrom (value);
+ property.SetValue (ob, value);
+ return true;
+ } catch (Exception exc) {
+ DataGridViewDataErrorEventArgs args = new DataGridViewDataErrorEventArgs (exc, currentCell.ColumnIndex,
+ currentCell.RowIndex, context);
+ InternalOnDataError (args);
+ if (args.ThrowException)
+ throw exc;
+ return false;
+ }
+ }
}
-
- return false;
+
+ return true;
}
- public int DisplayedColumnCount (bool includePartialColumns) {
- /////////////////////// PartialColumns?
+ [MonoTODO ("Always includes partial columns")]
+ public int DisplayedColumnCount (bool includePartialColumns)
+ {
int result = 0;
- foreach (DataGridViewColumn col in columns) {
- if (col.Visible) {
+
+ for (int i = first_col_index; i < Columns.Count; i++)
+ if (Columns.ColumnDisplayIndexSortedArrayList[i].Displayed)
result++;
- }
- }
+ else
+ break;
+
return result;
}
- public int DisplayedRowCount (bool includePartialRow) {
- /////////////////////// PartialRows?
+ public int DisplayedRowCount (bool includePartialRow)
+ {
int result = 0;
- foreach (DataGridViewRow row in rows) {
- if (row.Visible) {
+ int rowTop = 0;
+
+ if (ColumnHeadersVisible)
+ rowTop += ColumnHeadersHeight;
+
+ for (int index = first_row_index; index < Rows.Count; index++) {
+ DataGridViewRow row = GetRowInternal (index);
+ if (rowTop + row.Height < ClientSize.Height) {
result++;
+ rowTop += row.Height;
+ } else {
+ if (includePartialRow)
+ result++;
+ break;
}
}
+
return result;
}
public bool EndEdit ()
{
- if (currentCell != null && currentCell.IsInEditMode) {
- IDataGridViewEditingControl ctrl = EditingControl as IDataGridViewEditingControl;
- ctrl.GetEditingControlFormattedValue (DataGridViewDataErrorContexts.Commit);
- currentCell.Value = ctrl.GetEditingControlFormattedValue (DataGridViewDataErrorContexts.Commit);
-
- currentCell.SetIsInEditMode (false);
- currentCell.DetachEditingControl ();
- OnCellEndEdit (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
- }
-
- return true;
+ return EndEdit (DataGridViewDataErrorContexts.Commit);
}
[MonoTODO ("Does not use context parameter")]
public bool EndEdit (DataGridViewDataErrorContexts context)
{
- return EndEdit ();
+ if (currentCell == null || !currentCell.IsInEditMode)
+ return true;
+
+ if (EditingControl != null) {
+ IDataGridViewEditingControl ctrl = EditingControl as IDataGridViewEditingControl;
+ currentCell.Value = ctrl.GetEditingControlFormattedValue (DataGridViewDataErrorContexts.Commit);
+ if (!CommitEdit (context)) {
+ EditingControl.Focus ();
+ return false;
+ }
+ currentCell.DetachEditingControl ();
+ } else if (currentCell is IDataGridViewEditingCell) {
+ currentCell.Value = (currentCell as IDataGridViewEditingCell).EditingCellFormattedValue;
+ if (!CommitEdit (context))
+ return false;
+ }
+
+ currentCell.SetIsInEditMode (false);
+ new_row_commited = true;
+ OnCellEndEdit (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
+ Focus ();
+ return true;
}
public int GetCellCount (DataGridViewElementStates includeFilter) {
if (RowHeadersVisible)
x += RowHeadersWidth;
-
- ArrayList cols = columns.ColumnDisplayIndexSortedArrayList;
+
+ List<DataGridViewColumn> cols = columns.ColumnDisplayIndexSortedArrayList;
for (int i = first_col_index; i < cols.Count; i++) {
- if ((cols[i] as DataGridViewColumn).Index == columnIndex) {
- w = (cols[i] as DataGridViewColumn).Width;
+ if (!cols[i].Visible)
+ continue;
+
+ if (cols[i].Index == columnIndex) {
+ w = cols[i].Width;
break;
}
- x += (cols[i] as DataGridViewColumn).Width;
+ x += cols[i].Width;
}
for (int i = first_row_index; i < Rows.Count; i++) {
if (RowHeadersVisible)
x += RowHeadersWidth;
- ArrayList cols = columns.ColumnDisplayIndexSortedArrayList;
+ List<DataGridViewColumn> cols = columns.ColumnDisplayIndexSortedArrayList;
for (int i = first_col_index; i < cols.Count; i++) {
- if ((cols[i] as DataGridViewColumn).Index == columnIndex) {
- w = (cols[i] as DataGridViewColumn).Width;
+ if (!cols[i].Visible)
+ continue;
+
+ if (cols[i].Index == columnIndex) {
+ w = cols[i].Width;
break;
}
- x += (cols[i] as DataGridViewColumn).Width;
+ x += cols[i].Width;
}
return new Rectangle (x, 0, w, Height);
}
int left = rowHeadersVisible ? RowHeadersWidth : 0;
-
- ArrayList cols = columns.ColumnDisplayIndexSortedArrayList;
+
+ List<DataGridViewColumn> cols = columns.ColumnDisplayIndexSortedArrayList;
for (int i = first_col_index; i < cols.Count; i++) {
- DataGridViewColumn col = (DataGridViewColumn)cols[i];
-
- if (x > left && x <= (left + col.Width)) {
- colindex = col.Index;
+ if (!cols[i].Visible)
+ continue;
+
+ if (x > left && x <= (left + cols[i].Width)) {
+ colindex = cols[i].Index;
break;
}
-
- left += col.Width;
+
+ left += cols[i].Width;
}
if (colindex >= 0 && rowindex >= 0)
return new HitTestInfo (colindex, x, rowindex, y, DataGridViewHitTestType.Cell);
- if (isInColHeader)
+ if (isInColHeader && colindex > -1)
return new HitTestInfo (colindex, x, rowindex, y, DataGridViewHitTestType.ColumnHeader);
- if (isInRowHeader)
+ if (isInRowHeader && rowindex > -1)
return new HitTestInfo (colindex, x, rowindex, y, DataGridViewHitTestType.RowHeader);
return new HitTestInfo (-1, x, -1, y, DataGridViewHitTestType.None);
if (dataGridViewCell.DataGridView != this)
throw new ArgumentException ("The specified cell does not belong to this DataGridView.");
- Invalidate ();
+ InvalidateCell (dataGridViewCell.ColumnIndex, dataGridViewCell.RowIndex);
}
[MonoTODO ("Invalidates whole grid")]
if (rowIndex < 0 || rowIndex >= rows.Count)
throw new ArgumentOutOfRangeException ("Row index is out of range.");
- InvalidateCell (Rows[rowIndex].Cells[columnIndex]);
+ Invalidate (GetCellDisplayRectangle (columnIndex, rowIndex, true));
}
[MonoTODO ("Invalidates whole grid")]
if (columnIndex < 0 || columnIndex >= columns.Count)
throw new ArgumentOutOfRangeException ("Column index is out of range.");
- Invalidate ();
+ Invalidate (GetColumnDisplayRectangle (columnIndex, true));
}
[MonoTODO ("Invalidates whole grid")]
if (rowIndex < 0 || rowIndex >= rows.Count)
throw new ArgumentOutOfRangeException ("Row index is out of range.");
- Invalidate ();
+ Invalidate (GetRowDisplayRectangle (rowIndex, true));
}
public virtual void NotifyCurrentCellDirty (bool dirty) {
- throw new NotImplementedException();
+ if (currentCell != null)
+ InvalidateCell (currentCell);
}
public bool RefreshEdit ()
throw new ArgumentNullException ("dataGridViewColumn");
if (dataGridViewColumn.DataGridView != this)
throw new ArgumentException ("dataGridViewColumn");
- if (DataSource != null && !dataGridViewColumn.IsDataBound)
- throw new ArgumentException ("dataGridViewColumn");
- if (VirtualMode && !dataGridViewColumn.IsDataBound)
- throw new InvalidOperationException ();
+
+ if (!EndEdit ())
+ return;
if (SortedColumn != null)
SortedColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
- EndEdit ();
-
- ColumnSorter sorter = new ColumnSorter (dataGridViewColumn, direction);
- Rows.Sort (sorter);
-
sortedColumn = dataGridViewColumn;
- sortOrder = (SortOrder)direction + 1;
+ sortOrder = direction == ListSortDirection.Ascending ? SortOrder.Ascending : SortOrder.Descending;
+
+ if (Rows.Count == 0)
+ return;
- dataGridViewColumn.HeaderCell.SortGlyphDirection = (SortOrder)direction + 1;
+ IBindingList bindingList = DataSource as IBindingList;
+ if (dataGridViewColumn.IsDataBound) {
+ if (bindingList != null && bindingList.SupportsSorting) {
+ CurrencyManager currencyManager = (CurrencyManager) this.BindingContext[DataSource];
+ bindingList.ApplySort (currencyManager.GetItemProperties()[dataGridViewColumn.DataPropertyName], direction);
+ dataGridViewColumn.HeaderCell.SortGlyphDirection = sortOrder;
+ }
+ } else {
+ // Figure out if this is a numeric sort or text sort
+ bool is_numeric = true;
+ double n;
+
+ foreach (DataGridViewRow row in Rows) {
+ object val = row.Cells[dataGridViewColumn.Index].Value;
+
+ if (val != null && !double.TryParse (val.ToString (), out n)) {
+ is_numeric = false;
+ break;
+ }
+ }
+
+ ColumnSorter sorter = new ColumnSorter (dataGridViewColumn, direction, is_numeric);
+ Rows.Sort (sorter);
+ dataGridViewColumn.HeaderCell.SortGlyphDirection = sortOrder;
+ }
Invalidate ();
-
OnSorted (EventArgs.Empty);
}
public void UpdateCellErrorText (int columnIndex, int rowIndex)
{
- throw new NotImplementedException();
+ if (columnIndex < 0 || columnIndex > Columns.Count - 1)
+ throw new ArgumentOutOfRangeException ("columnIndex");
+ if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+ throw new ArgumentOutOfRangeException ("rowIndex");
+
+ InvalidateCell (columnIndex, rowIndex);
}
public void UpdateCellValue (int columnIndex, int rowIndex)
{
- throw new NotImplementedException();
+ if (columnIndex < 0 || columnIndex > Columns.Count - 1)
+ throw new ArgumentOutOfRangeException ("columnIndex");
+ if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+ throw new ArgumentOutOfRangeException ("rowIndex");
+
+ InvalidateCell (columnIndex, rowIndex);
}
public void UpdateRowErrorText (int rowIndex)
{
- throw new NotImplementedException();
+ if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+ throw new ArgumentOutOfRangeException ("rowIndex");
+
+ InvalidateRow (rowIndex);
}
- public void UpdateRowErrorText (int rowIndexStart, int rowIndexEnd) {
- throw new NotImplementedException();
+ public void UpdateRowErrorText (int rowIndexStart, int rowIndexEnd)
+ {
+ if (rowIndexStart < 0 || rowIndexStart > Rows.Count - 1)
+ throw new ArgumentOutOfRangeException ("rowIndexStart");
+ if (rowIndexEnd < 0 || rowIndexEnd > Rows.Count - 1)
+ throw new ArgumentOutOfRangeException ("rowIndexEnd");
+ if (rowIndexEnd < rowIndexStart)
+ throw new ArgumentOutOfRangeException ("rowIndexEnd", "rowIndexEnd must be greater than rowIndexStart");
+
+ for (int i = rowIndexStart; i <= rowIndexEnd; i++)
+ InvalidateRow (i);
}
public void UpdateRowHeightInfo (int rowIndex, bool updateToEnd) {
throw new NotImplementedException();
}
+ protected override bool CanEnableIme {
+ get {
+ if (CurrentCell != null && CurrentCell.EditType != null)
+ return true;
+
+ return false;
+ }
+ }
+
protected override Size DefaultSize {
get { return new Size (240, 150); }
}
[MonoTODO ("Does not use fixedWidth parameter")]
protected void AutoResizeRow (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth)
{
- AutoResizeRow (rowIndex, autoSizeRowMode);
+ if (autoSizeRowMode == DataGridViewAutoSizeRowMode.RowHeader && !rowHeadersVisible)
+ throw new InvalidOperationException ("row headers are not visible");
+ if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+ throw new ArgumentOutOfRangeException ("rowIndex");
+
+ DataGridViewRow row = GetRowInternal (rowIndex);
+
+ int new_height = row.GetPreferredHeight (rowIndex, autoSizeRowMode, true);
+
+ if (row.Height != new_height)
+ row.SetAutoSizeHeight (new_height);
}
[MonoTODO ("Does not use fixedColumnHeadersHeight or fixedRowsHeight parameter")]
AutoResizeRowHeadersWidth (rowHeadersWidthSizeMode);
}
- [MonoTODO ("Does not use fixedMode parameter")]
+ [MonoTODO ("Does not use fixedWidth parameter")]
protected void AutoResizeRows (DataGridViewAutoSizeRowsMode autoSizeRowsMode, bool fixedWidth)
{
if (autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None)
return;
- bool include_headers = false;
- bool include_cells = false;
bool displayed_only = false;
-
+ DataGridViewAutoSizeRowMode mode = DataGridViewAutoSizeRowMode.AllCells;
+
switch (autoSizeRowsMode) {
case DataGridViewAutoSizeRowsMode.AllHeaders:
- include_headers = true;
+ mode = DataGridViewAutoSizeRowMode.RowHeader;
break;
case DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders:
- include_cells = true;
+ mode = DataGridViewAutoSizeRowMode.AllCellsExceptHeader;
break;
case DataGridViewAutoSizeRowsMode.AllCells:
- include_cells = true;
- include_headers = true;
+ mode = DataGridViewAutoSizeRowMode.AllCells;
break;
case DataGridViewAutoSizeRowsMode.DisplayedHeaders:
- include_headers = true;
+ mode = DataGridViewAutoSizeRowMode.RowHeader;
displayed_only = true;
break;
case DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders:
- include_cells = true;
+ mode = DataGridViewAutoSizeRowMode.AllCellsExceptHeader;
displayed_only = true;
break;
case DataGridViewAutoSizeRowsMode.DisplayedCells:
- include_cells = true;
- include_headers = true;
+ mode = DataGridViewAutoSizeRowMode.AllCells;
displayed_only = true;
break;
}
foreach (DataGridViewRow row in Rows) {
- int new_height = 0;
-
- if (include_headers)
- if (!displayed_only || row.HeaderCell.Displayed)
- new_height = Math.Max (new_height, row.HeaderCell.PreferredSize.Height);
-
- if (include_cells)
- foreach (DataGridViewCell cell in row.Cells)
- if (!displayed_only || cell.Displayed)
- new_height = Math.Max (new_height, cell.PreferredSize.Height);
-
- if (row.Height != new_height)
- row.Height = new_height;
+ if (!displayed_only || row.Displayed) {
+ int new_height = row.GetPreferredHeight (row.Index, mode, fixedWidth);
+
+ if (row.Height != new_height)
+ row.SetAutoSizeHeight (new_height);
+ }
}
}
eh (this, e);
}
- protected virtual void OnAutoSizeColumnModeChanged (DataGridViewAutoSizeColumnModeEventArgs e)
+ protected internal virtual void OnAutoSizeColumnModeChanged (DataGridViewAutoSizeColumnModeEventArgs e)
{
DataGridViewAutoSizeColumnModeEventHandler eh = (DataGridViewAutoSizeColumnModeEventHandler)(Events [AutoSizeColumnModeChangedEvent]);
if (eh != null)
eh (this, e);
}
+ internal void OnCellStateChangedInternal (DataGridViewCellStateChangedEventArgs e) {
+ this.OnCellStateChanged (e);
+ }
+
protected virtual void OnCellStateChanged (DataGridViewCellStateChangedEventArgs e)
{
DataGridViewCellStateChangedEventHandler eh = (DataGridViewCellStateChangedEventHandler)(Events [CellStateChangedEvent]);
eh (this, e);
}
- protected virtual void OnCellValueNeeded (DataGridViewCellValueEventArgs e)
+ protected internal virtual void OnCellValueNeeded (DataGridViewCellValueEventArgs e)
{
DataGridViewCellValueEventHandler eh = (DataGridViewCellValueEventHandler)(Events [CellValueNeededEvent]);
if (eh != null)
internal void OnColumnAddedInternal (DataGridViewColumnEventArgs e)
{
+ if (e.Column.CellTemplate != null) {
+ foreach (DataGridViewRow row in Rows)
+ row.Cells.Add ((DataGridViewCell)e.Column.CellTemplate.Clone ());
+ }
+
AutoResizeColumnsInternal ();
OnColumnAdded (e);
PrepareEditingRow (false, true);
eh (this, e);
}
+ internal void OnColumnRemovedInternal (DataGridViewColumnEventArgs e)
+ {
+ if (e.Column.CellTemplate != null) {
+ int index = e.Column.Index;
+
+ foreach (DataGridViewRow row in Rows)
+ row.Cells.RemoveAt (index);
+ }
+
+ AutoResizeColumnsInternal ();
+ OnColumnRemoved (e);
+ PrepareEditingRow (false, true);
+ }
+
protected virtual void OnColumnRemoved (DataGridViewColumnEventArgs e)
{
DataGridViewColumnEventHandler eh = (DataGridViewColumnEventHandler)(Events [ColumnRemovedEvent]);
{
base.OnHandleCreated(e);
- if (Rows.Count > 0 && Columns.Count > 0)
- MoveCurrentCell (ColumnDisplayIndexToIndex (0), 0, true, false, false);
+ if (CurrentCell == null && Rows.Count > 0 && Columns.Count > 0)
+ MoveCurrentCell (ColumnDisplayIndexToIndex (0), 0, true, false, false, false);
}
protected override void OnHandleDestroyed(EventArgs e)
horizontalScrollBar.Bounds = new Rectangle (BorderWidth, Height - BorderWidth - horizontalScrollBar.Height, Width - (2 * BorderWidth), horizontalScrollBar.Height);
else if (verticalScrollBar.Visible)
verticalScrollBar.Bounds = new Rectangle (Width - BorderWidth - verticalScrollBar.Width, BorderWidth, verticalScrollBar.Width, Height - (2 * BorderWidth));
-
+
+ AutoResizeColumnsInternal ();
Invalidate ();
}
protected override void OnMouseClick (MouseEventArgs e)
{
base.OnMouseClick(e);
+
+ if (column_resize_active || row_resize_active)
+ return;
+
//Console.WriteLine("Mouse: Clicks: {0}; Delta: {1}; X: {2}; Y: {3};", e.Clicks, e.Delta, e.X, e.Y);
HitTestInfo hit = HitTest (e.X, e.Y);
DataGridViewCell cell = GetCellInternal (hit.ColumnIndex, hit.RowIndex);
- if (cell.GetContentBounds (hit.RowIndex).Contains (cellpoint))
- cell.OnContentClickInternal (new DataGridViewCellEventArgs (hit.ColumnIndex, hit.RowIndex));
+ if (cell.GetContentBounds (hit.RowIndex).Contains (cellpoint)) {
+ DataGridViewCellEventArgs dgvcea = new DataGridViewCellEventArgs (hit.ColumnIndex, hit.RowIndex);
+ OnCellContentClick (dgvcea);
+ }
break;
case DataGridViewHitTestType.ColumnHeader:
{
base.OnMouseDown(e);
+ if (!EndEdit ())
+ return;
+
HitTestInfo hitTest = HitTest(e.X, e.Y);
DataGridViewCell cell = null;
DataGridViewRow row = null;
Rectangle cellBounds;
+ if (hitTest.Type == DataGridViewHitTestType.ColumnHeader && MouseOverColumnResize (hitTest.ColumnIndex, e.X)) {
+ if (e.Clicks == 2) {
+ AutoResizeColumn (hitTest.ColumnIndex);
+ return;
+ }
+
+ resize_band = hitTest.ColumnIndex;
+ column_resize_active = true;
+ resize_band_start = e.X;
+ resize_band_delta = 0;
+ DrawVerticalResizeLine (resize_band_start);
+ return;
+ }
+
+ if (hitTest.Type == DataGridViewHitTestType.RowHeader && MouseOverRowResize (hitTest.RowIndex, e.Y)) {
+ if (e.Clicks == 2) {
+ AutoResizeRow (hitTest.RowIndex);
+ return;
+ }
+
+ resize_band = hitTest.RowIndex;
+ row_resize_active = true;
+ resize_band_start = e.Y;
+ resize_band_delta = 0;
+ DrawHorizontalResizeLine (resize_band_start);
+ return;
+ }
+
if (hitTest.Type == DataGridViewHitTestType.Cell) {
+ row = rows [hitTest.RowIndex];
+ cell = row.Cells [hitTest.ColumnIndex];
+ SetCurrentCellAddressCore (cell.ColumnIndex, cell.RowIndex, false, true, true);
cellBounds = GetCellDisplayRectangle (hitTest.ColumnIndex, hitTest.RowIndex, false);
OnCellMouseDown (new DataGridViewCellMouseEventArgs (hitTest.ColumnIndex, hitTest.RowIndex, e.X - cellBounds.X, e.Y - cellBounds.Y, e));
OnCellClick (new DataGridViewCellEventArgs (hitTest.ColumnIndex, hitTest.RowIndex));
- row = rows [hitTest.RowIndex];
- cell = row.Cells [hitTest.ColumnIndex];
}
DoSelectionOnMouseDown (hitTest);
if (hitTest.Type != DataGridViewHitTestType.Cell) {
+ if (hitTest.Type == DataGridViewHitTestType.ColumnHeader)
+ pressed_header_cell = columns [hitTest.ColumnIndex].HeaderCell;
+ else if (hitTest.Type == DataGridViewHitTestType.RowHeader)
+ pressed_header_cell = rows [hitTest.RowIndex].HeaderCell;
Invalidate ();
return;
}
- if (cell == currentCell) {
- BeginEdit (true);
- } else if (currentCell != null) {
- EndEdit ();
- OnCellLeave(new DataGridViewCellEventArgs(currentCell.ColumnIndex, currentCell.RowIndex));
- }
- currentCell = cell;
- currentCellAddress = new Point (currentCell.ColumnIndex, currentCell.RowIndex);
- currentRow = cell.OwningRow;
- OnCurrentCellChanged(EventArgs.Empty);
- OnCellEnter(new DataGridViewCellEventArgs(cell.ColumnIndex, cell.RowIndex));
- if (editMode == DataGridViewEditMode.EditOnEnter) {
- BeginEdit (true);
- }
Invalidate();
return;
}
+ private void UpdateBindingPosition (int position)
+ {
+ if (DataSource != null && BindingContext != null) {
+ CurrencyManager currencyManager = this.BindingContext[DataSource] as CurrencyManager;
+ if (currencyManager != null)
+ currencyManager.Position = position;
+ }
+ }
+
protected override void OnMouseEnter (EventArgs e)
{
base.OnMouseEnter(e);
OnCellMouseLeave (new DataGridViewCellEventArgs (hover_cell.ColumnIndex, hover_cell.RowIndex));
hover_cell = null;
}
+
+ EnteredHeaderCell = null;
}
protected override void OnMouseMove (MouseEventArgs e)
{
base.OnMouseMove (e);
-
+
+ if (column_resize_active) {
+ // Erase the old line
+ DrawVerticalResizeLine (resize_band_start + resize_band_delta);
+
+ resize_band_delta = e.X - resize_band_start;
+
+ // Draw the new line
+ DrawVerticalResizeLine (resize_band_start + resize_band_delta);
+ return;
+ }
+
+ if (row_resize_active) {
+ // Erase the old line
+ DrawHorizontalResizeLine (resize_band_start + resize_band_delta);
+
+ resize_band_delta = e.Y - resize_band_start;
+
+ // Draw the new line
+ DrawHorizontalResizeLine (resize_band_start + resize_band_delta);
+ return;
+ }
+
+ Cursor new_cursor = Cursors.Default;
HitTestInfo hit = this.HitTest (e.X, e.Y);
if (hit.Type == DataGridViewHitTestType.Cell) {
+ EnteredHeaderCell = null;
+
DataGridViewCell new_cell = GetCellInternal (hit.ColumnIndex, hit.RowIndex);
+ // Check if we have moved into an error icon area
+ Rectangle icon = new_cell.ErrorIconBounds;
+
+ if (!icon.IsEmpty) {
+ Point loc = GetCellDisplayRectangle (hit.ColumnIndex, hit.RowIndex, false).Location;
+
+ icon.X += loc.X;
+ icon.Y += loc.Y;
+
+ if (icon.Contains (e.X, e.Y)) {
+ if (tooltip_currently_showing != new_cell)
+ MouseEnteredErrorIcon (new_cell);
+ } else
+ MouseLeftErrorIcon (new_cell);
+ }
+
// We have never been in a cell before
if (hover_cell == null) {
hover_cell = new_cell;
OnCellMouseMove (new DataGridViewCellMouseEventArgs (hit.ColumnIndex, hit.RowIndex, e.X - display2.X, e.Y - display2.Y, e));
return;
+ } else if (hit.Type == DataGridViewHitTestType.RowHeader) {
+ DataGridViewRowHeaderCell new_cell = Rows[hit.RowIndex].HeaderCell;
+
+ EnteredHeaderCell = new_cell;
+
+ if (MouseOverRowResize (hit.RowIndex, e.Y))
+ new_cursor = Cursors.HSplit;
+
+ // Check if we have moved into an error icon area
+ Rectangle icon = new_cell.InternalErrorIconsBounds;
+
+ if (!icon.IsEmpty) {
+ Point loc = GetCellDisplayRectangle (0, hit.RowIndex, false).Location;
+
+ icon.X += BorderWidth;
+ icon.Y += loc.Y;
+
+ if (icon.Contains (e.X, e.Y)) {
+ if (tooltip_currently_showing != new_cell)
+ MouseEnteredErrorIcon (new_cell);
+ } else
+ MouseLeftErrorIcon (new_cell);
+ }
+ } else if (hit.Type == DataGridViewHitTestType.TopLeftHeader) {
+ EnteredHeaderCell = null;
+
+ DataGridViewTopLeftHeaderCell new_cell = (DataGridViewTopLeftHeaderCell)TopLeftHeaderCell;
+
+ // Check if we have moved into an error icon area
+ Rectangle icon = new_cell.InternalErrorIconsBounds;
+
+ if (!icon.IsEmpty) {
+ Point loc = Point.Empty;
+
+ icon.X += BorderWidth;
+ icon.Y += loc.Y;
+
+ if (icon.Contains (e.X, e.Y)) {
+ if (tooltip_currently_showing != new_cell)
+ MouseEnteredErrorIcon (new_cell);
+ } else
+ MouseLeftErrorIcon (new_cell);
+ }
+
} else {
+ if (hit.Type == DataGridViewHitTestType.ColumnHeader) {
+ EnteredHeaderCell = Columns [hit.ColumnIndex].HeaderCell;
+
+ if (MouseOverColumnResize (hit.ColumnIndex, e.X))
+ new_cursor = Cursors.VSplit;
+ } else
+ EnteredHeaderCell = null;
+
// We have left the cell area
if (hover_cell != null) {
OnCellMouseLeave (new DataGridViewCellEventArgs (hover_cell.ColumnIndex, hover_cell.RowIndex));
hover_cell = null;
}
}
+
+ Cursor = new_cursor;
}
protected override void OnMouseUp (MouseEventArgs e)
{
base.OnMouseUp(e);
+ if (column_resize_active) {
+ column_resize_active = false;
+
+ if (resize_band_delta + Columns[resize_band].Width < 0)
+ resize_band_delta = -Columns[resize_band].Width;
+
+ Columns[resize_band].Width = Math.Max (resize_band_delta + Columns[resize_band].Width, Columns[resize_band].MinimumWidth);
+ Invalidate ();
+ return;
+ }
+
+ if (row_resize_active) {
+ row_resize_active = false;
+
+ if (resize_band_delta + Rows[resize_band].Height < 0)
+ resize_band_delta = -Rows[resize_band].Height;
+
+ Rows[resize_band].Height = Math.Max (resize_band_delta + Rows[resize_band].Height, Rows[resize_band].MinimumHeight);
+ Invalidate ();
+ return;
+ }
+
HitTestInfo hit = this.HitTest (e.X, e.Y);
if (hit.Type == DataGridViewHitTestType.Cell) {
Rectangle display = GetCellDisplayRectangle (hit.ColumnIndex, hit.RowIndex, false);
OnCellMouseUp (new DataGridViewCellMouseEventArgs (hit.ColumnIndex, hit.RowIndex, e.X - display.X, e.Y - display.Y, e));
}
+
+ if (pressed_header_cell != null) {
+ DataGridViewHeaderCell cell = pressed_header_cell;
+ pressed_header_cell = null;
+ if (ThemeEngine.Current.DataGridViewHeaderCellHasPressedStyle (this))
+ Invalidate (GetHeaderCellBounds (cell));
+ }
}
protected override void OnMouseWheel (MouseEventArgs e)
// Paint the background
PaintBackground (g, e.ClipRectangle, bounds);
-
- ArrayList sortedColumns = columns.ColumnDisplayIndexSortedArrayList;
+
+ List<DataGridViewColumn> sortedColumns = columns.ColumnDisplayIndexSortedArrayList;
// Take borders into account
bounds.Inflate (-BorderWidth, -BorderWidth);
// Paint the top left cell
- if (rowHeadersVisible && columnHeadersVisible) {
+ if (rowHeadersVisible && columnHeadersVisible && ColumnCount > 0) {
Rectangle topleftbounds = new Rectangle (bounds.X, bounds.Y, rowHeadersWidth, columnHeadersHeight);
TopLeftHeaderCell.PaintWork (g, e.ClipRectangle, topleftbounds, -1, TopLeftHeaderCell.State, ColumnHeadersDefaultCellStyle, AdvancedColumnHeadersBorderStyle, DataGridViewPaintParts.All);
headerBounds.X += rowHeadersWidth;
for (int index = first_col_index; index < sortedColumns.Count; index++) {
- DataGridViewColumn col = (DataGridViewColumn)sortedColumns[index];
+ DataGridViewColumn col = sortedColumns[index];
+
+ if (!col.Visible)
+ continue;
headerBounds.Width = col.Width;
DataGridViewCell cell = col.HeaderCell;
DataGridViewAdvancedBorderStyle intermediateBorderStyle = (DataGridViewAdvancedBorderStyle)((ICloneable)this.AdvancedColumnHeadersBorderStyle).Clone ();
DataGridViewAdvancedBorderStyle borderStyle = AdjustColumnHeaderBorderStyle (this.AdvancedColumnHeadersBorderStyle, intermediateBorderStyle, cell.ColumnIndex == 0, cell.ColumnIndex == columns.Count - 1);
- cell.PaintWork (g, e.ClipRectangle, headerBounds, -1, cell.State, columnHeadersDefaultCellStyle, borderStyle, DataGridViewPaintParts.All);
+ cell.PaintWork (g, e.ClipRectangle, headerBounds, -1, cell.State, cell.InheritedStyle, borderStyle, DataGridViewPaintParts.All);
headerBounds.X += col.Width;
}
bounds.Y += columnHeadersHeight;
}
- gridWidth = 0;
+ gridWidth = rowHeadersVisible ? rowHeadersWidth : 0;
gridHeight = 0;
- int rows_displayed = 0;
- int first_row_height = Rows.Count > 0 ? Rows[first_row_index].Height : 0;
+ int first_row_height = Rows.Count > 0 ? Rows[Math.Min (Rows.Count - 1, first_row_index)].Height : 0;
+// int room_left = this.Height;
+
+ // Reset all columns to !Displayed
+ for (int i = 0; i < Columns.Count; i++)
+ Columns[i].DisplayedInternal = false;
+
+ // Set Displayed columns
+ for (int i = first_col_index; i < Columns.Count; i++) {
+ DataGridViewColumn col = Columns.ColumnDisplayIndexSortedArrayList[i];
+
+ if (!col.Visible)
+ continue;
+
+ col.DisplayedInternal = true;
+ gridWidth += col.Width;
+
+ if (gridWidth >= Width)
+ break;
+ }
+
+ // Reset all rows to !Displayed
+ for (int i = 0; i < Rows.Count; i++)
+ GetRowInternal (i).DisplayedInternal = false;
// Draw rows
for (int index = first_row_index; index < Rows.Count; index++) {
DataGridViewRow row = Rows[index];
-
+ GetRowInternal (index).DisplayedInternal = true;
+
bounds.Height = row.Height;
bool is_first = row.Index == 0;
bool is_last = row.Index == rows.Count - 1;
- row.Paint (g, e.ClipRectangle, bounds, index, row.GetState (row.Index), is_first, is_last);
+ row.Paint (g, e.ClipRectangle, bounds, row.Index, row.GetState (row.Index), is_first, is_last);
bounds.Y += bounds.Height;
bounds.X = BorderWidth;
- if (gridHeight + columnHeadersHeight <= ClientSize.Height)
- rows_displayed++;
- else
+ if (bounds.Y >= ClientSize.Height - (horizontalScrollBar.Visible ? horizontalScrollBar.Height : 0))
break;
gridHeight += row.Height;
}
+
+ gridWidth = 0;
foreach (DataGridViewColumn col in sortedColumns)
- gridWidth += col.Width;
+ if (col.Visible)
+ gridWidth += col.Width;
gridHeight = 0;
foreach (DataGridViewRow row in Rows)
gridHeight += row.Height;
- if (rowHeadersVisible) {
+ if (rowHeadersVisible)
gridWidth += rowHeadersWidth;
- }
- if (columnHeadersVisible) {
+
+ if (columnHeadersVisible)
gridHeight += columnHeadersHeight;
- }
bool horizontalVisible = false;
bool verticalVisible = false;
if (eh != null) eh (this, e);
}
- protected internal virtual void OnRowsRemoved (DataGridViewRowsRemovedEventArgs e)
+ internal void OnRowsRemovedInternal (DataGridViewRowsRemovedEventArgs e)
+ {
+ if (selected_rows != null)
+ selected_rows.InternalClear ();
+ if (selected_columns != null)
+ selected_columns.InternalClear ();
+
+ if (Rows.Count > 0 && Columns.Count > 0 && currentCell != null &&
+ currentCell.RowIndex >= e.RowIndex)
+ MoveCurrentCell (0, Math.Min (e.RowIndex, Rows.Count - 2), true, false, false, true);
+ Invalidate ();
+ OnRowsRemoved (e);
+ }
+
+ protected virtual void OnRowsRemoved (DataGridViewRowsRemovedEventArgs e)
{
DataGridViewRowsRemovedEventHandler eh = (DataGridViewRowsRemovedEventHandler)(Events [RowsRemovedEvent]);
if (eh != null) eh (this, e);
protected virtual void OnUserAddedRow (DataGridViewRowEventArgs e)
{
+ editing_row = null;
+ PrepareEditingRow (false, false);
+
+ e = new DataGridViewRowEventArgs (editing_row);
+
DataGridViewRowEventHandler eh = (DataGridViewRowEventHandler)(Events [UserAddedRowEvent]);
if (eh != null) eh (this, e);
}
protected virtual bool ProcessDataGridViewKey (KeyEventArgs e)
{
- switch (e.KeyData) {
+ switch (e.KeyData & ~Keys.Modifiers) {
case Keys.A:
return ProcessAKey (e.KeyData);
case Keys.Delete:
return ProcessHomeKey (e.KeyData);
case Keys.Left:
return ProcessLeftKey (e.KeyData);
+ case Keys.Next:
+ return ProcessNextKey (e.KeyData);
+ case Keys.Prior:
+ return ProcessPriorKey (e.KeyData);
case Keys.Right:
return ProcessRightKey (e.KeyData);
case Keys.Space:
return ProcessSpaceKey (e.KeyData);
case Keys.Tab:
- case Keys.Shift | Keys.Tab:
- case Keys.Control | Keys.Tab:
- case Keys.Control | Keys.Shift | Keys.Tab:
return ProcessTabKey (e.KeyData);
case Keys.Up:
return ProcessUpKey (e.KeyData);
return false;
}
- [MonoTODO ("What does delete do?")]
protected bool ProcessDeleteKey (Keys keyData)
{
- return false;
+ if (!allowUserToDeleteRows || SelectedRows.Count == 0)
+ return false;
+
+ int index = Math.Max (selected_row - SelectedRows.Count + 1, 0);
+
+ for (int i = SelectedRows.Count - 1; i >= 0; i--) {
+ DataGridViewRow row = SelectedRows[i];
+
+ if (row.IsNewRow)
+ continue;
+
+ if (hover_cell != null && hover_cell.OwningRow == row)
+ hover_cell = null;
+
+ if (DataSource != null && DataSource is DataSet)
+ (DataSource as DataSet).Tables[dataMember].Rows.RemoveAt (row.Index);
+ else
+ Rows.RemoveAt (row.Index);
+ }
+
+ return true;
}
protected override bool ProcessDialogKey (Keys keyData)
if (ProcessDataGridViewKey (new KeyEventArgs (keyData)))
return true;
+ break;
+ case Keys.Enter:
+ case Keys.Escape:
+ if (ProcessDataGridViewKey (new KeyEventArgs (keyData)))
+ return true;
+
break;
}
int current_row = CurrentCellAddress.Y;
if (current_row < Rows.Count - 1) {
- EndEdit ();
-
// Move to the last cell in the column
if ((keyData & Keys.Control) == Keys.Control)
- MoveCurrentCell (CurrentCellAddress.X, Rows.Count - 1, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (CurrentCellAddress.X, Rows.Count - 1, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
// Move one cell down
else
- MoveCurrentCell (CurrentCellAddress.X, current_row + 1, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (CurrentCellAddress.X, current_row + 1, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
return true;
}
// Move to the last cell in the control
if ((keyData & Keys.Control) == Keys.Control) {
- MoveCurrentCell (ColumnDisplayIndexToIndex (Columns.Count - 1), Rows.Count - 1, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (ColumnDisplayIndexToIndex (Columns.Count - 1), Rows.Count - 1, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
return true;
}
// Move to the last cell in the row
if (disp_index < Columns.Count - 1) {
- MoveCurrentCell (ColumnDisplayIndexToIndex (Columns.Count - 1), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (ColumnDisplayIndexToIndex (Columns.Count - 1), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
return true;
}
protected bool ProcessEnterKey (Keys keyData)
{
- if (!IsCurrentCellInEditMode)
- return false;
-
- CommitEdit (DataGridViewDataErrorContexts.Commit);
-
- // Move one cell down
- if ((keyData & Keys.Control) == 0) {
- int current_row = CurrentCellAddress.Y;
-
- if (current_row < Rows.Count - 1)
- MoveCurrentCell (CurrentCellAddress.X, current_row + 1, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
- }
+ if (ProcessDownKey (keyData))
+ return true;
+ // ProcessDown may fail if we are on the last row,
+ // but Enter should still EndEdit if this is the last row
+ EndEdit ();
return true;
}
// Move to the first cell in the control
if ((keyData & Keys.Control) == Keys.Control) {
- MoveCurrentCell (ColumnDisplayIndexToIndex (0), 0, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (ColumnDisplayIndexToIndex (0), 0, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
return true;
}
// Move to the first cell in the row
if (disp_index > 0) {
- MoveCurrentCell (ColumnDisplayIndexToIndex (0), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (ColumnDisplayIndexToIndex (0), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
return true;
}
protected override bool ProcessKeyPreview (ref Message m)
{
- if ((Msg)m.Msg == Msg.WM_KEYDOWN && IsCurrentCellInEditMode) {
+ if ((Msg)m.Msg == Msg.WM_KEYDOWN && (IsCurrentCellInEditMode || m.HWnd == horizontalScrollBar.Handle || m.HWnd == verticalScrollBar.Handle)) {
KeyEventArgs e = new KeyEventArgs ((Keys)m.WParam.ToInt32 ());
IDataGridViewEditingControl ctrl = (IDataGridViewEditingControl)EditingControlInternal;
if (ctrl.EditingControlWantsInputKey (e.KeyData, false))
return false;
- switch (e.KeyData)
- {
+ switch (e.KeyData) {
case Keys.Escape:
case Keys.Down:
case Keys.Up:
case Keys.Left:
case Keys.Right:
case Keys.Tab:
+ case Keys.Prior:
+ case Keys.Next:
return ProcessDataGridViewKey (e);
}
}
- return base.ProcessKeyPreview(ref m);
+
+ return base.ProcessKeyPreview (ref m);
}
protected bool ProcessLeftKey (Keys keyData)
int disp_index = ColumnIndexToDisplayIndex (currentCellAddress.X);
if (disp_index > 0) {
- EndEdit ();
-
// Move to the first cell in the row
if ((keyData & Keys.Control) == Keys.Control)
- MoveCurrentCell (ColumnDisplayIndexToIndex (0), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (ColumnDisplayIndexToIndex (0), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
// Move one cell to the left
else
- MoveCurrentCell (ColumnDisplayIndexToIndex (disp_index - 1), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (ColumnDisplayIndexToIndex (disp_index - 1), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
return true;
}
return false;
}
- protected bool ProcessNextKey (Keys keyData) {
- // PAGE DOWN
- throw new NotImplementedException();
+ // Page Down
+ protected bool ProcessNextKey (Keys keyData)
+ {
+ int current_row = CurrentCellAddress.Y;
+
+ if (current_row < Rows.Count - 1) {
+ // Move one "page" of cells down
+ int new_row = Math.Min (Rows.Count - 1, current_row + DisplayedRowCount (false));
+
+ MoveCurrentCell (CurrentCellAddress.X, new_row, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
+
+ return true;
+ }
+
+ return false;
}
- protected bool ProcessPriorKey (Keys keyData) {
- // PAGE UP
- throw new NotImplementedException();
+ // Page Up
+ protected bool ProcessPriorKey (Keys keyData)
+ {
+ int current_row = CurrentCellAddress.Y;
+
+ if (current_row > 0) {
+ // Move one "page" of cells up
+ int new_row = Math.Max (0, current_row - DisplayedRowCount (false));
+
+ MoveCurrentCell (CurrentCellAddress.X, new_row, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
+
+ return true;
+ }
+
+ return false;
}
protected bool ProcessRightKey (Keys keyData)
int disp_index = ColumnIndexToDisplayIndex (currentCellAddress.X);
if (disp_index < Columns.Count - 1) {
- EndEdit ();
-
// Move to the last cell in the row
if ((keyData & Keys.Control) == Keys.Control)
- MoveCurrentCell (ColumnDisplayIndexToIndex (Columns.Count - 1), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (ColumnDisplayIndexToIndex (Columns.Count - 1), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
// Move one cell to the right
else
- MoveCurrentCell (ColumnDisplayIndexToIndex (disp_index + 1), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (ColumnDisplayIndexToIndex (disp_index + 1), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
return true;
}
protected bool ProcessTabKey (Keys keyData)
{
- EndEdit ();
-
Form f = FindForm ();
if (f != null)
if ((keyData & Keys.Shift) == Keys.Shift) {
if (disp_index > 0) {
// Move one cell to the left
- MoveCurrentCell (ColumnDisplayIndexToIndex (disp_index - 1), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (ColumnDisplayIndexToIndex (disp_index - 1), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, false, true);
return true;
} else if (currentCellAddress.Y > 0) {
// Move to the last cell in the previous row
- MoveCurrentCell (ColumnDisplayIndexToIndex (Columns.Count - 1), currentCellAddress.Y - 1, true, false, false);
+ MoveCurrentCell (ColumnDisplayIndexToIndex (Columns.Count - 1), currentCellAddress.Y - 1, true, false, false, true);
return true;
}
} else {
if (disp_index < Columns.Count - 1) {
-
// Move one cell to the right
- MoveCurrentCell (ColumnDisplayIndexToIndex (disp_index + 1), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (ColumnDisplayIndexToIndex (disp_index + 1), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, false, true);
return true;
} else if (currentCellAddress.Y < Rows.Count - 1) {
// Move to the first cell in the next row
- MoveCurrentCell (ColumnDisplayIndexToIndex (0), currentCellAddress.Y + 1, true, false, false);
+ MoveCurrentCell (ColumnDisplayIndexToIndex (0), currentCellAddress.Y + 1, true, false, false, true);
return true;
}
int current_row = CurrentCellAddress.Y;
if (current_row > 0) {
- EndEdit ();
-
// Move to the first cell in the column
if ((keyData & Keys.Control) == Keys.Control)
- MoveCurrentCell (CurrentCellAddress.X, 0, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (CurrentCellAddress.X, 0, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
// Move one cell up
else
- MoveCurrentCell (CurrentCellAddress.X, current_row - 1, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift);
+ MoveCurrentCell (CurrentCellAddress.X, current_row - 1, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
return true;
}
base.SetBoundsCore(x, y, width, height, specified);
}
- [MonoTODO ("Does not use validateCurrentCell or throughMouseClick")]
+ [MonoTODO ("Does not use validateCurrentCell")]
protected virtual bool SetCurrentCellAddressCore (int columnIndex, int rowIndex, bool setAnchorCellAddress, bool validateCurrentCell, bool throughMouseClick)
{
if ((columnIndex < 0 || columnIndex > Columns.Count - 1) && rowIndex != -1)
if (cell != null && !cell.Visible)
throw new InvalidOperationException ("cell is not visible");
- if (setAnchorCellAddress)
- anchor_cell = new Point (columnIndex, rowIndex);
+ if (cell != currentCell) {
+ if (currentCell != null) {
+ if (currentCell.IsInEditMode && !EndEdit ())
+ return false;
+ OnCellLeave (new DataGridViewCellEventArgs(currentCell.ColumnIndex, currentCell.RowIndex));
+ OnRowLeave (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
+ }
+
+ currentCell = cell;
+ if (setAnchorCellAddress)
+ anchor_cell = new Point (columnIndex, rowIndex);
+ currentCellAddress = new Point (columnIndex, rowIndex);
+
+ UpdateBindingPosition (currentCell.RowIndex);
+ OnRowEnter (new DataGridViewCellEventArgs (cell.ColumnIndex, cell.RowIndex));
+ OnCellEnter (new DataGridViewCellEventArgs(cell.ColumnIndex, cell.RowIndex));
+ OnCurrentCellChanged (EventArgs.Empty);
+ if (throughMouseClick || editMode == DataGridViewEditMode.EditOnEnter)
+ BeginEdit (true);
+ } else {
+ if (throughMouseClick)
+ BeginEdit (true);
+ }
- currentCellAddress = new Point (columnIndex, rowIndex);
- CurrentCell = cell;
-
- OnCurrentCellChanged (EventArgs.Empty);
-
return true;
}
protected virtual void SetSelectedCellCore (int columnIndex, int rowIndex, bool selected) {
rows [rowIndex].Cells [columnIndex].Selected = selected;
+
+ OnSelectionChanged (EventArgs.Empty);
}
internal void SetSelectedColumnCoreInternal (int columnIndex, bool selected) {
} else if (selected && !selected_columns.Contains (col)) {
selected_columns.InternalAdd (col);
}
+
+ Invalidate();
}
internal void SetSelectedRowCoreInternal (int rowIndex, bool selected) {
} else if (selected && !selected_rows.Contains (row)) {
selected_rows.InternalAdd (row);
}
+
+ Invalidate();
}
protected override void WndProc (ref Message m)
internal void InternalOnCellValueChanged (DataGridViewCellEventArgs e)
{
OnCellValueChanged (e);
-
- if (editing_row != null && e.RowIndex == editing_row.Index)
- PrepareEditingRow (true, false);
}
internal void InternalOnDataError (DataGridViewDataErrorEventArgs e)
internal void OnVScrollBarScroll (object sender, ScrollEventArgs e)
{
verticalScrollingOffset = e.NewValue;
+ if (Rows.Count == 0)
+ return;
+
int top = 0;
for (int index = 0; index < Rows.Count; index++) {
DataGridViewRow row = Rows[index];
-
if (e.NewValue < top + row.Height) {
if (first_row_index != index) {
first_row_index = index;
top += row.Height;
}
+
+ first_row_index = Rows.Count - DisplayedRowCount (false);
+ Invalidate ();
+ OnScroll (e);
}
internal void RaiseCellStyleChanged (DataGridViewCellEventArgs e) {
internal void OnColumnCollectionChanged (object sender, CollectionChangeEventArgs e) {
switch (e.Action) {
case CollectionChangeAction.Add:
- OnColumnAdded(new DataGridViewColumnEventArgs(e.Element as DataGridViewColumn));
+ OnColumnAddedInternal(new DataGridViewColumnEventArgs(e.Element as DataGridViewColumn));
break;
case CollectionChangeAction.Remove:
- OnColumnRemoved(new DataGridViewColumnEventArgs(e.Element as DataGridViewColumn));
+ OnColumnRemovedInternal(new DataGridViewColumnEventArgs(e.Element as DataGridViewColumn));
break;
case CollectionChangeAction.Refresh:
break;
{
float totalFillWeight = 0;
int FillCount = 0; // The number of columns that has AutoSizeMode.Fill set
- int spaceLeft = ClientSize.Width;
+ int spaceLeft = ClientSize.Width - (verticalScrollBar.VisibleInternal ? verticalScrollBar.Width : 0);
if (RowHeadersVisible) {
spaceLeft -= RowHeadersWidth;
case DataGridViewAutoSizeColumnMode.AllCells:
case DataGridViewAutoSizeColumnMode.DisplayedCells:
case DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader:
- size = CalculateColumnCellWidth (columnIndex, col.InheritedAutoSizeMode);
+ size = Math.Max (CalculateColumnCellWidth (columnIndex, col.InheritedAutoSizeMode),
+ col.HeaderCell.ContentBounds.Width);
break;
case DataGridViewAutoSizeColumnMode.ColumnHeader:
size = col.HeaderCell.ContentBounds.Width;
continue;
}
- Rectangle cell_rect = GetCellDisplayRectangle (index, i, false);
-
- result = Math.Max (result, cell_rect.Width);
+ int cell_width = Rows[i].Cells[index].PreferredSize.Width;
+
+ result = Math.Max (result, cell_width);
}
return result;
}
- private void PrepareEditingRow (bool cell_changed, bool column_changed)
+ Rectangle GetHeaderCellBounds (DataGridViewHeaderCell cell)
+ {
+ Rectangle bounds = new Rectangle (ClientRectangle.Location, cell.Size);
+ if (cell is DataGridViewColumnHeaderCell) {
+ if (RowHeadersVisible)
+ bounds.X += RowHeadersWidth;
+ List<DataGridViewColumn> sortedColumns = columns.ColumnDisplayIndexSortedArrayList;
+ for (int index = first_col_index; index < sortedColumns.Count; index++) {
+ DataGridViewColumn column = sortedColumns [index];
+ if (column.Index == cell.ColumnIndex)
+ break;
+ bounds.X += column.Width;
+ }
+ } else {
+ if (ColumnHeadersVisible)
+ bounds.Y += ColumnHeadersHeight;
+ for (int index = first_row_index; index < Rows.Count; index++) {
+ DataGridViewRow row = GetRowInternal (index);
+ if (row.HeaderCell == cell)
+ break;
+ bounds.Y += row.Height;
+ }
+ }
+ return bounds;
+ }
+
+ internal void PrepareEditingRow (bool cell_changed, bool column_changed)
{
bool show = false;
show = ColumnCount > 0 && AllowUserToAddRows;
if (!show && editing_row != null) {
- Rows.Remove (editing_row);
+ Rows.RemoveInternal (editing_row);
editing_row = null;
} else if (show) {
if (editing_row != null) {
editing_row = null;
} else if (column_changed) {
// The number of columns has changed, we need a new editing row.
- Rows.Remove (editing_row);
+ Rows.RemoveInternal (editing_row);
editing_row = null;
}
}
}
private void BindIList (IList list) {
- if (list is DataView) {
- DataView dataView = (DataView) list;
- DataTable table = dataView.Table;
- DataGridViewCell template = new DataGridViewTextBoxCell();
- foreach (DataColumn dataColumn in table.Columns) {
- DataGridViewColumn col = new DataGridViewColumn(template);
- col.Name = dataColumn.ColumnName;
- col.ValueType = dataColumn.DataType;
- columns.Add(col);
+ if (autoGenerateColumns) {
+ // Stuff from a DataSet
+ if (list is DataView) {
+ DataView dataView = (DataView) list;
+ DataTable table = dataView.Table;
+
+ foreach (DataColumn dataColumn in table.Columns) {
+ DataGridViewColumn col = CreateColumnByType (dataColumn.DataType);
+
+ col.Name = dataColumn.ColumnName;
+ col.DataPropertyName = dataColumn.ColumnName;
+ col.SetIsDataBound (true);
+ col.ValueType = dataColumn.DataType;
+ col.AutoGenerated = true;
+
+ columns.Add (col);
+ }
}
- dataView.ListChanged += OnListChanged;
- }
- else if (list.Count > 0) {
- DataGridViewCell template = new DataGridViewTextBoxCell();
- foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(list[0])) {
- DataGridViewColumn col = new DataGridViewColumn(template);
- col.Name = property.DisplayName;
- col.ReadOnly = property.IsReadOnly;
- columns.Add(col);
+ // Its a generic something or other, like a BindingList<T>, so
+ // we can figure out the type from the generic type
+ else if (list.GetType ().GetGenericArguments ().Length > 0) {
+ GenerateColumnsFromType (list.GetType ().GetGenericArguments ()[0]);
+ }
+ // Its a normal array/collection type thing
+ else if (list.GetType ().IsArray) {
+ GenerateColumnsFromType (list.GetType ().GetElementType ());
+ } else if (list is BindingSource && (list as BindingSource).item_type != null) {
+ foreach (PropertyDescriptor property in TypeDescriptor.GetProperties ((list as BindingSource).item_type)) {
+ DataGridViewColumn col = CreateColumnByType (property.PropertyType);
+ col.Name = property.DisplayName;
+ col.ReadOnly = property.IsReadOnly;
+ col.AutoGenerated = true;
+ columns.Add (col);
+ }
+
+ AllowUserToAddRows = (list as BindingSource).AllowNew;
}
}
- foreach (object element in list) {
- DataGridViewRow row = (DataGridViewRow)RowTemplate.Clone ();
- rows.InternalAdd(row);
- PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(element);
- foreach (PropertyDescriptor property in properties) {
- DataGridViewTextBoxCell cell = new DataGridViewTextBoxCell();
- cell.Value = property.GetValue(element);
- cell.ValueType = property.PropertyType;
- row.Cells.Add(cell);
+
+ // Subscribe to the dataset's change notification
+ if (list is DataView) {
+ (list as DataView).ListChanged += OnListChanged;
+ (list as DataView).Table.ColumnChanged += OnTableColumnChanged;
+ (list as DataView).Table.TableCleared += OnTableCleared;
+ }
+
+ // Add the rows
+ foreach (object element in list)
+ AddBoundRow (element);
+ }
+
+ private void OnBindingSourceDataSourceChanged (object sender, EventArgs args)
+ {
+ ClearBinding();
+ DoBinding();
+ }
+
+ private void AddBoundRow (object element)
+ {
+ // Don't add rows if there are no columns
+ if (ColumnCount == 0)
+ return;
+
+ DataGridViewRow row = (DataGridViewRow)RowTemplateFull;
+ rows.InternalAdd (row);
+
+ PropertyDescriptorCollection properties = TypeDescriptor.GetProperties (element);
+
+ foreach (PropertyDescriptor property in properties) {
+ if (property.PropertyType == typeof (IBindingList))
+ continue;
+
+ // We do it this way because there may not be a column
+ // for every cell, ignore cells with no column
+ DataGridViewCell cell = row.Cells.GetBoundCell (property.Name);
+
+ if (cell == null)
+ continue;
+
+ cell.valuex = property.GetValue (element);
+ cell.valueType = property.PropertyType;
+ }
+ }
+
+ private void GenerateColumnsFromType (Type type)
+ {
+ foreach (PropertyDescriptor property in TypeDescriptor.GetProperties (type)) {
+ // This keeps out things like arrays
+ if ((typeof(ICollection).IsAssignableFrom (property.PropertyType)))
+ continue;
+
+ DataGridViewColumn col = CreateColumnByType (property.PropertyType);
+ col.Name = property.DisplayName;
+ col.DataPropertyName = property.DisplayName;
+ col.ReadOnly = property.IsReadOnly;
+ col.SetIsDataBound (true);
+ col.ValueType = property.PropertyType;
+ col.AutoGenerated = true;
+ columns.Add (col);
+ }
+ }
+
+ private DataGridViewColumn CreateColumnByType (Type type)
+ {
+ if (type == typeof (bool))
+ return new DataGridViewCheckBoxColumn ();
+
+ return new DataGridViewTextBoxColumn ();
+ }
+
+ private void ClearBinding ()
+ {
+ columns.ClearAutoGeneratedColumns ();
+ rows.Clear ();
+ PrepareEditingRow (false, true);
+
+ if (dataSource != null) {
+ if (dataSource is DataSet) {
+ (dataSource as DataSet).Tables.CollectionChanged -= OnDataSetTableChanged;
+
+ DataTable dt = (dataSource as DataSet).Tables[dataMember];
+
+ if (dt != null) {
+ DataView dv = dt.DefaultView;
+
+ if (dv != null) {
+ (dv as DataView).Table.ColumnChanged -= OnTableColumnChanged;
+ (dv as DataView).ListChanged -= OnListChanged;
+ }
+ }
+ } else if (dataSource is DataView) {
+ (dataSource as DataView).ListChanged -= OnListChanged;
+ (dataSource as DataView).Table.ColumnChanged -= OnTableColumnChanged;
+ } else if (dataSource is DataTable)
+ ((dataSource as IListSource).GetList () as DataView).ListChanged -= OnListChanged;
+
+ if (dataSource is IBindingList)
+ (dataSource as IBindingList).ListChanged -= OnListChanged;
+ if (dataSource is BindingSource)
+ (dataSource as BindingSource).DataSourceChanged -= OnBindingSourceDataSourceChanged;
+ }
+ }
+
+ private void DoBinding ()
+ {
+ /* The System.Windows.Forms.DataGridView class supports the standard Windows Forms data-binding model. This means the data source can be of any type that implements:
+ - the System.Collections.IList interface, including one-dimensional arrays.
+ - the System.ComponentModel.IListSource interface, such as the System.Data.DataTable and System.Data.DataSet classes.
+ - the System.ComponentModel.IBindingList interface, such as the System.ComponentModel.Collections.BindingList<> class.
+ - the System.ComponentModel.IBindingListView interface, such as the System.Windows.Forms.BindingSource class.
+ */
+
+ if (dataSource != null) {
+ object value = dataSource;
+
+ // DataBinding
+ if (value is DataSet && string.IsNullOrEmpty (dataMember)) {
+ Invalidate ();
+ return;
+ }
+ if (value is DataSet) {
+ (value as DataSet).Tables.CollectionChanged += OnDataSetTableChanged;
+ value = (value as DataSet).Tables[dataMember];
}
+
+ if (value is BindingSource)
+ BindBindingSource (value as BindingSource);
+ else if (value is IBindingListView)
+ BindIBindingListView (value as IBindingListView);
+ else if (value is IBindingList)
+ BindIBindingList (value as IBindingList);
+ else if (value is IList)
+ BindIList (value as IList);
+ else if (value is IListSource)
+ BindIListSource (value as IListSource);
+
+ OnDataBindingComplete (new DataGridViewBindingCompleteEventArgs (ListChangedType.Reset));
}
+
+ if (Rows.Count > 0 && Columns.Count > 0)
+ MoveCurrentCell (0, 0, true, false, false, false);
+ PerformLayout();
+ Invalidate ();
+ }
+
+ private void BindBindingSource (BindingSource bindingSource)
+ {
+ BindIList (bindingSource.List);
+ bindingSource.ListChanged += OnBindingSourceDataSourceChanged;
+ bindingSource.DataSourceChanged += OnBindingSourceDataSourceChanged;
}
private void BindIListSource (IListSource list) {
- BindIList(list.GetList());
+ BindIList (list.GetList());
}
private void BindIBindingList (IBindingList list) {
- BindIList(list);
+ BindIList (list);
+ list.ListChanged += OnListChanged;
}
private void BindIBindingListView (IBindingListView list) {
BindIList(list);
}
- private void MoveCurrentCell (int x, int y, bool select, bool isControl, bool isShift)
+ private void MoveCurrentCell (int x, int y, bool select, bool isControl, bool isShift, bool scroll)
{
+ if (!SetCurrentCellAddressCore (x, y, true, false, false))
+ return;
+
bool full_row_selected = Rows.SharedRow(CurrentCellAddress.Y).Selected;
bool full_col_selected = Columns[CurrentCellAddress.X].Selected;
else if (mode == DataGridViewSelectionMode.ColumnHeaderSelect)
mode = DataGridViewSelectionMode.CellSelect;
- // Move CurrentCell
- SetCurrentCellAddressCore (x, y, true, false, false);
+ // If the current cell isn't visible, scroll to it
+ if (scroll) {
+ int disp_x = ColumnIndexToDisplayIndex (x);
+
+ if (disp_x < first_col_index) {
+ int delta_x = 0;
+
+ if (disp_x == 0)
+ delta_x = horizontalScrollBar.Value;
+ else
+ for (int i = disp_x; i < first_col_index; i++)
+ delta_x += Columns[ColumnDisplayIndexToIndex (i)].Width;
+
+ horizontalScrollBar.SafeValueSet (horizontalScrollBar.Value - delta_x);
+ OnHScrollBarScroll (this, new ScrollEventArgs (ScrollEventType.ThumbPosition, horizontalScrollBar.Value));
+ }
+
+ int disp_y = y;
+ int displayedRowsCount = DisplayedRowCount (false);
+ int delta_y = 0;
+
+ if (disp_y < first_row_index) {
+ if (disp_y == 0)
+ delta_y = verticalScrollBar.Value;
+ else
+ for (int i = disp_y; i < first_row_index; i++)
+ delta_y += GetRowInternal (i).Height;
+
+ verticalScrollBar.SafeValueSet (verticalScrollBar.Value - delta_y);
+ OnVScrollBarScroll (this, new ScrollEventArgs (ScrollEventType.ThumbPosition, verticalScrollBar.Value));
+ } else if (disp_y > first_row_index + displayedRowsCount - 1) {
+ if (disp_y == Rows.Count - 1)
+ delta_y = verticalScrollBar.Maximum - verticalScrollBar.Value;
+ else
+ for (int i = first_row_index + displayedRowsCount - 1; i < disp_y; i++)
+ delta_y += GetRowInternal (i).Height;
+
+ verticalScrollBar.SafeValueSet (verticalScrollBar.Value + delta_y);
+ OnVScrollBarScroll (this, new ScrollEventArgs (ScrollEventType.ThumbPosition, verticalScrollBar.Value));
+ }
+ }
if (!select)
return;
private int ColumnDisplayIndexToIndex (int index)
{
- return ((Columns.ColumnDisplayIndexSortedArrayList[index]) as DataGridViewColumn).Index;
+ return Columns.ColumnDisplayIndexSortedArrayList[index].Index;
}
- private void OnListChanged (object sender, ListChangedEventArgs args) {
- if (args.OldIndex >= 0) {
+ private void OnListChanged (object sender, ListChangedEventArgs args)
+ {
+ switch (args.ListChangedType) {
+ case ListChangedType.ItemAdded:
+ AddBoundRow ((sender as IBindingList)[args.NewIndex]);
+ break;
+ case ListChangedType.ItemDeleted:
+ Rows.RemoveAt (args.NewIndex);
+ break;
+ default:
+ ClearBinding ();
+ DoBinding ();
+ break;
}
- if (args.NewIndex >= 0) {
- object element = (sender as DataView)[args.NewIndex];
- DataGridViewRow row = new DataGridViewRow();
- rows.InternalAdd(row);
- PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(element);
- foreach (PropertyDescriptor property in properties) {
- DataGridViewTextBoxCell cell = new DataGridViewTextBoxCell();
- cell.Value = property.GetValue(element);
- cell.ValueType = property.PropertyType;
- row.Cells.Add(cell);
+
+ Invalidate ();
+ }
+
+ private void OnTableColumnChanged (object sender, DataColumnChangeEventArgs e)
+ {
+ ClearBinding ();
+ DoBinding ();
+ }
+
+ private void OnDataSetTableChanged (object sender, CollectionChangeEventArgs e)
+ {
+ ClearBinding ();
+ DoBinding ();
+ }
+
+ private void OnTableCleared (object sender, DataTableClearEventArgs e)
+ {
+ ClearBinding ();
+ DoBinding ();
+ }
+
+ private bool MouseOverColumnResize (int col, int mousex)
+ {
+ if (!allowUserToResizeColumns)
+ return false;
+
+ Rectangle col_bounds = GetCellDisplayRectangle (col, 0, false);
+
+ if (mousex >= col_bounds.Right - 4 && mousex <= col_bounds.Right)
+ return true;
+
+ return false;
+ }
+
+ private bool MouseOverRowResize (int row, int mousey)
+ {
+ if (!allowUserToResizeRows)
+ return false;
+
+ Rectangle row_bounds = GetCellDisplayRectangle (0, row, false);
+
+ if (mousey >= row_bounds.Bottom - 4 && mousey <= row_bounds.Bottom)
+ return true;
+
+ return false;
+ }
+
+ private void DrawVerticalResizeLine (int x)
+ {
+ Rectangle splitter = new Rectangle (x, Bounds.Y + 3 + (ColumnHeadersVisible ? ColumnHeadersHeight : 0), 1, Bounds.Height - 3 - (ColumnHeadersVisible ? ColumnHeadersHeight : 0));
+ XplatUI.DrawReversibleRectangle (Handle, splitter, 2);
+ }
+
+ private void DrawHorizontalResizeLine (int y)
+ {
+ Rectangle splitter = new Rectangle (Bounds.X + 3 + (RowHeadersVisible ? RowHeadersWidth : 0), y, Bounds.Width - 3 + (RowHeadersVisible ? RowHeadersWidth : 0), 1);
+ XplatUI.DrawReversibleRectangle (Handle, splitter, 2);
+ }
+
+ #region Stuff for ToolTips
+ private void MouseEnteredErrorIcon (DataGridViewCell item)
+ {
+ tooltip_currently_showing = item;
+ ToolTipTimer.Start ();
+ }
+
+ private void MouseLeftErrorIcon (DataGridViewCell item)
+ {
+ ToolTipTimer.Stop ();
+ ToolTipWindow.Hide (this);
+ tooltip_currently_showing = null;
+ }
+
+ private Timer ToolTipTimer {
+ get {
+ if (tooltip_timer == null) {
+ tooltip_timer = new Timer ();
+ tooltip_timer.Enabled = false;
+ tooltip_timer.Interval = 500;
+ tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
}
- Invalidate();
+
+ return tooltip_timer;
+ }
+ }
+
+ private ToolTip ToolTipWindow {
+ get {
+ if (tooltip_window == null)
+ tooltip_window = new ToolTip ();
+
+ return tooltip_window;
}
}
+ private void ToolTipTimer_Tick (object o, EventArgs args)
+ {
+ string tooltip = tooltip_currently_showing.ErrorText;
+
+ if (!string.IsNullOrEmpty (tooltip))
+ ToolTipWindow.Present (this, tooltip);
+
+ ToolTipTimer.Stop ();
+ }
+ #endregion
+
private class ColumnSorter : IComparer
{
int column;
int direction = 1;
-
- public ColumnSorter (DataGridViewColumn column, ListSortDirection direction)
+ bool numeric_sort;
+
+ public ColumnSorter (DataGridViewColumn column, ListSortDirection direction, bool numeric)
{
this.column = column.Index;
-
+ this.numeric_sort = numeric;
+
if (direction == ListSortDirection.Descending)
this.direction = -1;
}
DataGridViewRow row1 = (DataGridViewRow)x;
DataGridViewRow row2 = (DataGridViewRow)y;
+ if (row1.Cells[column].ValueType == typeof (DateTime) && row2.Cells[column].ValueType == typeof (DateTime))
+ return DateTime.Compare ((DateTime)row1.Cells[column].valuex, (DateTime)row2.Cells[column].valuex) * direction;
+
object val1 = row1.Cells[column].FormattedValue;
object val2 = row2.Cells[column].FormattedValue;
if (val2 == null)
return -1 * direction;
- return string.Compare (val1.ToString (), val2.ToString ()) * direction;
+ if (numeric_sort)
+ return (int)(double.Parse (val1.ToString ()) - double.Parse (val2.ToString ())) * direction;
+ else
+ return string.Compare (val1.ToString (), val2.ToString ()) * direction;
}
#endregion
}
[ComVisible (false)]
public class DataGridViewControlCollection : Control.ControlCollection
{
- private new DataGridView owner;
+ private DataGridView owner;
public DataGridViewControlCollection (DataGridView owner) : base (owner)
{