2008-12-08 Ivan N. Zlatev <contact@i-nz.net>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridView.cs
index b76f26482cf40f1075b432410de9abc6ff527d7d..3f766d3eb01f01c462da2825d4cb66a9a6656b20 100644 (file)
@@ -23,7 +23,6 @@
 //     Pedro Martínez Juliá <pedromj@gmail.com>
 //
 
-
 #if NET_2_0
 
 using System;
@@ -82,13 +81,14 @@ namespace System.Windows.Forms {
                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 int firstDisplayedScrollingRowIndex;
                private Color gridColor = Color.FromKnownColor(KnownColor.ControlDark);
                private int horizontalScrollingOffset;
+               private DataGridViewCell hover_cell = null;
                private bool isCurrentCellDirty;
                //private bool isCurrentRowDirty;
                private bool multiSelect;
@@ -117,11 +117,17 @@ namespace System.Windows.Forms {
                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;
@@ -129,6 +135,16 @@ namespace System.Windows.Forms {
                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);
@@ -155,7 +171,7 @@ namespace System.Windows.Forms {
                        backColor = Control.DefaultBackColor;
                        backgroundColor = SystemColors.AppWorkspace;
                        borderStyle = BorderStyle.FixedSingle;
-                       cellBorderStyle = DataGridViewCellBorderStyle.None;
+                       cellBorderStyle = DataGridViewCellBorderStyle.Single;
                        clipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithAutoHeaderText;
                        columnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
                        columnHeadersDefaultCellStyle = new DataGridViewCellStyle();
@@ -181,6 +197,8 @@ namespace System.Windows.Forms {
                        defaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
                        defaultCellStyle.WrapMode = DataGridViewTriState.False;
                        editMode = DataGridViewEditMode.EditOnKeystrokeOrF2;
+                       firstDisplayedScrollingColumnHiddenWidth = 0;
+                       isCurrentCellDirty = false;
                        multiSelect = true;
                        readOnly = false;
                        rowHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
@@ -250,6 +268,7 @@ namespace System.Windows.Forms {
                                        allowUserToAddRows = value;
                                        OnAllowUserToAddRowsChanged(EventArgs.Empty);
                                        PrepareEditingRow (false, false);
+                                       Invalidate ();
                                }
                        }
                }
@@ -355,7 +374,10 @@ namespace System.Windows.Forms {
                                                }
                                        }
                                }
+                               
                                autoSizeColumnsMode = value;
+                               AutoResizeColumns (value);
+                               Invalidate ();
                        }
                }
 
@@ -371,7 +393,15 @@ namespace System.Windows.Forms {
                                                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 ();
                                        ////////////////////////////////////////////////////////////////
                                }
                        }
@@ -456,8 +486,60 @@ namespace System.Windows.Forms {
                        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);
                                }
                        }
                }
@@ -586,11 +668,13 @@ namespace System.Windows.Forms {
                                /// 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);
                        }
                }
 
@@ -601,7 +685,11 @@ namespace System.Windows.Forms {
 
                [Browsable (false)]
                public DataGridViewRow CurrentRow {
-                       get { return currentRow; }
+                       get { 
+                               if (currentCell != null)
+                                       return currentCell.OwningRow;
+                               return null;
+                       }
                }
 
                [DefaultValue ("")]
@@ -610,8 +698,12 @@ namespace System.Windows.Forms {
                        get { return dataMember; }
                        set {
                                if (dataMember != value) {
+                                       ClearBinding ();
+                                       
                                        dataMember = value;
                                        OnDataMemberChanged(EventArgs.Empty);
+                                       
+                                       DoBinding ();
                                }
                        }
                }
@@ -622,47 +714,21 @@ namespace System.Windows.Forms {
                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 ();
                        }
                }
 
@@ -712,6 +778,26 @@ namespace System.Windows.Forms {
                        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 {
@@ -853,7 +939,7 @@ namespace System.Windows.Forms {
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public int NewRowIndex {
                        get {
-                               if (!allowUserToAddRows) {
+                               if (!allowUserToAddRows || ColumnCount == 0) {
                                        return -1;
                                }
                                return rows.Count - 1;
@@ -868,6 +954,10 @@ namespace System.Windows.Forms {
                        set { }
                }
 
+               internal DataGridViewHeaderCell PressedHeaderCell {
+                       get { return pressed_header_cell; }
+               }
+
                [Browsable (true)]
                [DefaultValue (false)]
                public bool ReadOnly {
@@ -908,7 +998,7 @@ namespace System.Windows.Forms {
                                                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)
@@ -1004,13 +1094,14 @@ namespace System.Windows.Forms {
                        }
                }
 
+               // 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 {
@@ -1019,6 +1110,8 @@ namespace System.Windows.Forms {
                        }
                }
 
+               // 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 ();
@@ -1107,9 +1200,14 @@ namespace System.Windows.Forms {
                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;
                        }
                }
@@ -1191,6 +1289,7 @@ namespace System.Windows.Forms {
                        get { return verticalScrollingOffset; }
                }
 
+               [MonoTODO ("VirtualMode is not supported.")]
                [EditorBrowsable (EditorBrowsableState.Advanced)]
                [DefaultValue (false)]
                public bool VirtualMode {
@@ -1217,8 +1316,11 @@ namespace System.Windows.Forms {
                                        }
                                }
                                
-                               if (value != null)
+                               
+                               if (value != null) {
+                                       value.Visible = false;
                                        Controls.Add (value);
+                               }
 
                                editingControl = value;
                        }
@@ -2033,16 +2135,26 @@ namespace System.Windows.Forms {
                        AutoResizeColumn (columnIndex, DataGridViewAutoSizeColumnMode.AllCells);
                }
 
-               public void AutoResizeColumn (int columnIndex, DataGridViewAutoSizeColumnMode autoSizeColumnMode) {
-                       AutoResizeColumn (columnIndex, autoSizeColumnMode, true);
+               public void AutoResizeColumn (int columnIndex, DataGridViewAutoSizeColumnMode autoSizeColumnMode)
+               {
+                       AutoResizeColumnInternal (columnIndex, autoSizeColumnMode);
                }
 
-               public void AutoResizeColumnHeadersHeight () {
-                       throw new NotImplementedException();
+               public void AutoResizeColumnHeadersHeight ()
+               {
+                       int new_height = 0;
+                       
+                       foreach (DataGridViewColumn col in Columns)
+                               new_height = Math.Max (new_height, col.HeaderCell.PreferredSize.Height);
+                       
+                       if (ColumnHeadersHeight != new_height)
+                               ColumnHeadersHeight = new_height;
                }
 
-               public void AutoResizeColumnHeadersHeight (int columnIndex) {
-                       throw new NotImplementedException();
+               [MonoTODO ("columnIndex parameter is not used")]
+               public void AutoResizeColumnHeadersHeight (int columnIndex)
+               {
+                       AutoResizeColumnHeadersHeight ();
                }
 
                public void AutoResizeColumns () {
@@ -2053,42 +2165,74 @@ namespace System.Windows.Forms {
                        AutoResizeColumns (autoSizeColumnsMode, true);
                }
 
-               public void AutoResizeRow (int rowIndex) {
-                       throw new NotImplementedException();
+               public void AutoResizeRow (int rowIndex)
+               {
+                       AutoResizeRow (rowIndex, DataGridViewAutoSizeRowMode.AllCells, true);
                }
 
-               public void AutoResizeRow (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode) {
-                       throw new NotImplementedException();
+               public void AutoResizeRow (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode)
+               {
+                       AutoResizeRow (rowIndex, autoSizeRowMode, true);
                }
 
-               public void AutoResizeRowHeadersWidth (DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode) {
-                       throw new NotImplementedException();
+               public void AutoResizeRowHeadersWidth (DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode)
+               {
+                       if (rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.AutoSizeToFirstHeader) {
+                               RowHeadersWidth = GetRowInternal (0).HeaderCell.PreferredSize.Width;
+                               return;
+                       }
+                       
+                       int new_width = 0;
+                       
+                       if (rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders) {
+                               foreach (DataGridViewRow row in Rows)
+                                       if (row.Displayed)
+                                               new_width = Math.Max (new_width, row.HeaderCell.PreferredSize.Width);
+                                               
+                               if (RowHeadersWidth != new_width)
+                                       RowHeadersWidth = new_width;
+                                       
+                               return;
+                       }
+
+                       if (rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders) {
+                               foreach (DataGridViewRow row in Rows)
+                                       new_width = Math.Max (new_width, row.HeaderCell.PreferredSize.Width);
+
+                               if (RowHeadersWidth != new_width)
+                                       RowHeadersWidth = new_width;
+
+                               return;
+                       }
                }
 
-               public void AutoResizeRowHeadersWidth (int rowIndex, DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use rowIndex parameter.")]
+               public void AutoResizeRowHeadersWidth (int rowIndex, DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode)
+               {
+                       AutoResizeRowHeadersWidth (rowHeadersWidthSizeMode);
                }
 
-               public void AutoResizeRows () {
-                       throw new NotImplementedException();
+               public void AutoResizeRows ()
+               {
+                       AutoResizeRows (0, Rows.Count, DataGridViewAutoSizeRowMode.AllCells, false);
                }
 
-               public void AutoResizeRows (DataGridViewAutoSizeRowsMode autoSizeRowsMode) {
-                       if (!Enum.IsDefined(typeof(DataGridViewAutoSizeRowsMode), autoSizeRowsMode)) {
-                               throw new InvalidEnumArgumentException("Parameter AutoSizeRowsMode is not valid DataGridViewRowsMode.");
-                       }
-                       if ((autoSizeRowsMode == DataGridViewAutoSizeRowsMode.AllHeaders || autoSizeRowsMode == DataGridViewAutoSizeRowsMode.DisplayedHeaders) && rowHeadersVisible == false) {
-                               throw new InvalidOperationException("Parameter AutoSizeRowsMode cant be AllHeaders or DisplayedHeaders in this DataGridView.");
-                       }
-                       if (autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None) {
-                               throw new ArgumentException("Parameter AutoSieRowsMode cant be None.");
-                       }
+               public void AutoResizeRows (DataGridViewAutoSizeRowsMode autoSizeRowsMode)
+               {
+                       if (!Enum.IsDefined(typeof(DataGridViewAutoSizeRowsMode), autoSizeRowsMode))
+                               throw new InvalidEnumArgumentException ("Parameter autoSizeRowsMode is not a valid DataGridViewRowsMode.");
+                       if ((autoSizeRowsMode == DataGridViewAutoSizeRowsMode.AllHeaders || autoSizeRowsMode == DataGridViewAutoSizeRowsMode.DisplayedHeaders) && rowHeadersVisible == false)
+                               throw new InvalidOperationException ("Parameter autoSizeRowsMode cannot be AllHeaders or DisplayedHeaders in this DataGridView.");
+                       if (autoSizeRowsMode == DataGridViewAutoSizeRowsMode.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;
@@ -2097,34 +2241,88 @@ namespace System.Windows.Forms {
                        
                        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
+                       DataGridViewCellCancelEventArgs e = new DataGridViewCellCancelEventArgs (cell.ColumnIndex, cell.RowIndex);
+                       OnCellBeginEdit (e);
 
-                       cell.SetIsInEditMode (true);
-                       Control ctrl = EditingControlInternal;
-                       bool isCorrectType = ctrl != null && ctrl.GetType () == editType;
-                       if (ctrl != null && !isCorrectType) {
-                               ctrl = null;
+                       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]));
                        }
-                       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));
-                       if (edControl != null)
-                               edControl.PrepareEditingControlForEdit (selectAll);
-                       ctrl.Visible = true;
+                       // 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);
 
-                       OnCellBeginEdit (new DataGridViewCellCancelEventArgs (cell.ColumnIndex, cell.RowIndex));
                        return true;
                }
 
-               public bool CancelEdit () {
-                       throw new NotImplementedException();
+               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));
+                       }
+
+                       return true;
                }
 
                public void ClearSelection ()
@@ -2137,43 +2335,100 @@ namespace System.Windows.Forms {
                                cell.Selected = false;
                }
 
-               public bool CommitEdit (DataGridViewDataErrorContexts context) {
-                       throw new NotImplementedException();
+               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;
+                                       }
+                               }
+                       }
+
+                       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) {
-                               currentCell.SetIsInEditMode (false);
-                               currentCell.DetachEditingControl ();
-                               OnCellEndEdit (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
-                       }
-                       return true;
+               public bool EndEdit ()
+               {
+                       return EndEdit (DataGridViewDataErrorContexts.Commit);
                }
 
-               public bool EndEdit (DataGridViewDataErrorContexts context) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use context parameter")]
+               public bool EndEdit (DataGridViewDataErrorContexts context)
+               {
+                       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) {
@@ -2205,21 +2460,27 @@ namespace System.Windows.Forms {
                        
                        int x = 0, y = 0, w = 0, h = 0;
                        
+                       x = BorderWidth;
+                       y = BorderWidth;
+                       
                        if (ColumnHeadersVisible)
-                               y = ColumnHeadersHeight;
+                               y += ColumnHeadersHeight;
                        
                        if (RowHeadersVisible)
-                               x = RowHeadersWidth;
-                               
-                       ArrayList cols = columns.ColumnDisplayIndexSortedArrayList;
+                               x += RowHeadersWidth;
+
+                       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++) {
@@ -2438,12 +2699,61 @@ namespace System.Windows.Forms {
                        return result;
                }
 
-               public Rectangle GetColumnDisplayRectangle (int columnIndex, bool cutOverflow) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use cutOverflow parameter")]
+               public Rectangle GetColumnDisplayRectangle (int columnIndex, bool cutOverflow)
+               {
+                       if (columnIndex < 0 || columnIndex > Columns.Count - 1)
+                               throw new ArgumentOutOfRangeException ("columnIndex");
+                               
+                       int x = 0;
+                       int w = 0;
+
+                       x = BorderWidth;
+
+                       if (RowHeadersVisible)
+                               x += RowHeadersWidth;
+
+                       List<DataGridViewColumn> cols = columns.ColumnDisplayIndexSortedArrayList;
+
+                       for (int i = first_col_index; i < cols.Count; i++) {
+                               if (!cols[i].Visible)
+                                       continue;
+                                       
+                               if (cols[i].Index == columnIndex) {
+                                       w = cols[i].Width;
+                                       break;
+                               }
+
+                               x += cols[i].Width;
+                       }
+
+                       return new Rectangle (x, 0, w, Height);
                }
 
-               public Rectangle GetRowDisplayRectangle (int rowIndex, bool cutOverflow) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use cutOverflow parameter")]
+               public Rectangle GetRowDisplayRectangle (int rowIndex, bool cutOverflow)
+               {
+                       if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+                               throw new ArgumentOutOfRangeException ("rowIndex");
+
+                       int y = 0;
+                       int h = 0;
+
+                       y = BorderWidth;
+
+                       if (ColumnHeadersVisible)
+                               y += ColumnHeadersHeight;
+
+                       for (int i = first_row_index; i < Rows.Count; i++) {
+                               if (i == rowIndex) {
+                                       h = rows[i].Height;
+                                       break;
+                               }
+
+                               y += rows[i].Height;
+                       }
+
+                       return new Rectangle (0, y, Width, h);
                }
 
                public HitTestInfo HitTest (int x, int y) {
@@ -2486,27 +2796,28 @@ namespace System.Windows.Forms {
                        }
                        
                        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);
@@ -2521,7 +2832,7 @@ namespace System.Windows.Forms {
                        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")]
@@ -2533,7 +2844,7 @@ namespace System.Windows.Forms {
                        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")]
@@ -2542,7 +2853,7 @@ namespace System.Windows.Forms {
                        if (columnIndex < 0 || columnIndex >= columns.Count)
                                throw new ArgumentOutOfRangeException ("Column index is out of range.");
 
-                       Invalidate ();
+                       Invalidate (GetColumnDisplayRectangle (columnIndex, true));
                }
 
                [MonoTODO ("Invalidates whole grid")]
@@ -2551,20 +2862,28 @@ namespace System.Windows.Forms {
                        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 NotImplementedException();
+               public bool RefreshEdit ()
+               {
+                       if (IsCurrentCellInEditMode) {
+                               currentCell.InitializeEditingControl (currentCell.RowIndex, currentCell.FormattedValue, currentCell.InheritedStyle);
+                               return true;
+                       }
+                       
+                       return false;
                }
 
                [EditorBrowsable (EditorBrowsableState.Never)]
-               public override void ResetText () {
-                       throw new NotImplementedException();
+               public override void ResetText ()
+               {
+                       Text = string.Empty;
                }
 
                public void SelectAll () {
@@ -2591,44 +2910,140 @@ namespace System.Windows.Forms {
                        Invalidate ();
                }
 
-               public virtual void Sort (IComparer comparer) {
-                       throw new NotImplementedException();
-               }
+               public virtual void Sort (IComparer comparer)
+               {
+                       if (comparer == null)
+                               throw new ArgumentNullException ("comparer");
+                       if (VirtualMode || DataSource != null)
+                               throw new InvalidOperationException ();
 
-               public virtual void Sort (DataGridViewColumn dataGridViewColumn, ListSortDirection direction) {
-                       throw new NotImplementedException();
-               }
+                       if (SortedColumn != null)
+                               SortedColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
 
-               public void UpdateCellErrorText (int columnIndex, int rowIndex)
-               {
-                       throw new NotImplementedException();
-               }
+                       EndEdit ();
 
-               public void UpdateCellValue (int columnIndex, int rowIndex)
-               {
-                       throw new NotImplementedException();
+                       Rows.Sort (comparer);
+                       
+                       sortedColumn = null;
+                       sortOrder = SortOrder.None;
+                       
+                       currentCell = null;
+                       
+                       Invalidate ();
+                       
+                       OnSorted (EventArgs.Empty);
                }
 
-               public void UpdateRowErrorText (int rowIndex)
+               public virtual void Sort (DataGridViewColumn dataGridViewColumn, ListSortDirection direction)
                {
-                       throw new NotImplementedException();
-               }
-
-               public void UpdateRowErrorText (int rowIndexStart, int rowIndexEnd) {
-                       throw new NotImplementedException();
-               }
+                       if (dataGridViewColumn == null)
+                               throw new ArgumentNullException ("dataGridViewColumn");
+                       if (dataGridViewColumn.DataGridView != this)
+                               throw new ArgumentException ("dataGridViewColumn");
 
-               public void UpdateRowHeightInfo (int rowIndex, bool updateToEnd) {
-                       throw new NotImplementedException();
-               }
+                       if (!EndEdit ())
+                               return;
 
-               protected override Size DefaultSize {
-                       get { return new Size (240, 150); }
-               }
+                       if (SortedColumn != null)
+                               SortedColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
 
-               protected ScrollBar HorizontalScrollBar {
-                       get { return horizontalScrollBar; }
-               }
+                       sortedColumn = dataGridViewColumn;
+                       sortOrder = direction == ListSortDirection.Ascending ? SortOrder.Ascending : SortOrder.Descending;
+                       
+                       if (Rows.Count == 0)
+                               return;
+
+                       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)
+               {
+                       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)
+               {
+                       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)
+               {
+                       if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+                               throw new ArgumentOutOfRangeException ("rowIndex");
+
+                       InvalidateRow (rowIndex);
+               }
+
+               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); }
+               }
+
+               protected ScrollBar HorizontalScrollBar {
+                       get { return horizontalScrollBar; }
+               }
 
                protected ScrollBar VerticalScrollBar {
                        get { return verticalScrollBar; }
@@ -2639,16 +3054,22 @@ namespace System.Windows.Forms {
                        throw new NotImplementedException ();
                }
 
-               protected void AutoResizeColumn (int columnIndex, DataGridViewAutoSizeColumnMode autoSizeColumnMode, bool fixedHeight) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use fixedHeight parameter")]
+               protected void AutoResizeColumn (int columnIndex, DataGridViewAutoSizeColumnMode autoSizeColumnMode, bool fixedHeight)
+               {
+                       AutoResizeColumn (columnIndex, autoSizeColumnMode);
                }
 
-               protected void AutoResizeColumnHeadersHeight (bool fixedRowHeadersWidth, bool fixedColumnsWidth) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use fixedRowHeadersWidth or fixedColumnsWidth parameters")]
+               protected void AutoResizeColumnHeadersHeight (bool fixedRowHeadersWidth, bool fixedColumnsWidth)
+               {
+                       AutoResizeColumnHeadersHeight ();
                }
 
-               protected void AutoResizeColumnHeadersHeight (int columnIndex, bool fixedRowHeadersWidth, bool fixedColumnWidth) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use columnIndex or fixedRowHeadersWidth or fixedColumnsWidth parameters")]
+               protected void AutoResizeColumnHeadersHeight (int columnIndex, bool fixedRowHeadersWidth, bool fixedColumnWidth)
+               {
+                       AutoResizeColumnHeadersHeight (columnIndex);
                }
 
                protected void AutoResizeColumns (DataGridViewAutoSizeColumnsMode autoSizeColumnsMode, bool fixedHeight) {
@@ -2657,24 +3078,82 @@ namespace System.Windows.Forms {
                        }
                }
 
-               protected void AutoResizeRow (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use fixedWidth parameter")]
+               protected void AutoResizeRow (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth)
+               {
+                       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);
                }
 
-               protected void AutoResizeRowHeadersWidth (DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode, bool fixedColumnHeadersHeight, bool fixedRowsHeight) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use fixedColumnHeadersHeight or fixedRowsHeight parameter")]
+               protected void AutoResizeRowHeadersWidth (DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode, bool fixedColumnHeadersHeight, bool fixedRowsHeight)
+               {
+                       AutoResizeRowHeadersWidth (rowHeadersWidthSizeMode);
                }
 
-               protected void AutoResizeRowHeadersWidth (int rowIndex, DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode, bool fixedColumnHeadersHeight, bool fixedRowHeight) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use rowIndex or fixedColumnHeadersHeight or fixedRowsHeight parameter")]
+               protected void AutoResizeRowHeadersWidth (int rowIndex, DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode, bool fixedColumnHeadersHeight, bool fixedRowHeight)
+               {
+                       AutoResizeRowHeadersWidth (rowHeadersWidthSizeMode);
                }
 
-               protected void AutoResizeRows (DataGridViewAutoSizeRowsMode autoSizeRowsMode, bool fixedWidth) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use fixedWidth parameter")]
+               protected void AutoResizeRows (DataGridViewAutoSizeRowsMode autoSizeRowsMode, bool fixedWidth)
+               {
+                       if (autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None)
+                               return;
+                               
+                       bool displayed_only = false;
+                       DataGridViewAutoSizeRowMode mode = DataGridViewAutoSizeRowMode.AllCells;
+                       
+                       switch (autoSizeRowsMode) {
+                               case DataGridViewAutoSizeRowsMode.AllHeaders:
+                                       mode = DataGridViewAutoSizeRowMode.RowHeader;
+                                       break;
+                               case DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders:
+                                       mode = DataGridViewAutoSizeRowMode.AllCellsExceptHeader;
+                                       break;
+                               case DataGridViewAutoSizeRowsMode.AllCells:
+                                       mode = DataGridViewAutoSizeRowMode.AllCells;
+                                       break;
+                               case DataGridViewAutoSizeRowsMode.DisplayedHeaders:
+                                       mode = DataGridViewAutoSizeRowMode.RowHeader;
+                                       displayed_only = true;
+                                       break;
+                               case DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders:
+                                       mode = DataGridViewAutoSizeRowMode.AllCellsExceptHeader;
+                                       displayed_only = true;
+                                       break;
+                               case DataGridViewAutoSizeRowsMode.DisplayedCells:
+                                       mode = DataGridViewAutoSizeRowMode.AllCells;
+                                       displayed_only = true;
+                                       break;
+                       }
+                       
+                       foreach (DataGridViewRow row in Rows) {
+                               if (!displayed_only || row.Displayed) {
+                                       int new_height = row.GetPreferredHeight (row.Index, mode, fixedWidth);
+
+                                       if (row.Height != new_height)
+                                               row.SetAutoSizeHeight (new_height);
+                               }
+                       }
                }
 
-               protected void AutoResizeRows (int rowIndexStart, int rowsCount, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use fixedMode parameter")]
+               protected void AutoResizeRows (int rowIndexStart, int rowsCount, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth)
+               {
+                       for (int i = rowIndexStart; i < rowIndexStart + rowsCount; i++)
+                               AutoResizeRow (i, autoSizeRowMode, fixedWidth);
                }
 
                protected void ClearSelection (int columnIndexException, int rowIndexException, bool selectExceptionElement) {
@@ -2841,7 +3320,7 @@ namespace System.Windows.Forms {
                                eh (this, e);
                }
 
-               protected virtual void OnAutoSizeColumnModeChanged (DataGridViewAutoSizeColumnModeEventArgs e)
+               protected internal virtual void OnAutoSizeColumnModeChanged (DataGridViewAutoSizeColumnModeEventArgs e)
                {
                        DataGridViewAutoSizeColumnModeEventHandler eh = (DataGridViewAutoSizeColumnModeEventHandler)(Events [AutoSizeColumnModeChangedEvent]);
                        if (eh != null)
@@ -3102,6 +3581,10 @@ namespace System.Windows.Forms {
                                eh (this, e);
                }
 
+               internal void OnCellStateChangedInternal (DataGridViewCellStateChangedEventArgs e) {
+                       this.OnCellStateChanged (e);
+               }
+
                protected virtual void OnCellStateChanged (DataGridViewCellStateChangedEventArgs e)
                {
                        DataGridViewCellStateChangedEventHandler eh = (DataGridViewCellStateChangedEventHandler)(Events [CellStateChangedEvent]);
@@ -3156,7 +3639,7 @@ namespace System.Windows.Forms {
                                eh (this, e);
                }
 
-               protected virtual void OnCellValueNeeded (DataGridViewCellValueEventArgs e)
+               protected internal virtual void OnCellValueNeeded (DataGridViewCellValueEventArgs e)
                {
                        DataGridViewCellValueEventHandler eh = (DataGridViewCellValueEventHandler)(Events [CellValueNeededEvent]);
                        if (eh != null)
@@ -3172,6 +3655,11 @@ namespace System.Windows.Forms {
 
                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);
@@ -3235,6 +3723,21 @@ namespace System.Windows.Forms {
 
                protected virtual void OnColumnHeaderMouseClick (DataGridViewCellMouseEventArgs e)
                {
+                       DataGridViewColumn col = Columns[e.ColumnIndex];
+                       
+                       if (col.SortMode == DataGridViewColumnSortMode.Automatic) {
+                               ListSortDirection new_order;
+                               
+                               // Always use ascending unless we are clicking on a
+                               // column that is already sorted ascending.
+                               if (SortedColumn != col || sortOrder != SortOrder.Ascending)
+                                       new_order = ListSortDirection.Ascending;
+                               else
+                                       new_order = ListSortDirection.Descending;
+
+                               Sort (col, new_order);
+                       }
+                       
                        DataGridViewCellMouseEventHandler eh = (DataGridViewCellMouseEventHandler)(Events [ColumnHeaderMouseClickEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -3289,6 +3792,20 @@ namespace System.Windows.Forms {
                                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]);
@@ -3440,8 +3957,8 @@ namespace System.Windows.Forms {
                {
                        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)
@@ -3478,7 +3995,8 @@ namespace System.Windows.Forms {
                                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 ();
                }
 
@@ -3499,16 +4017,34 @@ namespace System.Windows.Forms {
                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);
 
-                       switch (hit.Type) 
-                       {
-                       case DataGridViewHitTestType.Cell:
-                               Rectangle display = GetCellDisplayRectangle (hit.ColumnIndex, hit.RowIndex, false);
-                               OnCellMouseClick (new DataGridViewCellMouseEventArgs (hit.ColumnIndex, hit.RowIndex, e.X - display.X, e.Y - display.Y, e));
-                               break;
-                       
+                       switch (hit.Type) {
+                               case DataGridViewHitTestType.Cell:
+                                       Rectangle display = GetCellDisplayRectangle (hit.ColumnIndex, hit.RowIndex, false);
+                                       Point cellpoint = new Point (e.X - display.X, e.Y - display.Y);
+
+                                       OnCellMouseClick (new DataGridViewCellMouseEventArgs (hit.ColumnIndex, hit.RowIndex, cellpoint.X, cellpoint.Y, e));
+                                       
+                                       DataGridViewCell cell = GetCellInternal (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:
+                                       Rectangle display2 = GetCellDisplayRectangle (hit.ColumnIndex, hit.RowIndex, false);
+                                       Point cellpoint2 = new Point (e.X - display2.X, e.Y - display2.Y);
+                                       
+                                       OnColumnHeaderMouseClick (new DataGridViewCellMouseEventArgs (hit.ColumnIndex, hit.RowIndex, cellpoint2.X, cellpoint2.Y, e));
+                                       break;
                        }
                }
 
@@ -3532,9 +4068,15 @@ namespace System.Windows.Forms {
                                break;
                        case DataGridViewHitTestType.ColumnHeader:
                                mode = selectionMode == DataGridViewSelectionMode.ColumnHeaderSelect ? DataGridViewSelectionMode.FullColumnSelect : selectionMode;
+                               
+                               if (mode != DataGridViewSelectionMode.FullColumnSelect)
+                                       return;
                                break;
                        case DataGridViewHitTestType.RowHeader:
                                mode = selectionMode == DataGridViewSelectionMode.RowHeaderSelect ?  DataGridViewSelectionMode.FullRowSelect : selectionMode;
+
+                               if (mode != DataGridViewSelectionMode.FullRowSelect)
+                                       return;
                                break; // Handled below
                        default:
                                return;
@@ -3654,45 +4196,76 @@ namespace System.Windows.Forms {
                {
                        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);
@@ -3700,43 +4273,198 @@ namespace System.Windows.Forms {
 
                protected override void OnMouseLeave (EventArgs e)
                {
-                       base.OnMouseLeave(e);
+                       base.OnMouseLeave (e);
+                       
+                       if (hover_cell != null) {
+                               OnCellMouseLeave (new DataGridViewCellEventArgs (hover_cell.ColumnIndex, hover_cell.RowIndex));
+                               hover_cell = null;
+                       }
+                       
+                       EnteredHeaderCell = null;
                }
-
+               
                protected override void OnMouseMove (MouseEventArgs e)
                {
-                       base.OnMouseMove(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);
                        
-                       switch (hit.Type)
-                       {
-                       case DataGridViewHitTestType.Cell:
-                               Rectangle display = GetCellDisplayRectangle (hit.ColumnIndex, hit.RowIndex, false);
-                               OnCellMouseMove (new DataGridViewCellMouseEventArgs (hit.ColumnIndex, hit.RowIndex, e.X - display.X, e.Y - display.Y, e));
-                               break;
-                       case DataGridViewHitTestType.ColumnHeader:
-                       case DataGridViewHitTestType.RowHeader:
-                       case DataGridViewHitTestType.TopLeftHeader:
+                       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;
+                                       OnCellMouseEnter (new DataGridViewCellEventArgs (hit.ColumnIndex, hit.RowIndex));
+                                       
+                                       Rectangle display = GetCellDisplayRectangle (hit.ColumnIndex, hit.RowIndex, false);
+                                       OnCellMouseMove (new DataGridViewCellMouseEventArgs (hit.ColumnIndex, hit.RowIndex, e.X - display.X, e.Y - display.Y, e));
+                                       
+                                       return;
+                               }
                        
-                       case DataGridViewHitTestType.HorizontalScrollBar:
-                       case DataGridViewHitTestType.VerticalScrollBar:
+                               // Were we already in this cell?
+                               if (hover_cell.RowIndex == hit.RowIndex && hover_cell.ColumnIndex == hit.ColumnIndex) {
+                                       Rectangle display = GetCellDisplayRectangle (hit.ColumnIndex, hit.RowIndex, false);
+                                       OnCellMouseMove (new DataGridViewCellMouseEventArgs (hit.ColumnIndex, hit.RowIndex, e.X - display.X, e.Y - display.Y, e));
+                               
+                                       return;
+                               }
                        
+                               // We are changing cells
+                               OnCellMouseLeave (new DataGridViewCellEventArgs (hover_cell.ColumnIndex, hover_cell.RowIndex));
+
+                               hover_cell = new_cell;
+                               
+                               OnCellMouseEnter (new DataGridViewCellEventArgs (hit.ColumnIndex, hit.RowIndex));
+
+                               Rectangle display2 = GetCellDisplayRectangle (hit.ColumnIndex, hit.RowIndex, false);
+                               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);
+                               }
                        
-                       case DataGridViewHitTestType.None:
-                               break;
+                       } 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)
@@ -3767,14 +4495,14 @@ namespace System.Windows.Forms {
                        
                        // 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);
@@ -3789,7 +4517,10 @@ namespace System.Windows.Forms {
                                        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;
@@ -3797,7 +4528,7 @@ namespace System.Windows.Forms {
                                        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;
                                }
@@ -3805,47 +4536,70 @@ namespace System.Windows.Forms {
                                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;
@@ -4077,9 +4831,23 @@ namespace System.Windows.Forms {
                        if (eh != null) eh (this, e);
                }
 
-               protected internal virtual void OnRowsRemoved (DataGridViewRowsRemovedEventArgs e)
+               internal void OnRowsRemovedInternal (DataGridViewRowsRemovedEventArgs e)
                {
-                       DataGridViewRowsRemovedEventHandler eh = (DataGridViewRowsRemovedEventHandler)(Events [RowsRemovedEvent]);
+                       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);
                }
 
@@ -4132,6 +4900,11 @@ namespace System.Windows.Forms {
 
                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);
                }
@@ -4179,7 +4952,7 @@ namespace System.Windows.Forms {
 
                protected virtual bool ProcessDataGridViewKey (KeyEventArgs e)
                {
-                       switch (e.KeyCode) {
+                       switch (e.KeyData & ~Keys.Modifiers) {
                                case Keys.A:
                                        return ProcessAKey (e.KeyData);
                                case Keys.Delete:
@@ -4198,10 +4971,16 @@ namespace System.Windows.Forms {
                                        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:
+                                       return ProcessTabKey (e.KeyData);
                                case Keys.Up:
                                        return ProcessUpKey (e.KeyData);
                                case Keys.D0:
@@ -4212,14 +4991,60 @@ namespace System.Windows.Forms {
                        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)
                {
+                       switch (keyData) {
+                               case Keys.Tab:
+                               case Keys.Shift | Keys.Tab:
+                                       if (standardTab)
+                                               return base.ProcessDialogKey (keyData & ~Keys.Control);
+                                               
+                                       if (ProcessDataGridViewKey (new KeyEventArgs (keyData)))
+                                               return true;
+                                               
+                                       break;
+                               case Keys.Control | Keys.Tab:
+                               case Keys.Control | Keys.Shift | Keys.Tab:
+                                       if (!standardTab)
+                                               return base.ProcessDialogKey (keyData & ~Keys.Control);
+
+                                       if (ProcessDataGridViewKey (new KeyEventArgs (keyData)))
+                                               return true;
+                                               
+                                       break;
+                               case Keys.Enter:
+                               case Keys.Escape:
+                                       if (ProcessDataGridViewKey (new KeyEventArgs (keyData)))
+                                               return true;
+                                               
+                                       break;
+                       }
+                       
                        return base.ProcessDialogKey(keyData);
                }
 
@@ -4230,10 +5055,10 @@ namespace System.Windows.Forms {
                        if (current_row < Rows.Count - 1) {
                                // 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;
                        }
@@ -4247,13 +5072,13 @@ namespace System.Windows.Forms {
 
                        // 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;
                        }
 
@@ -4262,19 +5087,12 @@ namespace System.Windows.Forms {
 
                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;
                }
 
@@ -4303,13 +5121,13 @@ namespace System.Windows.Forms {
 
                        // 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;
                        }
 
@@ -4322,14 +5140,42 @@ namespace System.Windows.Forms {
                        return false;
                }
 
-               protected override bool ProcessKeyEventArgs (ref Message m) {
-                       return base.ProcessKeyEventArgs(ref m);
-                       //throw new NotImplementedException();
+               protected override bool ProcessKeyEventArgs (ref Message m)
+               {
+                       DataGridViewCell cell = CurrentCell;
+                       
+                       if (cell != null)
+                               if (cell.KeyEntersEditMode (new KeyEventArgs ((Keys)m.WParam.ToInt32 ())))
+                                       BeginEdit (true);
+
+                       return base.ProcessKeyEventArgs (ref m);
                }
 
-               protected override bool ProcessKeyPreview (ref Message m) {
-                       return base.ProcessKeyPreview(ref m);
-                       //throw new NotImplementedException();
+               protected override bool ProcessKeyPreview (ref Message m)
+               {
+                       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 != null)
+                                       if (ctrl.EditingControlWantsInputKey (e.KeyData, false))
+                                               return false;
+
+                               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);
                }
 
                protected bool ProcessLeftKey (Keys keyData)
@@ -4339,10 +5185,10 @@ namespace System.Windows.Forms {
                        if (disp_index > 0) {
                                // 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;
                        }
@@ -4350,14 +5196,38 @@ namespace System.Windows.Forms {
                        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)
@@ -4367,10 +5237,10 @@ namespace System.Windows.Forms {
                        if (disp_index < Columns.Count - 1) {
                                // 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;
                        }
@@ -4410,8 +5280,44 @@ namespace System.Windows.Forms {
                        return false;
                }
 
-               protected bool ProcessTabKey (Keys keyData) {
-                       throw new NotImplementedException();
+               protected bool ProcessTabKey (Keys keyData)
+               {
+                       Form f = FindForm ();
+                       
+                       if (f != null)
+                               f.ActivateFocusCues ();
+                       
+                       int disp_index = ColumnIndexToDisplayIndex (currentCellAddress.X);
+
+                       // Tab goes forward
+                       // Shift-tab goes backwards
+                       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, 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, 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, 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, true);
+                                       return true;
+                               }
+
+                       
+                       }
+                       
+                       return false;
                }
 
                protected bool ProcessUpKey (Keys keyData)
@@ -4421,10 +5327,10 @@ namespace System.Windows.Forms {
                        if (current_row > 0) {
                                // 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;
                        }
@@ -4447,7 +5353,7 @@ namespace System.Windows.Forms {
                        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)
@@ -4465,19 +5371,37 @@ namespace System.Windows.Forms {
                        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) {
@@ -4500,6 +5424,8 @@ namespace System.Windows.Forms {
                        } else if (selected && !selected_columns.Contains (col)) {
                                selected_columns.InternalAdd (col);
                        }
+
+                       Invalidate();
                }
 
                internal void SetSelectedRowCoreInternal (int rowIndex, bool selected) {
@@ -4519,59 +5445,44 @@ namespace System.Windows.Forms {
                        } else if (selected && !selected_rows.Contains (row)) {
                                selected_rows.InternalAdd (row);
                        }
-               }
 
-               protected override void WndProc (ref Message m) {
-                       base.WndProc(ref m);
+                       Invalidate();
                }
 
-               void IDropTarget.OnDragDrop (DragEventArgs e)
+               protected override void WndProc (ref Message m)
                {
-                       throw new NotImplementedException ();
+                       base.WndProc (ref m);
                }
 
-               void IDropTarget.OnDragEnter (DragEventArgs e)
+               internal void InternalOnCellClick (DataGridViewCellEventArgs e)
                {
-                       throw new NotImplementedException ();
+                       OnCellClick (e);
                }
 
-               void IDropTarget.OnDragLeave (EventArgs e)
+               internal void InternalOnCellContentClick (DataGridViewCellEventArgs e)
                {
-                       throw new NotImplementedException ();
+                       OnCellContentClick (e);
                }
 
-               void IDropTarget.OnDragOver (DragEventArgs e)
+               internal void InternalOnCellContentDoubleClick (DataGridViewCellEventArgs e)
                {
-                       throw new NotImplementedException ();
+                       OnCellContentDoubleClick (e);
                }
 
-               internal void InternalOnCellClick (DataGridViewCellEventArgs e) {
-                       OnCellClick(e);
-               }
-
-               internal void InternalOnCellContentClick (DataGridViewCellEventArgs e) {
-                       OnCellContentClick(e);
-               }
-
-               internal void InternalOnCellContentDoubleClick (DataGridViewCellEventArgs e) {
-                       OnCellContentDoubleClick(e);
-               }
-
-               internal void InternalOnCellValueChanged (DataGridViewCellEventArgs e) {
-                       OnCellValueChanged(e);
-                       
-                       if (editing_row != null && e.RowIndex == editing_row.Index) {
-                               PrepareEditingRow (true, false);
-                       }
+               internal void InternalOnCellValueChanged (DataGridViewCellEventArgs e)
+               {
+                       OnCellValueChanged (e);
                }
 
-               internal void InternalOnDataError (DataGridViewDataErrorEventArgs e) {
+               internal void InternalOnDataError (DataGridViewDataErrorEventArgs e)
+               {
                        /////////////// false? ////////////
-                       OnDataError(false, e);
+                       OnDataError (false, e);
                }
 
-               internal void InternalOnMouseWheel (MouseEventArgs e) {
-                       OnMouseWheel(e);
+               internal void InternalOnMouseWheel (MouseEventArgs e)
+               {
+                       OnMouseWheel (e);
                }
 
                internal void OnHScrollBarScroll (object sender, ScrollEventArgs e)
@@ -4599,11 +5510,13 @@ namespace System.Windows.Forms {
                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;
@@ -4616,6 +5529,10 @@ namespace System.Windows.Forms {
                                
                                top += row.Height;
                        }
+                       
+                       first_row_index = Rows.Count - DisplayedRowCount (false);
+                       Invalidate ();
+                       OnScroll (e);
                }
 
                internal void RaiseCellStyleChanged (DataGridViewCellEventArgs e) {
@@ -4625,10 +5542,10 @@ namespace System.Windows.Forms {
                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;
@@ -4649,7 +5566,7 @@ namespace System.Windows.Forms {
                {
                        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;
@@ -4732,7 +5649,8 @@ namespace System.Windows.Forms {
                        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;
@@ -4769,22 +5687,48 @@ namespace System.Windows.Forms {
                                                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) {
@@ -4793,7 +5737,7 @@ namespace System.Windows.Forms {
                                                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;
                                        }
                                }
@@ -4811,54 +5755,216 @@ namespace System.Windows.Forms {
                }
 
                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;
                        
@@ -4877,8 +5983,47 @@ namespace System.Windows.Forms {
                        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;
@@ -4909,25 +6054,170 @@ namespace System.Windows.Forms {
                
                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;
+                       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;
+                       }
+
+                       #region IComparer Members
+                       public int Compare (object x, object y)
+                       {
+                               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 (val1 == null && val2 == null)
+                                       return 0;
+                               if (val1 == null)
+                                       return direction;
+                               if (val2 == null)
+                                       return -1 * 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
                }
 
                public sealed class HitTestInfo {
@@ -4991,7 +6281,7 @@ namespace System.Windows.Forms {
                [ComVisible (false)]
                public class DataGridViewControlCollection : Control.ControlCollection
                {
-                       private new DataGridView owner;
+                       private DataGridView owner;
                        
                        public DataGridViewControlCollection (DataGridView owner) : base (owner)
                        {
@@ -5144,7 +6434,6 @@ namespace System.Windows.Forms {
                        #endregion
                }
        }
-
 }
 
 #endif