X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FManaged.Windows.Forms%2FSystem.Windows.Forms%2FDataGridView.cs;h=ffc8bd7c59bb40ab80fcce63b852beef786d78b8;hb=27894abb99e01e79bb967bb04498b0883f535d00;hp=438e268f67f60633c8c52d20c4a47877984a82d8;hpb=9d003f271ebece614ae801a8c1f309cf3a9b3fe9;p=mono.git diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridView.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridView.cs index 438e268f67f..ffc8bd7c59b 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridView.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridView.cs @@ -21,6 +21,7 @@ // // Author: // Pedro Martínez Juliá +// Ivan N. Zlatev // #if NET_2_0 @@ -117,8 +118,9 @@ namespace System.Windows.Forms { private HScrollBar horizontalScrollBar; private VScrollBar verticalScrollBar; private Control editingControl; - private bool new_row_commited = true; private bool is_autogenerating_columns = false; + private bool is_binding = false; + private bool new_row_editing = false; // These are used to implement selection behaviour with SHIFT pressed. private int selected_row = -1; @@ -133,9 +135,6 @@ namespace System.Windows.Forms { private DataGridViewSelectedColumnCollection selected_columns; private DataGridViewRow editing_row; - private int gridWidth; - private int gridHeight; - DataGridViewHeaderCell pressed_header_cell; DataGridViewHeaderCell entered_header_cell; @@ -188,6 +187,7 @@ namespace System.Windows.Forms { columnHeadersVisible = true; columns = CreateColumnsInstance(); columns.CollectionChanged += OnColumnCollectionChanged; + currentCellAddress = new Point (-1, -1); dataMember = String.Empty; defaultCellStyle = new DataGridViewCellStyle(); defaultCellStyle.BackColor = SystemColors.Window; @@ -212,6 +212,7 @@ namespace System.Windows.Forms { selectionMode = DataGridViewSelectionMode.RowHeaderSelect; showCellErrors = true; showEditingIcon = true; + scrollBars = ScrollBars.Both; userSetCursor = Cursor.Current; virtualMode = false; @@ -263,12 +264,22 @@ namespace System.Windows.Forms { [DefaultValue (true)] public bool AllowUserToAddRows { - get { return allowUserToAddRows; } + get { + if (allowUserToAddRows && DataManager != null) + return DataManager.AllowNew; + return allowUserToAddRows; + } set { if (allowUserToAddRows != value) { allowUserToAddRows = value; + if (!value) { + if (new_row_editing) + CancelEdit (); + RemoveEditingRow (); + } else { + PrepareEditingRow (false, false); + } OnAllowUserToAddRowsChanged(EventArgs.Empty); - PrepareEditingRow (false, false); Invalidate (); } } @@ -276,7 +287,11 @@ namespace System.Windows.Forms { [DefaultValue (true)] public bool AllowUserToDeleteRows { - get { return allowUserToDeleteRows; } + get { + if (allowUserToDeleteRows && DataManager != null) + return DataManager.AllowRemove; + return allowUserToDeleteRows; + } set { if (allowUserToDeleteRows != value) { allowUserToDeleteRows = value; @@ -567,12 +582,12 @@ namespace System.Windows.Forms { throw new InvalidOperationException("Cant change column count if DataSource is set."); } if (value < columns.Count) { - for (int i = value; i < columns.Count; i++) { + for (int i = columns.Count -1; i >= value; i--) { columns.RemoveAt(i); } } else if (value > columns.Count) { - for (int i = 0; i < value; i++) { + for (int i = columns.Count; i < value; i++) { DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn (); columns.Add(col); } @@ -669,13 +684,12 @@ namespace System.Windows.Forms { /// to the data cache, or the new cell is in a hidden /// row. ///////////////////////////////////////////////////// - if (value.DataGridView != this) + if (value == null) + MoveCurrentCell (-1, -1, true, false, false, true); + else if (value.DataGridView != this) throw new ArgumentException("The cell is not in this DataGridView."); - - if (value != null) - MoveCurrentCell (value.OwningColumn.Index, value.OwningRow.Index, true, false, false, true); else - MoveCurrentCell (-1, -1, true, false, false, true); + MoveCurrentCell (value.OwningColumn.Index, value.OwningRow.Index, true, false, false, true); } } @@ -699,12 +713,10 @@ namespace System.Windows.Forms { get { return dataMember; } set { if (dataMember != value) { - ClearBinding (); - dataMember = value; + if (BindingContext != null) + ReBind (); OnDataMemberChanged(EventArgs.Empty); - - DoBinding (); } } } @@ -725,11 +737,22 @@ namespace System.Windows.Forms { throw new NotSupportedException ("Type cannot be bound."); ClearBinding (); - dataSource = value; + if (BindingContext != null) + ReBind (); OnDataSourceChanged (EventArgs.Empty); - - DoBinding (); + } + } + + internal CurrencyManager DataManager { + get { + if (DataSource != null && BindingContext != null) { + string dataMember = DataMember; + if (dataMember == null) + dataMember = String.Empty; + return (CurrencyManager) this.BindingContext[DataSource, dataMember]; + } + return null; } } @@ -940,7 +963,7 @@ namespace System.Windows.Forms { [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public int NewRowIndex { get { - if (!allowUserToAddRows || ColumnCount == 0) { + if (!AllowUserToAddRows || ColumnCount == 0) { return -1; } return rows.Count - 1; @@ -981,18 +1004,25 @@ namespace System.Windows.Forms { if (value < 0) { throw new ArgumentException("RowCount must be >= 0."); } - if (value < 1 && allowUserToAddRows) { + if (value < 1 && AllowUserToAddRows) { throw new ArgumentException("RowCount must be >= 1 if AllowUserToAddRows is true."); } if (dataSource != null) { throw new InvalidOperationException("Cant change row count if DataSource is set."); } + if (value < rows.Count) { - for (int i = value; i < rows.Count; i++) { + int removeRangeEndIndex = rows.Count - 1; + if (AllowUserToAddRows) + removeRangeEndIndex--; // do not remove editing row + + int removeRangeStartIndex = value - 1; + if (AllowUserToAddRows) + removeRangeStartIndex--; // remove an extra row before/instead of the editing row + + for (int i = removeRangeEndIndex; i > removeRangeStartIndex; i--) rows.RemoveAt(i); - } - } - else if (value > rows.Count) { + } else if (value > rows.Count) { // If we need to add rows and don't have any columns, // we create one column if (ColumnCount == 0) @@ -1149,6 +1179,8 @@ namespace System.Windows.Forms { /// or canceled. /////////////////////////////////////////////////////////// scrollBars = value; + PerformLayout (); + Invalidate (); } } @@ -1273,8 +1305,16 @@ namespace System.Windows.Forms { return topLeftHeaderCell; } set { + if (topLeftHeaderCell == value) + return; + + if (topLeftHeaderCell != null) + topLeftHeaderCell.SetDataGridView (null); + topLeftHeaderCell = value; - topLeftHeaderCell.SetDataGridView (this); + + if (topLeftHeaderCell != null) + topLeftHeaderCell.SetDataGridView (this); } } @@ -2239,7 +2279,7 @@ namespace System.Windows.Forms { return false; } } - + DataGridViewCell cell = currentCell; Type editType = cell.EditType; @@ -2253,12 +2293,6 @@ namespace System.Windows.Forms { if (e.Cancel) return false; - // 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])); - } - cell.SetIsInEditMode (true); // The cell has an editing control we need to setup @@ -2284,7 +2318,8 @@ namespace System.Windows.Forms { 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; + if (EditingControlInternal != null) + EditingControlInternal.Visible = true; IDataGridViewEditingControl dgvEditingControl = (IDataGridViewEditingControl) EditingControlInternal; if (dgvEditingControl != null) { @@ -2306,21 +2341,21 @@ namespace System.Windows.Forms { 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; + if (currentCell != null) { + if (currentCell.IsInEditMode) { + currentCell.SetIsInEditMode (false); + currentCell.DetachEditingControl (); } - currentCell.SetIsInEditMode (false); - currentCell.DetachEditingControl (); - OnCellEndEdit (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex)); + if (currentCell.RowIndex == NewRowIndex) { + if (DataManager != null) + DataManager.CancelCurrentEdit (); + + new_row_editing = false; + PrepareEditingRow (false, false); + MoveCurrentCell (currentCell.ColumnIndex, NewRowIndex, true, false, false, true); + OnUserDeletedRow (new DataGridViewRowEventArgs (EditingRow)); + } } return true; @@ -2338,28 +2373,20 @@ namespace System.Windows.Forms { public bool CommitEdit (DataGridViewDataErrorContexts context) { - 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; - } - } - } + if (currentCell == null) + return true; + try { + currentCell.Value = currentCell.ParseFormattedValue (currentCell.EditedFormattedValue, + currentCell.InheritedStyle, null, null); + } catch (Exception e) { + DataGridViewDataErrorEventArgs args = new DataGridViewDataErrorEventArgs (e, currentCell.ColumnIndex, currentCell.RowIndex, + DataGridViewDataErrorContexts.Commit); + OnDataError (false, args); + if (args.ThrowException) + throw e; + return false; + } return true; } @@ -2385,9 +2412,15 @@ namespace System.Windows.Forms { if (ColumnHeadersVisible) rowTop += ColumnHeadersHeight; + Size visibleClientArea = ClientSize; + if (verticalScrollBar.Visible) + visibleClientArea.Width -= verticalScrollBar.Width; + if (horizontalScrollBar.Visible) + visibleClientArea.Height -= horizontalScrollBar.Height; + for (int index = first_row_index; index < Rows.Count; index++) { DataGridViewRow row = GetRowInternal (index); - if (rowTop + row.Height < ClientSize.Height) { + if (rowTop + row.Height <= visibleClientArea.Height) { result++; rowTop += row.Height; } else { @@ -2411,24 +2444,24 @@ namespace System.Windows.Forms { if (currentCell == null || !currentCell.IsInEditMode) return true; - if (EditingControl != null) { - IDataGridViewEditingControl ctrl = EditingControl as IDataGridViewEditingControl; - currentCell.Value = ctrl.GetEditingControlFormattedValue (DataGridViewDataErrorContexts.Commit); - if (!CommitEdit (context)) { + if (!CommitEdit (context)) { + if (DataManager != null) + DataManager.EndCurrentEdit (); + if (EditingControl != null) EditingControl.Focus (); - return false; - } - currentCell.DetachEditingControl (); - } else if (currentCell is IDataGridViewEditingCell) { - currentCell.Value = (currentCell as IDataGridViewEditingCell).EditingCellFormattedValue; - if (!CommitEdit (context)) - return false; + return false; } currentCell.SetIsInEditMode (false); - new_row_commited = true; + currentCell.DetachEditingControl (); OnCellEndEdit (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex)); Focus (); + if (currentCell.RowIndex == NewRowIndex) { + new_row_editing = false; + editing_row = null; // editing row becomes a real row + PrepareEditingRow (true, false); // add a new editing row + MoveCurrentCell (currentCell.ColumnIndex, NewRowIndex, true, false, false, true); + } return true; } @@ -2485,7 +2518,10 @@ namespace System.Windows.Forms { } for (int i = first_row_index; i < Rows.Count; i++) { - if (i == rowIndex) { + if (!rows[i].Visible) + continue; + + if (rows[i].Index == rowIndex) { h = rows [i].Height; break; } @@ -2745,13 +2781,17 @@ namespace System.Windows.Forms { if (ColumnHeadersVisible) y += ColumnHeadersHeight; + for (int i = first_row_index; i < Rows.Count; i++) { - if (i == rowIndex) { - h = rows[i].Height; + if (!rows[i].Visible) + continue; + + if (rows[i].Index == rowIndex) { + h = rows [i].Height; break; } - - y += rows[i].Height; + + y += rows [i].Height; } return new Rectangle (0, y, Width, h); @@ -2787,6 +2827,8 @@ namespace System.Windows.Forms { for (int i = first_row_index; i < Rows.Count; i++) { DataGridViewRow row = Rows[i]; + if (!row.Visible) + continue; if (y > top && y <= (top + row.Height)) { rowindex = i; @@ -2954,11 +2996,10 @@ namespace System.Windows.Forms { if (Rows.Count == 0) return; - IBindingList bindingList = DataSource as IBindingList; if (dataGridViewColumn.IsDataBound) { + IBindingList bindingList = DataManager.List as IBindingList; if (bindingList != null && bindingList.SupportsSorting) { - CurrencyManager currencyManager = (CurrencyManager) this.BindingContext[DataSource]; - bindingList.ApplySort (currencyManager.GetItemProperties()[dataGridViewColumn.DataPropertyName], direction); + bindingList.ApplySort (DataManager.GetItemProperties()[dataGridViewColumn.DataPropertyName], direction); dataGridViewColumn.HeaderCell.SortGlyphDirection = sortOrder; } } else { @@ -3141,6 +3182,8 @@ namespace System.Windows.Forms { } foreach (DataGridViewRow row in Rows) { + if (!row.Visible) + continue; if (!displayed_only || row.Displayed) { int new_height = row.GetPreferredHeight (row.Index, mode, fixedWidth); @@ -3352,6 +3395,7 @@ namespace System.Windows.Forms { protected override void OnBindingContextChanged (EventArgs e) { base.OnBindingContextChanged(e); + ReBind(); } protected virtual void OnBorderStyleChanged (EventArgs e) @@ -3447,6 +3491,9 @@ namespace System.Windows.Forms { protected virtual void OnCellEnter (DataGridViewCellEventArgs e) { + DataGridViewCell cell = GetCellInternal (e.ColumnIndex, e.RowIndex); + cell.OnEnterInternal (e.RowIndex, true); + DataGridViewCellEventHandler eh = (DataGridViewCellEventHandler)(Events [CellEnterEvent]); if (eh != null) eh (this, e); @@ -3480,6 +3527,9 @@ namespace System.Windows.Forms { protected virtual void OnCellLeave (DataGridViewCellEventArgs e) { + DataGridViewCell cell = GetCellInternal (e.ColumnIndex, e.RowIndex); + cell.OnLeaveInternal (e.RowIndex, true); + DataGridViewCellEventHandler eh = (DataGridViewCellEventHandler)(Events [CellLeaveEvent]); if (eh != null) eh (this, e); @@ -3662,7 +3712,6 @@ namespace System.Windows.Forms { // if (!is_autogenerating_columns && columns.Count == 1) ReBind (); - foreach (DataGridViewRow row in Rows) row.Cells.Add ((DataGridViewCell)e.Column.CellTemplate.Clone ()); } @@ -3799,7 +3848,22 @@ namespace System.Windows.Forms { eh (this, e); } - internal void OnColumnRemovedInternal (DataGridViewColumnEventArgs e) + internal void OnColumnPreRemovedInternal (DataGridViewColumnEventArgs e) + { + if (Columns.Count - 1 == 0) { + MoveCurrentCell (-1, -1, true, false, false, true); + rows.ClearInternal (); + } else if (currentCell != null && CurrentCell.ColumnIndex == e.Column.Index) { + int nextColumnIndex = e.Column.Index; + if (nextColumnIndex >= Columns.Count - 1) + nextColumnIndex = Columns.Count - 1 - 1; + MoveCurrentCell (nextColumnIndex, currentCell.RowIndex, true, false, false, true); + if (hover_cell != null && hover_cell.ColumnIndex >= e.Column.Index) + hover_cell = null; + } + } + + private void OnColumnPostRemovedInternal (DataGridViewColumnEventArgs e) { if (e.Column.CellTemplate != null) { int index = e.Column.Index; @@ -3809,8 +3873,9 @@ namespace System.Windows.Forms { } AutoResizeColumnsInternal (); - OnColumnRemoved (e); PrepareEditingRow (false, true); + + OnColumnRemoved (e); } protected virtual void OnColumnRemoved (DataGridViewColumnEventArgs e) @@ -3963,6 +4028,7 @@ namespace System.Windows.Forms { protected override void OnHandleCreated (EventArgs e) { base.OnHandleCreated(e); + ReBind (); if (CurrentCell == null && Rows.Count > 0 && Columns.Count > 0) MoveCurrentCell (ColumnDisplayIndexToIndex (0), 0, true, false, false, false); @@ -4058,6 +4124,11 @@ namespace System.Windows.Forms { protected override void OnMouseDoubleClick (MouseEventArgs e) { base.OnMouseDoubleClick(e); + + HitTestInfo hitInfo = HitTest (e.X, e.Y); + if (hitInfo.Type == DataGridViewHitTestType.Cell) + OnCellMouseDoubleClick (new DataGridViewCellMouseEventArgs (hitInfo.ColumnIndex, hitInfo.RowIndex, + hitInfo.ColumnX, hitInfo.RowY, e)); } private void DoSelectionOnMouseDown (HitTestInfo hitTest) @@ -4266,11 +4337,8 @@ namespace System.Windows.Forms { private void UpdateBindingPosition (int position) { - if (DataSource != null && BindingContext != null) { - CurrencyManager currencyManager = this.BindingContext[DataSource] as CurrencyManager; - if (currencyManager != null) - currencyManager.Position = position; - } + if (DataManager != null) + DataManager.Position = position; } protected override void OnMouseEnter (EventArgs e) @@ -4477,6 +4545,14 @@ namespace System.Windows.Forms { protected override void OnMouseWheel (MouseEventArgs e) { base.OnMouseWheel(e); + + int delta = SystemInformation.MouseWheelScrollLines * verticalScrollBar.SmallChange; + if (e.Delta < 0) + verticalScrollBar.SafeValueSet (verticalScrollBar.Value + delta); + else + verticalScrollBar.SafeValueSet (verticalScrollBar.Value - delta); + + OnVScrollBarScroll (this, new ScrollEventArgs (ScrollEventType.ThumbPosition, verticalScrollBar.Value)); } protected virtual void OnMultiSelectChanged (EventArgs e) @@ -4543,16 +4619,12 @@ namespace System.Windows.Forms { bounds.Y += columnHeadersHeight; } - gridWidth = rowHeadersVisible ? rowHeadersWidth : 0; - gridHeight = 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++) + // Reset not displayed columns to !Displayed + for (int i = 0; i < first_col_index; i++) Columns[i].DisplayedInternal = false; + int gridWidth = rowHeadersVisible ? rowHeadersWidth : 0; + // Set Displayed columns for (int i = first_col_index; i < Columns.Count; i++) { DataGridViewColumn col = Columns.ColumnDisplayIndexSortedArrayList[i]; @@ -4562,18 +4634,19 @@ namespace System.Windows.Forms { col.DisplayedInternal = true; gridWidth += col.Width; - if (gridWidth >= Width) break; } - // Reset all rows to !Displayed - for (int i = 0; i < Rows.Count; i++) + // Reset all not displayed rows to !Displayed + for (int i = 0; i < first_row_index; i++) GetRowInternal (i).DisplayedInternal = false; // Draw rows for (int index = first_row_index; index < Rows.Count; index++) { DataGridViewRow row = Rows[index]; + if (!row.Visible) + continue; GetRowInternal (index).DisplayedInternal = true; bounds.Height = row.Height; @@ -4587,80 +4660,92 @@ namespace System.Windows.Forms { if (bounds.Y >= ClientSize.Height - (horizontalScrollBar.Visible ? horizontalScrollBar.Height : 0)) break; - - gridHeight += row.Height; } - gridWidth = 0; + RefreshScrollBars (); + + // Paint the bottom right square if both scrollbars are displayed + if (horizontalScrollBar.Visible && verticalScrollBar.Visible) + g.FillRectangle (SystemBrushes.Control, new Rectangle (horizontalScrollBar.Right, verticalScrollBar.Bottom, verticalScrollBar.Width, horizontalScrollBar.Height)); + + // Paint the border + bounds = ClientRectangle; - foreach (DataGridViewColumn col in sortedColumns) + switch (BorderStyle) { + case BorderStyle.FixedSingle: + g.DrawRectangle (Pens.Black, new Rectangle (bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1)); + break; + case BorderStyle.Fixed3D: + ControlPaint.DrawBorder3D (g, bounds, Border3DStyle.Sunken); + break; + } + } + + private void RefreshScrollBars () + { + int gridWidth = 0; + int gridHeight = 0; + + foreach (DataGridViewColumn col in columns.ColumnDisplayIndexSortedArrayList) if (col.Visible) gridWidth += col.Width; - - gridHeight = 0; foreach (DataGridViewRow row in Rows) - gridHeight += row.Height; + if (row.Visible) + gridHeight += row.Height; if (rowHeadersVisible) gridWidth += rowHeadersWidth; - if (columnHeadersVisible) gridHeight += columnHeadersHeight; - + bool horizontalVisible = false; bool verticalVisible = false; if (AutoSize) { - if (gridWidth > Size.Width || gridHeight > Size.Height) { + if (gridWidth > Size.Width || gridHeight > Size.Height) Size = new Size(gridWidth, gridHeight); - } } else { - if (gridWidth > Size.Width) { + if (gridWidth > Size.Width) horizontalVisible = true; - } - if (gridHeight > Size.Height) { + if (gridHeight > Size.Height) verticalVisible = true; - } - if (horizontalScrollBar.Visible && (gridHeight + horizontalScrollBar.Height) > Size.Height) { + + if (horizontalScrollBar.Visible && (gridHeight + horizontalScrollBar.Height) > Size.Height) verticalVisible = true; - } - if (verticalScrollBar.Visible && (gridWidth + verticalScrollBar.Width) > Size.Width) { + if (verticalScrollBar.Visible && (gridWidth + verticalScrollBar.Width) > Size.Width) horizontalVisible = true; - } + + if (scrollBars != ScrollBars.Vertical && scrollBars != ScrollBars.Both) + verticalVisible = false; + if (scrollBars != ScrollBars.Horizontal && scrollBars != ScrollBars.Both) + horizontalVisible = false; + if (horizontalVisible) { horizontalScrollBar.Minimum = 0; horizontalScrollBar.Maximum = gridWidth; horizontalScrollBar.SmallChange = Columns[first_col_index].Width; - horizontalScrollBar.LargeChange = ClientSize.Width - rowHeadersWidth; + int largeChange = ClientSize.Width - rowHeadersWidth - horizontalScrollBar.Height; + if (largeChange <= 0) + largeChange = ClientSize.Width; + horizontalScrollBar.LargeChange = largeChange; } + if (verticalVisible) { verticalScrollBar.Minimum = 0; verticalScrollBar.Maximum = gridHeight; + int first_row_height = Rows.Count > 0 ? Rows[Math.Min (Rows.Count - 1, first_row_index)].Height : 0; verticalScrollBar.SmallChange = first_row_height + 1; - verticalScrollBar.LargeChange = ClientSize.Height - columnHeadersHeight; + int largeChange = ClientSize.Height - columnHeadersHeight - verticalScrollBar.Width; + if (largeChange <= 0) + largeChange = ClientSize.Height; + verticalScrollBar.LargeChange = largeChange; } } horizontalScrollBar.Visible = horizontalVisible; verticalScrollBar.Visible = verticalVisible; - - // Paint the bottom right square if both scrollbars are displayed - if (horizontalScrollBar.Visible && verticalScrollBar.Visible) - g.FillRectangle (SystemBrushes.Control, new Rectangle (horizontalScrollBar.Right, verticalScrollBar.Bottom, verticalScrollBar.Width, horizontalScrollBar.Height)); - - // Paint the border - bounds = ClientRectangle; - - switch (BorderStyle) { - case BorderStyle.FixedSingle: - g.DrawRectangle (Pens.Black, new Rectangle (bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1)); - break; - case BorderStyle.Fixed3D: - ControlPaint.DrawBorder3D (g, bounds, Border3DStyle.Sunken); - break; - } } protected virtual void OnReadOnlyChanged (EventArgs e) { @@ -4822,12 +4907,15 @@ namespace System.Windows.Forms { internal void OnRowsAddedInternal (DataGridViewRowsAddedEventArgs e) { + if (hover_cell != null && hover_cell.RowIndex >= e.RowIndex) + hover_cell = null; + AutoResizeColumnsInternal (); Invalidate (); OnRowsAdded (e); } - protected internal virtual void OnRowsAdded (DataGridViewRowsAddedEventArgs e) + protected virtual void OnRowsAdded (DataGridViewRowsAddedEventArgs e) { DataGridViewRowsAddedEventHandler eh = (DataGridViewRowsAddedEventHandler)(Events [RowsAddedEvent]); if (eh != null) eh (this, e); @@ -4839,16 +4927,32 @@ namespace System.Windows.Forms { if (eh != null) eh (this, e); } - internal void OnRowsRemovedInternal (DataGridViewRowsRemovedEventArgs e) + internal void OnRowsPreRemovedInternal (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); + if (Rows.Count - e.RowCount <= 0) { + MoveCurrentCell (-1, -1, true, false, false, true); + hover_cell = null; + } else if (Columns.Count == 0) { + MoveCurrentCell (-1, -1, true, false, false, true); + hover_cell = null; + } else if (currentCell != null && currentCell.RowIndex == e.RowIndex) { + int nextRowIndex = e.RowIndex; + if (nextRowIndex >= Rows.Count - e.RowCount) + nextRowIndex = Rows.Count - 1 - e.RowCount; + MoveCurrentCell (currentCell != null ? currentCell.ColumnIndex : 0, nextRowIndex, + true, false, false, true); + if (hover_cell != null && hover_cell.RowIndex >= e.RowIndex) + hover_cell = null; + } + } + + internal void OnRowsPostRemovedInternal (DataGridViewRowsRemovedEventArgs e) + { Invalidate (); OnRowsRemoved (e); } @@ -4908,11 +5012,19 @@ namespace System.Windows.Forms { protected virtual void OnUserAddedRow (DataGridViewRowEventArgs e) { - editing_row = null; PrepareEditingRow (false, false); - e = new DataGridViewRowEventArgs (editing_row); - + new_row_editing = true; + if (DataManager != null) { + // Switch the current editing row with a real one + if (editing_row != null) { + Rows.RemoveInternal (editing_row); + editing_row = null; + } + DataManager.AddNew (); // will raise OnListPositionChanged + } + + e = new DataGridViewRowEventArgs (Rows[NewRowIndex]); DataGridViewRowEventHandler eh = (DataGridViewRowEventHandler)(Events [UserAddedRowEvent]); if (eh != null) eh (this, e); } @@ -4921,7 +5033,6 @@ namespace System.Windows.Forms { { DataGridViewRowEventHandler eh = (DataGridViewRowEventHandler)(Events [UserDeletedRowEvent]); if (eh != null) eh (this, e); - } protected virtual void OnUserDeletingRow (DataGridViewRowCancelEventArgs e) @@ -5001,7 +5112,7 @@ namespace System.Windows.Forms { protected bool ProcessDeleteKey (Keys keyData) { - if (!allowUserToDeleteRows || SelectedRows.Count == 0) + if (!AllowUserToDeleteRows || SelectedRows.Count == 0) return false; int index = Math.Max (selected_row - SelectedRows.Count + 1, 0); @@ -5015,8 +5126,8 @@ namespace System.Windows.Forms { 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); + if (DataManager != null) + DataManager.RemoveAt (row.Index); else Rows.RemoveAt (row.Index); } @@ -5152,9 +5263,12 @@ namespace System.Windows.Forms { { DataGridViewCell cell = CurrentCell; - if (cell != null) + if (cell != null) { if (cell.KeyEntersEditMode (new KeyEventArgs ((Keys)m.WParam.ToInt32 ()))) BeginEdit (true); + if (EditingControl != null && ((Msg)m.Msg == Msg.WM_KEYDOWN || (Msg)m.Msg == Msg.WM_CHAR)) + XplatUI.SendMessage (EditingControl.Handle, (Msg)m.Msg, m.WParam, m.LParam); + } return base.ProcessKeyEventArgs (ref m); } @@ -5379,10 +5493,25 @@ namespace System.Windows.Forms { if (cell != null && !cell.Visible) throw new InvalidOperationException ("cell is not visible"); + // Always update the current cell address property + // If the row has moved it would be out of date. + if (currentCell != null) { + if (setAnchorCellAddress) { + anchor_cell.X = currentCell.ColumnIndex; + anchor_cell.Y = currentCell.RowIndex; + } + currentCellAddress.X = currentCell.ColumnIndex; + currentCellAddress.Y = currentCell.RowIndex; + } + if (cell != currentCell) { if (currentCell != null) { - if (currentCell.IsInEditMode && !EndEdit ()) - return false; + if (currentCell.IsInEditMode) { + if (!EndEdit ()) + return false; + else if (currentCell.RowIndex == NewRowIndex && new_row_editing) + CancelEdit (); + } OnCellLeave (new DataGridViewCellEventArgs(currentCell.ColumnIndex, currentCell.RowIndex)); OnRowLeave (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex)); } @@ -5392,14 +5521,25 @@ namespace System.Windows.Forms { 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)); + if (cell != null) { + UpdateBindingPosition (cell.RowIndex); + OnRowEnter (new DataGridViewCellEventArgs (cell.ColumnIndex, cell.RowIndex)); + OnCellEnter (new DataGridViewCellEventArgs(cell.ColumnIndex, cell.RowIndex)); + } OnCurrentCellChanged (EventArgs.Empty); - if (editMode == DataGridViewEditMode.EditOnEnter) - BeginEdit (true); + + if (cell != null) { + // If the user begins an edit in the NewRow, add a new row + if (AllowUserToAddRows && cell.RowIndex == NewRowIndex && !is_binding && !new_row_editing) { + // OnUserAddedRow will add a real row and reset the current cell + OnUserAddedRow (new DataGridViewRowEventArgs (Rows[NewRowIndex])); + } else { + if (editMode == DataGridViewEditMode.EditOnEnter) + BeginEdit (true); + } + } } else { - if (throughMouseClick) + if (cell != null && throughMouseClick) BeginEdit (true); } @@ -5437,7 +5577,8 @@ namespace System.Windows.Forms { } internal void SetSelectedRowCoreInternal (int rowIndex, bool selected) { - SetSelectedRowCore (rowIndex, selected); + if (rowIndex >= 0 && rowIndex < Rows.Count) + SetSelectedRowCore (rowIndex, selected); } protected virtual void SetSelectedRowCore (int rowIndex, bool selected) { @@ -5522,10 +5663,16 @@ namespace System.Windows.Forms { return; int top = 0; - + int lastTopVisibleRowIndex = Rows.Count - DisplayedRowCount (false); + for (int index = 0; index < Rows.Count; index++) { DataGridViewRow row = Rows[index]; - if (e.NewValue < top + row.Height) { + if (!row.Visible) + continue; + + if (row.Index >= lastTopVisibleRowIndex) { + first_row_index = lastTopVisibleRowIndex; + } else if (e.NewValue < top + row.Height) { if (first_row_index != index) { first_row_index = index; Invalidate (); @@ -5538,7 +5685,7 @@ namespace System.Windows.Forms { top += row.Height; } - first_row_index = Rows.Count - DisplayedRowCount (false); + first_row_index = lastTopVisibleRowIndex; Invalidate (); OnScroll (e); } @@ -5553,7 +5700,7 @@ namespace System.Windows.Forms { OnColumnAddedInternal(new DataGridViewColumnEventArgs(e.Element as DataGridViewColumn)); break; case CollectionChangeAction.Remove: - OnColumnRemovedInternal(new DataGridViewColumnEventArgs(e.Element as DataGridViewColumn)); + OnColumnPostRemovedInternal(new DataGridViewColumnEventArgs(e.Element as DataGridViewColumn)); break; case CollectionChangeAction.Refresh: break; @@ -5689,6 +5836,8 @@ namespace System.Windows.Forms { only_visible = (mode == DataGridViewAutoSizeColumnMode.DisplayedCells || mode == DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader); for (int i = first_row; i < Rows.Count; i++) { + if (!Rows[i].Visible) + continue; if (only_visible) { Rectangle row_rect = this.GetRowDisplayRectangle (i, false); if (!ClientRectangle.IntersectsWith (row_rect)) @@ -5729,90 +5878,42 @@ namespace System.Windows.Forms { return bounds; } - internal void PrepareEditingRow (bool cell_changed, bool column_changed) + private void PrepareEditingRow (bool cell_changed, bool column_changed) { + if (new_row_editing) + return; + bool show = false; show = ColumnCount > 0 && AllowUserToAddRows; - if (!show && editing_row != null) { - Rows.RemoveInternal (editing_row); - editing_row = null; + if (!show) { + RemoveEditingRow (); } else if (show) { - if (editing_row != null) { - if (cell_changed) { - // The row changed, it's no longer an editing row. - editing_row = null; - } else if (column_changed) { - // The number of columns has changed, we need a new editing row. - Rows.RemoveInternal (editing_row); - editing_row = null; - } + if (editing_row != null && (cell_changed || column_changed)) { + // The row changed, it's no longer an editing row. + // or + // The number of columns has changed, we need a new editing row. + RemoveEditingRow (); } if (editing_row == null) { editing_row = RowTemplateFull; Rows.AddInternal (editing_row, false); } } - - } - internal DataGridViewRow EditingRow { - get { return editing_row; } - } - - private void BindIList (IList list) { - if (autoGenerateColumns) { - is_autogenerating_columns = true; - // 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); - } - } - // Its a generic something or other, like a BindingList, 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) { - GenerateColumnsFromType ((list as BindingSource).item_type); - AllowUserToAddRows = (list as BindingSource).AllowNew; - } - - is_autogenerating_columns = false; - } - - // 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; + internal void RemoveEditingRow () + { + if (editing_row != null) { + if (Rows.Contains (editing_row)) + Rows.RemoveInternal (editing_row); + editing_row = null; } - - // Add the rows - foreach (object element in list) - AddBoundRow (element); } - private void OnBindingSourceDataSourceChanged (object sender, EventArgs args) - { - ReBind (); + internal DataGridViewRow EditingRow { + get { return editing_row; } } private void AddBoundRow (object element) @@ -5837,36 +5938,15 @@ namespace System.Windows.Forms { if (cell == null) continue; - cell.valuex = property.GetValue (element); - cell.valueType = property.PropertyType; + cell.Value = 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; - - if (IsColumnAlreadyBound (property)) - 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 bool IsColumnAlreadyBound (PropertyDescriptor property) + private bool IsColumnAlreadyBound (string name) { foreach (DataGridViewColumn col in Columns) - if (col.DataPropertyName == property.DisplayName) + if (col.DataPropertyName == name) return true; return false; @@ -5876,41 +5956,37 @@ namespace System.Windows.Forms { { if (type == typeof (bool)) return new DataGridViewCheckBoxColumn (); + else if (typeof(Bitmap).IsAssignableFrom (type)) + return new DataGridViewImageColumn (); return new DataGridViewTextBoxColumn (); } private void ClearBinding () { - columns.ClearAutoGeneratedColumns (); - rows.Clear (); - PrepareEditingRow (false, true); + if (IsCurrentCellInEditMode && !EndEdit ()) + CancelEdit (); + MoveCurrentCell (-1, -1, false, false, 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 (DataManager != null) { + DataManager.ListChanged -= OnListChanged; + DataManager.PositionChanged -= OnListPositionChanged; + columns.ClearAutoGeneratedColumns (); + rows.Clear (); + RemoveEditingRow (); + } + } - if (dataSource is IBindingList) - (dataSource as IBindingList).ListChanged -= OnListChanged; - if (dataSource is BindingSource) - (dataSource as BindingSource).DataSourceChanged -= OnBindingSourceDataSourceChanged; + private void ResetRows () + { + rows.Clear (); + RemoveEditingRow (); + if (DataManager != null) { + foreach (object element in DataManager.List) + AddBoundRow (element); } + PrepareEditingRow (false, true); + OnListPositionChanged (this, EventArgs.Empty); } private void DoBinding () @@ -5922,62 +5998,99 @@ namespace System.Windows.Forms { - 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 (dataSource != null && DataManager != null) { + if (autoGenerateColumns) { + is_autogenerating_columns = true; + + foreach (PropertyDescriptor property in DataManager.GetItemProperties()) { + // This keeps out things like arrays + if ((typeof(ICollection).IsAssignableFrom (property.PropertyType))) + continue; + if (!property.IsBrowsable) + continue; + + if (IsColumnAlreadyBound (property.DisplayName)) + continue; + + DataGridViewColumn col = CreateColumnByType (property.PropertyType); + col.Name = property.DisplayName; + col.DataPropertyName = property.DisplayName; + col.ReadOnly = !DataManager.AllowEdit || property.IsReadOnly; + col.SetIsDataBound (true); + col.ValueType = property.PropertyType; + col.AutoGenerated = true; + columns.Add (col); + } + + is_autogenerating_columns = false; } - if (value is DataSet) { - (value as DataSet).Tables.CollectionChanged += OnDataSetTableChanged; - value = (value as DataSet).Tables[dataMember]; + + // DataBind both autogenerated and not columns if there is a matching property + foreach (PropertyDescriptor property in DataManager.GetItemProperties()) { + foreach (DataGridViewColumn col in Columns) { + if (col.DataPropertyName == property.Name) + col.SetIsDataBound (true); + } } - - 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); + foreach (object element in DataManager.List) + AddBoundRow (element); + + DataManager.ListChanged += OnListChanged; + DataManager.PositionChanged += OnListPositionChanged; OnDataBindingComplete (new DataGridViewBindingCompleteEventArgs (ListChangedType.Reset)); + OnListPositionChanged (this, EventArgs.Empty); + } else { + if (Rows.Count > 0 && Columns.Count > 0) + MoveCurrentCell (0, 0, true, false, false, false); } - if (Rows.Count > 0 && Columns.Count > 0) - MoveCurrentCell (0, 0, true, false, false, false); + + PrepareEditingRow (false, true); PerformLayout(); Invalidate (); } - private void BindBindingSource (BindingSource bindingSource) + private void MoveCurrentCell (int x, int y, bool select, bool isControl, bool isShift, bool scroll) { - BindIList (bindingSource.List); - bindingSource.ListChanged += OnBindingSourceDataSourceChanged; - bindingSource.DataSourceChanged += OnBindingSourceDataSourceChanged; - } - - private void BindIListSource (IListSource list) { - BindIList (list.GetList()); - } + if (x == -1 || y == -1) + x = y = -1; + else { + if (x < 0 || x > Columns.Count - 1) + throw new ArgumentOutOfRangeException ("x"); + if (y < 0 || y > Rows.Count - 1) + throw new ArgumentOutOfRangeException ("y"); + + if (!Rows[y].Visible) { + for (int i = y; i < Rows.Count; i++) { + if (Rows[i].Visible) { + y = i; + break; + } + } + } - private void BindIBindingList (IBindingList list) { - BindIList (list); - list.ListChanged += OnListChanged; - } + if (!Columns[x].Visible) { + for (int i = x; i < Columns.Count; i++) { + if (Columns[i].Visible) { + x = i; + break; + } + } + } - private void BindIBindingListView (IBindingListView list) { - BindIList(list); - } + // in case either no visible columns or rows + if (!Rows[y].Visible || !Columns[x].Visible) + x = y = -1; + } - private void MoveCurrentCell (int x, int y, bool select, bool isControl, bool isShift, bool scroll) - { - if (!SetCurrentCellAddressCore (x, y, true, false, false)) + if (!SetCurrentCellAddressCore (x, y, true, false, false)) { + ClearSelection (); + return; + } + if (x == -1 && y == -1) { + ClearSelection (); return; + } bool full_row_selected = Rows.SharedRow(CurrentCellAddress.Y).Selected; bool full_col_selected = Columns[CurrentCellAddress.X].Selected; @@ -6000,15 +6113,25 @@ namespace System.Windows.Forms { // If the current cell isn't visible, scroll to it if (scroll) { int disp_x = ColumnIndexToDisplayIndex (x); + bool scrollbarsRefreshed = false; if (disp_x < first_col_index) { + // The trick here is that in order to avoid unnecessary calculations each time a row/column + // is added/removed we recalculate the whole grid size just before just before the scroll + // to selection. + RefreshScrollBars (); + scrollbarsRefreshed = true; int delta_x = 0; if (disp_x == 0) delta_x = horizontalScrollBar.Value; - else + else { + // in case the column got removed + if (first_col_index >= ColumnCount) + first_col_index = ColumnCount - 1; 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)); @@ -6019,15 +6142,25 @@ namespace System.Windows.Forms { int delta_y = 0; if (disp_y < first_row_index) { + if (!scrollbarsRefreshed) + RefreshScrollBars (); + if (disp_y == 0) delta_y = verticalScrollBar.Value; - else + else { + // in case the row got removed + if (first_row_index >= RowCount) + first_row_index = RowCount - 1; 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 (!scrollbarsRefreshed) + RefreshScrollBars (); + if (disp_y == Rows.Count - 1) delta_y = verticalScrollBar.Maximum - verticalScrollBar.Value; else @@ -6063,6 +6196,8 @@ namespace System.Windows.Forms { private int ColumnIndexToDisplayIndex (int index) { + if (index == -1) + return index; return Columns[index].DisplayIndex; } @@ -6075,38 +6210,38 @@ namespace System.Windows.Forms { { switch (args.ListChangedType) { case ListChangedType.ItemAdded: - AddBoundRow ((sender as IBindingList)[args.NewIndex]); + AddBoundRow (DataManager[args.NewIndex]); break; case ListChangedType.ItemDeleted: - Rows.RemoveAt (args.NewIndex); + Rows.RemoveAtInternal (args.NewIndex); + break; + case ListChangedType.ItemChanged: break; default: - ReBind (); + ResetRows (); break; } Invalidate (); } - private void OnTableColumnChanged (object sender, DataColumnChangeEventArgs e) - { - ReBind (); - } - - private void OnDataSetTableChanged (object sender, CollectionChangeEventArgs e) + private void OnListPositionChanged (object sender, EventArgs args) { - ReBind (); - } - - private void OnTableCleared (object sender, DataTableClearEventArgs e) - { - ReBind (); + if (Rows.Count > 0 && Columns.Count > 0 && DataManager.Position != -1) + MoveCurrentCell (currentCell != null ? currentCell.ColumnIndex : 0, DataManager.Position, + true, false, false, true); + else + MoveCurrentCell (-1, -1, true, false, false, true); } private void ReBind () { - ClearBinding (); - DoBinding (); + if (!is_binding) { + is_binding = true; + ClearBinding (); + DoBinding (); + is_binding = false; + } } private bool MouseOverColumnResize (int col, int mousex) @@ -6216,16 +6351,18 @@ namespace System.Windows.Forms { 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; + return DateTime.Compare ((DateTime)row1.Cells[column].Value, (DateTime)row2.Cells[column].Value) * direction; object val1 = row1.Cells[column].FormattedValue; object val2 = row2.Cells[column].FormattedValue; + object val1NullValue = row1.Cells[column].InheritedStyle.NullValue; + object val2NullValue = row2.Cells[column].InheritedStyle.NullValue; - if (val1 == null && val2 == null) + if (val1 == val1NullValue && val2 == val2NullValue) return 0; - if (val1 == null) + if (val1 == val1NullValue) return direction; - if (val2 == null) + if (val2 == val2NullValue) return -1 * direction; if (numeric_sort)