Warnings cleanup
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridView.cs
index 65f0e309aff939599ecb6af5b599afb5d3e4549f..675575fb677f9663a756af1aabf345e330242c3e 100644 (file)
@@ -23,7 +23,6 @@
 //     Pedro Martínez Juliá <pedromj@gmail.com>
 //
 
-
 #if NET_2_0
 
 using System;
@@ -33,6 +32,7 @@ using System.Drawing;
 using System.Reflection;
 using System.Collections;
 using System.Data;
+using System.Collections.Generic;
 
 namespace System.Windows.Forms {
 
@@ -56,6 +56,7 @@ namespace System.Windows.Forms {
                private bool allowUserToResizeColumns;
                private bool allowUserToResizeRows;
                private DataGridViewCellStyle alternatingRowsDefaultCellStyle;
+               private Point anchor_cell;
                private bool autoGenerateColumns;
                private bool autoSize;
                private DataGridViewAutoSizeColumnsMode autoSizeColumnsMode;
@@ -80,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;
@@ -115,11 +117,32 @@ namespace System.Windows.Forms {
                private HScrollBar horizontalScrollBar;
                private VScrollBar verticalScrollBar;
                private Control editingControl;
+
+               // These are used to implement selection behaviour with SHIFT pressed.
+               private int selected_row = -1;
+               private int selected_column = -1;
                
-               internal int gridWidth;
-               internal int gridHeight;
+               // Stuff for error Tooltips
+               private Timer tooltip_timer;
+               private ToolTip tooltip_window;
+               private DataGridViewCell tooltip_currently_showing;
+
+               private DataGridViewSelectedRowCollection selected_rows;
+               private DataGridViewSelectedColumnCollection selected_columns;
+               private DataGridViewRow editing_row;
+               
+               private int gridWidth;
+               private int gridHeight;
+
+               DataGridViewHeaderCell pressed_header_cell;
+               DataGridViewHeaderCell entered_header_cell;
 
-               public DataGridView () {
+               public DataGridView ()
+               {
+                       SetStyle (ControlStyles.Opaque, true);
+                       //SetStyle (ControlStyles.UserMouse, true);
+                       SetStyle (ControlStyles.OptimizedDoubleBuffer, true);
+                       
                        adjustedTopLeftHeaderBorderStyle = new DataGridViewAdvancedBorderStyle();
                        adjustedTopLeftHeaderBorderStyle.All = DataGridViewAdvancedCellBorderStyle.Single;
                        advancedCellBorderStyle = new DataGridViewAdvancedBorderStyle();
@@ -182,15 +205,14 @@ namespace System.Windows.Forms {
                        virtualMode = false;
 
                        horizontalScrollBar = new HScrollBar();
-                       horizontalScrollBar.Dock = DockStyle.Bottom;
                        horizontalScrollBar.Scroll += OnHScrollBarScroll;
                        horizontalScrollBar.Visible = false;
-                       Controls.Add (horizontalScrollBar);
+                       
                        verticalScrollBar = new VScrollBar();
-                       verticalScrollBar.Dock = DockStyle.Right;
                        verticalScrollBar.Scroll += OnVScrollBarScroll;
                        verticalScrollBar.Visible = false;
-                       Controls.Add (verticalScrollBar);
+                       
+                       Controls.AddRange (new Control[] {horizontalScrollBar, verticalScrollBar});
                }
 
                void ISupportInitialize.BeginInit ()
@@ -235,6 +257,8 @@ namespace System.Windows.Forms {
                                if (allowUserToAddRows != value) {
                                        allowUserToAddRows = value;
                                        OnAllowUserToAddRowsChanged(EventArgs.Empty);
+                                       PrepareEditingRow (false, false);
+                                       Invalidate ();
                                }
                        }
                }
@@ -340,7 +364,10 @@ namespace System.Windows.Forms {
                                                }
                                        }
                                }
+                               
                                autoSizeColumnsMode = value;
+                               AutoResizeColumns (value);
+                               Invalidate ();
                        }
                }
 
@@ -356,7 +383,9 @@ namespace System.Windows.Forms {
                                                throw new InvalidOperationException("Cant set this property to AllHeaders or DisplayedHeaders in this DataGridView.");
                                        }
                                        autoSizeRowsMode = value;
+                                       AutoResizeRows (value);
                                        OnAutoSizeRowsModeChanged(new DataGridViewAutoSizeModeEventArgs(false));
+                                       Invalidate ();
                                        ////////////////////////////////////////////////////////////////
                                }
                        }
@@ -421,6 +450,20 @@ namespace System.Windows.Forms {
                        }
                }
 
+               internal int BorderWidth {
+                       get {
+                               switch (BorderStyle) {
+                               case BorderStyle.Fixed3D:
+                                       return 2;
+                               case BorderStyle.FixedSingle:
+                                       return 1;
+                               case BorderStyle.None:
+                               default:
+                                       return 0;
+                               }
+                       }
+               }
+
                [Browsable (true)]
                [DefaultValue (DataGridViewCellBorderStyle.Single)]
                public DataGridViewCellBorderStyle CellBorderStyle {
@@ -461,7 +504,7 @@ namespace System.Windows.Forms {
                                }
                                else if (value > columns.Count) {
                                        for (int i = 0; i < value; i++) {
-                                               DataGridViewColumn col = new DataGridViewColumn();
+                                               DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn ();
                                                columns.Add(col);
                                        }
                                }
@@ -506,6 +549,9 @@ namespace System.Windows.Forms {
                                        }
                                        columnHeadersHeight = value;
                                        OnColumnHeadersHeightChanged(EventArgs.Empty);
+                                       
+                                       if (columnHeadersVisible)
+                                               Invalidate ();
                                }
                        }
                }
@@ -528,7 +574,12 @@ namespace System.Windows.Forms {
                [DefaultValue (true)]
                public bool ColumnHeadersVisible {
                        get { return columnHeadersVisible; }
-                       set { columnHeadersVisible = value; }
+                       set {
+                               if (columnHeadersVisible != value) {
+                                       columnHeadersVisible = value;
+                                       Invalidate ();
+                               }
+                       }
                }
 
                [MergableProperty (false)]
@@ -553,6 +604,7 @@ namespace System.Windows.Forms {
                                        throw new ArgumentException("The cell is not in this DataGridView.");
                                }
                                currentCell = value;
+                               currentRow = currentCell.OwningRow;
                        }
                }
 
@@ -572,8 +624,12 @@ namespace System.Windows.Forms {
                        get { return dataMember; }
                        set {
                                if (dataMember != value) {
+                                       ClearBinding ();
+                                       
                                        dataMember = value;
                                        OnDataMemberChanged(EventArgs.Empty);
+                                       
+                                       DoBinding ();
                                }
                        }
                }
@@ -581,7 +637,6 @@ namespace System.Windows.Forms {
                [RefreshProperties (RefreshProperties.Repaint)]
                [DefaultValue (null)]
                [AttributeProvider (typeof (IListSource))]
-               // XXX AttributeProviderAtribute
                public object DataSource {
                        get { return dataSource; }
                        set {
@@ -595,36 +650,13 @@ namespace System.Windows.Forms {
                                        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;
-                                               }
-                                       }
+                                               
+                                       ClearBinding ();
+                                       
                                        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();
+                                       OnDataSourceChanged (EventArgs.Empty);
+                                       
+                                       DoBinding ();
                                }
                        }
                }
@@ -648,10 +680,7 @@ namespace System.Windows.Forms {
                [EditorBrowsable (EditorBrowsableState.Advanced)]
                public Control EditingControl {
                        get {
-                               if (currentCell == null || !currentCell.IsInEditMode) {
-                                       return null;
-                               }
-                               return (Control) Activator.CreateInstance(currentCell.EditType);
+                               return editingControl;
                        }
                }
 
@@ -678,6 +707,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 {
@@ -834,6 +883,10 @@ namespace System.Windows.Forms {
                        set { }
                }
 
+               internal DataGridViewHeaderCell PressedHeaderCell {
+                       get { return pressed_header_cell; }
+               }
+
                [Browsable (true)]
                [DefaultValue (false)]
                public bool ReadOnly {
@@ -868,20 +921,19 @@ namespace System.Windows.Forms {
                                        }
                                }
                                else if (value > rows.Count) {
-                                       for (int i = 0; i < value; i++) {
-                                               // DataGridViewRow row = new DataGridViewRow(); //(DataGridViewRow) rowTemplate.Clone();
-                                               DataGridViewRow row = (DataGridViewRow) rowTemplate.Clone();
-                                               rows.Add(row);
-                                               foreach (DataGridViewColumn col in columns) {
-                                                       row.Cells.Add(col.CellTemplate.Clone() as DataGridViewCell);
-                                               }
+                                       // If we need to add rows and don't have any columns,
+                                       // we create one column
+                                       if (ColumnCount == 0)
+                                               ColumnCount = 1;
+
+                                       for (int i = rows.Count; i < value; i++) {
+                                               DataGridViewRow row = (DataGridViewRow) RowTemplate.Clone ();
+                                               rows.AddInternal (row, false);
+                                               
+                                               foreach (DataGridViewColumn col in columns)
+                                                       row.Cells.Add (col.CellTemplate.Clone () as DataGridViewCell);
                                        }
                                }
-                               if (ColumnCount == 0) {
-                                       ///////////////////////////////////////////////////////////////
-                                       //columns.Add(new DataGridViewTextBoxColumn());
-                                       throw new NotImplementedException();
-                               }
                        }
                }
 
@@ -911,7 +963,12 @@ namespace System.Windows.Forms {
                [DefaultValue (true)]
                public bool RowHeadersVisible {
                        get { return rowHeadersVisible; }
-                       set { rowHeadersVisible = value; }
+                       set {
+                               if (rowHeadersVisible != value) {
+                                       rowHeadersVisible = value;
+                                       Invalidate ();
+                               }
+                       }
                }
 
                [Localizable (true)]
@@ -929,6 +986,9 @@ namespace System.Windows.Forms {
                                        }
                                        rowHeadersWidth = value;
                                        OnRowHeadersWidthChanged(EventArgs.Empty);
+                                       
+                                       if (rowHeadersVisible)
+                                               Invalidate ();
                                }
                        }
                }
@@ -967,9 +1027,9 @@ namespace System.Windows.Forms {
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                public DataGridViewRow RowTemplate {
                        get {
-                               if (rowTemplate == null) {
-                                       return new DataGridViewRow();
-                               }
+                               if (rowTemplate == null)
+                                       rowTemplate = new DataGridViewRow ();
+
                                return rowTemplate;
                        }
                        set {
@@ -978,6 +1038,27 @@ namespace System.Windows.Forms {
                        }
                }
 
+               internal DataGridViewRow RowTemplateFull {
+                       get {
+                               DataGridViewRow row = (DataGridViewRow) RowTemplate.Clone ();
+                               
+                               for (int i = row.Cells.Count; i < Columns.Count; i++) {
+                                       DataGridViewCell template = columns [i].CellTemplate;
+                                       
+                                       if (template == null)
+                                               throw new InvalidOperationException ("At least one of the DataGridView control's columns has no cell template.");
+                                       
+                                       row.Cells.Add ((DataGridViewCell) template.Clone ());
+                               }
+                               
+                               return row;
+                       }
+               }
+
+               internal override bool ScaleChildrenInternal {
+                       get { return false; }
+               }
+
                [DefaultValue (ScrollBars.Both)]
                [Localizable (true)]
                public ScrollBars ScrollBars {
@@ -1013,31 +1094,30 @@ namespace System.Windows.Forms {
 
                [Browsable (false)]
                public DataGridViewSelectedColumnCollection SelectedColumns {
-                       get {
-                               DataGridViewSelectedColumnCollection selectedColumns = new DataGridViewSelectedColumnCollection();
-                               if (selectionMode == DataGridViewSelectionMode.FullColumnSelect || selectionMode == DataGridViewSelectionMode.ColumnHeaderSelect) {
-                                       foreach (DataGridViewColumn col in columns) {
-                                               if (col.Selected) {
-                                                       selectedColumns.InternalAdd(col);
-                                               }
-                                       }
-                               }
-                               return selectedColumns;
+                       get
+                       {
+                               DataGridViewSelectedColumnCollection result = new DataGridViewSelectedColumnCollection ();
+
+                               if (selectionMode != DataGridViewSelectionMode.FullColumnSelect && selectionMode != DataGridViewSelectionMode.ColumnHeaderSelect)
+                                       return result;
+
+                               result.InternalAddRange (selected_columns);
+
+                               return result;
                        }
                }
 
                [Browsable (false)]
                public DataGridViewSelectedRowCollection SelectedRows {
                        get {
-                               DataGridViewSelectedRowCollection selectedRows = new DataGridViewSelectedRowCollection();
-                               if (selectionMode == DataGridViewSelectionMode.FullColumnSelect || selectionMode == DataGridViewSelectionMode.RowHeaderSelect) {
-                                       foreach (DataGridViewRow row in rows) {
-                                               if (row.Selected) {
-                                                       selectedRows.InternalAdd(row);
-                                               }
-                                       }
-                               }
-                               return selectedRows;
+                               DataGridViewSelectedRowCollection result = new DataGridViewSelectedRowCollection (this);
+                               
+                               if (selectionMode != DataGridViewSelectionMode.FullRowSelect && selectionMode != DataGridViewSelectionMode.RowHeaderSelect)
+                                       return result;
+                               
+                               result.InternalAddRange (selected_rows);
+
+                               return result;
                        }
                }
 
@@ -1046,9 +1126,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;
                        }
                }
@@ -1105,8 +1190,17 @@ namespace System.Windows.Forms {
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public DataGridViewHeaderCell TopLeftHeaderCell {
-                       get { return topLeftHeaderCell; }
-                       set { topLeftHeaderCell = value; }
+                       get {
+                               if (topLeftHeaderCell == null) {
+                                       topLeftHeaderCell = new DataGridViewTopLeftHeaderCell ();
+                                       topLeftHeaderCell.SetDataGridView (this);
+                               }
+                               return topLeftHeaderCell;
+                       }
+                       set {
+                               topLeftHeaderCell = value;
+                               topLeftHeaderCell.SetDataGridView (this);
+                       }
                }
 
                [Browsable (false)]
@@ -1121,6 +1215,7 @@ namespace System.Windows.Forms {
                        get { return verticalScrollingOffset; }
                }
 
+               [MonoTODO ("VirtualMode is not supported.")]
                [EditorBrowsable (EditorBrowsableState.Advanced)]
                [DefaultValue (false)]
                public bool VirtualMode {
@@ -1137,13 +1232,23 @@ namespace System.Windows.Forms {
                                        return;
 
                                if (editingControl != null) {
-                                       // Can't use Controls.RemoveAt (editingControls), because that method
+                                       // Can't use Controls.Remove (editingControls), because that method
                                        // is overriden to not remove the editing control.
-                                       Controls.RemoveAt (Controls.IndexOf (editingControl));
+                                       DataGridView.DataGridViewControlCollection ctrls = Controls as DataGridView.DataGridViewControlCollection;
+                                       if (ctrls != null) {
+                                               ctrls.RemoveInternal (editingControl);
+                                       } else {
+                                               Controls.Remove (editingControl);
+                                       }
                                }
                                
-                               if (value != null)
-                                       Controls.Add (editingControl);
+                               
+                               if (value != null) {
+                                       value.Visible = false;
+                                       Controls.Add (value);
+                               }
+
+                               editingControl = value;
                        }
                }
 
@@ -1953,107 +2058,249 @@ namespace System.Windows.Forms {
                }
 
                public void AutoResizeColumn (int columnIndex) {
-                       throw new NotImplementedException();
+                       AutoResizeColumn (columnIndex, DataGridViewAutoSizeColumnMode.AllCells);
                }
 
-               public void AutoResizeColumn (int columnIndex, DataGridViewAutoSizeColumnMode autoSizeColumnMode) {
-                       throw new NotImplementedException();
+               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 () {
-                       throw new NotImplementedException();
+                       AutoResizeColumns (DataGridViewAutoSizeColumnsMode.AllCells);
                }
 
                public void AutoResizeColumns (DataGridViewAutoSizeColumnsMode autoSizeColumnsMode) {
-                       throw new NotImplementedException();
+                       AutoResizeColumns (autoSizeColumnsMode, true);
                }
 
-               public void AutoResizeRow (int rowIndex) {
-                       throw new NotImplementedException();
+               public void AutoResizeRow (int rowIndex)
+               {
+                       AutoResizeRow (rowIndex, DataGridViewAutoSizeRowMode.AllCells);
                }
 
-               public void AutoResizeRow (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode) {
-                       throw new NotImplementedException();
+               public void AutoResizeRow (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode)
+               {
+                       if (autoSizeRowMode == DataGridViewAutoSizeRowMode.RowHeader && !rowHeadersVisible)
+                               throw new InvalidOperationException ("row headers are not visible");
+                       if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+                               throw new ArgumentOutOfRangeException ("rowIndex");
+                       
+                       DataGridViewRow row = GetRowInternal (rowIndex);
+                       
+                       if (autoSizeRowMode == DataGridViewAutoSizeRowMode.RowHeader) {
+                               row.Height = row.HeaderCell.PreferredSize.Height;
+                               return;
+                       }
+                       
+                       int row_height = 0;
+                       
+                       foreach (DataGridViewCell cell in row.Cells)
+                               row_height = Math.Max (row_height, cell.PreferredSize.Height);
+                               
+                       if (autoSizeRowMode == DataGridViewAutoSizeRowMode.AllCellsExceptHeader)
+                               row.Height = row_height;
+                       else
+                               row.Height = Math.Max (row_height, row.HeaderCell.PreferredSize.Height);
                }
 
-               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.");
+               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.");
+                       
+                       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;
+                               }
                        }
-                       if ((autoSizeRowsMode == DataGridViewAutoSizeRowsMode.AllHeaders || autoSizeRowsMode == DataGridViewAutoSizeRowsMode.DisplayedHeaders) && rowHeadersVisible == false) {
-                               throw new InvalidOperationException("Parameter AutoSizeRowsMode cant be AllHeaders or DisplayedHeaders in this DataGridView.");
+                       
+                       DataGridViewCell cell = currentCell;
+                       Type editType = cell.EditType;
+                       if (editType == null)
+                               return false;
+                               
+                       // Give user a chance to cancel the edit
+                       DataGridViewCellCancelEventArgs e = new DataGridViewCellCancelEventArgs (cell.ColumnIndex, cell.RowIndex);
+                       OnCellBeginEdit (e);
+
+                       if (e.Cancel)
+                               return false;
+                               
+                       cell.SetIsInEditMode (true);
+                       Control ctrl = EditingControlInternal;
+                       bool isCorrectType = ctrl != null && ctrl.GetType () == editType;
+                       if (ctrl != null && !isCorrectType) {
+                               ctrl = null;
                        }
-                       if (autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None) {
-                               throw new ArgumentException("Parameter AutoSieRowsMode cant be None.");
+                       if (ctrl == null) {
+                               ctrl = (Control) Activator.CreateInstance (editType);
+                               EditingControlInternal = ctrl;
                        }
-               }
 
-               public virtual bool BeginEdit (bool selectAll) {
-                       throw new NotImplementedException();
+                       IDataGridViewEditingControl edControl = ctrl as IDataGridViewEditingControl;
+                       DataGridViewCellStyle style = cell.RowIndex == -1 ? DefaultCellStyle : cell.InheritedStyle;
+                       cell.InitializeEditingControl (cell.RowIndex, cell.FormattedValue, style);
+                       
+                       cell.PositionEditingControl (true, true, this.GetCellDisplayRectangle (cell.ColumnIndex, cell.RowIndex, false), bounds, style, false, false, (columns [cell.ColumnIndex].DisplayIndex == 0), (cell.RowIndex == 0));
+                       EditingControlInternal.Visible = true;
+                       
+                       if (edControl != null)
+                               (EditingControlInternal as IDataGridViewEditingControl).PrepareEditingControlForEdit (selectAll);
+
+                       return true;
                }
 
-               public bool CancelEdit () {
-                       throw new NotImplementedException();
+               public bool CancelEdit ()
+               {
+                       if (currentCell != null && currentCell.IsInEditMode) {
+                               currentCell.SetIsInEditMode (false);
+                               currentCell.DetachEditingControl ();
+                               OnCellEndEdit (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
+                       }
+
+                       return true;
                }
 
-               public void ClearSelection () {
-                       foreach (DataGridViewCell cell in SelectedCells) {
+               public void ClearSelection ()
+               {
+                       foreach (DataGridViewColumn col in SelectedColumns)
+                               col.Selected = false;
+                       foreach (DataGridViewRow row in SelectedRows)
+                               row.Selected = false;
+                       foreach (DataGridViewCell cell in SelectedCells)
                                cell.Selected = false;
-                       }
                }
 
-               public bool CommitEdit (DataGridViewDataErrorContexts context) {
-                       throw new NotImplementedException();
+               public bool CommitEdit (DataGridViewDataErrorContexts context)
+               {
+                       if (currentCell != null && currentCell.IsInEditMode) {
+                               IDataGridViewEditingControl ctrl = EditingControl as IDataGridViewEditingControl;
+                               ctrl.GetEditingControlFormattedValue (DataGridViewDataErrorContexts.Commit);
+                               currentCell.Value = ctrl.GetEditingControlFormattedValue (DataGridViewDataErrorContexts.Commit);
+                               return true;
+                       }
+                       
+                       return false;
                }
 
-               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?
+               [MonoTODO ("Always includes partial rows")]
+               public int DisplayedRowCount (bool includePartialRow)
+               {
                        int result = 0;
-                       foreach (DataGridViewRow row in rows) {
-                               if (row.Visible) {
+                       
+                       for (int i = first_row_index; i < Rows.Count; i++)
+                               if (Rows[i].Displayed)
                                        result++;
-                               }
-                       }
+                               else
+                                       break;
+                                       
                        return result;
                }
 
-               public bool EndEdit () {
-                       throw new NotImplementedException();
+               public bool EndEdit ()
+               {
+                       if (currentCell != null && currentCell.IsInEditMode) {
+                               IDataGridViewEditingControl ctrl = EditingControl as IDataGridViewEditingControl;
+                               ctrl.GetEditingControlFormattedValue (DataGridViewDataErrorContexts.Commit);
+                               currentCell.Value = ctrl.GetEditingControlFormattedValue (DataGridViewDataErrorContexts.Commit);
+                               
+                               currentCell.SetIsInEditMode (false);
+                               currentCell.DetachEditingControl ();
+                               OnCellEndEdit (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
+                       }
+                       
+                       return true;
                }
 
-               public bool EndEdit (DataGridViewDataErrorContexts context) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use context parameter")]
+               public bool EndEdit (DataGridViewDataErrorContexts context)
+               {
+                       return EndEdit ();
                }
 
                public int GetCellCount (DataGridViewElementStates includeFilter) {
@@ -2068,115 +2315,446 @@ namespace System.Windows.Forms {
                        return result;
                }
 
+               internal DataGridViewRow GetRowInternal (int rowIndex)
+               {
+                       return Rows.SharedRow (rowIndex);
+               }
+
+               internal DataGridViewCell GetCellInternal (int colIndex, int rowIndex)
+               {
+                       return GetRowInternal (rowIndex).Cells.GetCellInternal (colIndex);
+               }
+
                public Rectangle GetCellDisplayRectangle (int columnIndex, int rowIndex, bool cutOverflow) {
                        if (columnIndex < 0 || columnIndex >= columns.Count) {
                                throw new ArgumentOutOfRangeException("Column index is out of range.");
                        }
-                       throw new NotImplementedException();
-               }
-
-               public virtual DataObject GetClipboardContent () {
-                       throw new NotImplementedException();
-               }
+                       
+                       int x = 0, y = 0, w = 0, h = 0;
+                       
+                       x = BorderWidth;
+                       y = BorderWidth;
+                       
+                       if (ColumnHeadersVisible)
+                               y += ColumnHeadersHeight;
+                       
+                       if (RowHeadersVisible)
+                               x += RowHeadersWidth;
 
-               public Rectangle GetColumnDisplayRectangle (int columnIndex, bool cutOverflow) {
-                       throw new NotImplementedException();
-               }
+                       List<DataGridViewColumn> cols = columns.ColumnDisplayIndexSortedArrayList;
 
-               public Rectangle GetRowDisplayRectangle (int rowIndex, bool cutOverflow) {
-                       throw new NotImplementedException();
-               }
+                       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;
+                               }
 
-               public HitTestInfo HitTest (int x, int y) {
-                       ///////////////////////////////////////////////////////
-                       x += horizontalScrollingOffset;
-                       y += verticalScrollingOffset;
-                       int rowIndex = -1;
-                       int totalHeight = (columnHeadersVisible)? 1 + columnHeadersHeight : 1;
-                       if (columnHeadersVisible && y <= totalHeight) {
-                               rowIndex = -1;
+                               x += cols[i].Width;
                        }
-                       else {
-                               foreach (DataGridViewRow row in rows.RowIndexSortedArrayList) {
-                                       totalHeight += row.Height;
-                                       if (y <= totalHeight) {
-                                               rowIndex = row.Index;
-                                               break;
-                                       }
-                                       totalHeight++; // sumar el ancho de las lineas...
+                       
+                       for (int i = first_row_index; i < Rows.Count; i++) {
+                               if (i == rowIndex) {
+                                       h = rows [i].Height;
+                                       break;
                                }
+                               
+                               y += rows [i].Height;
                        }
-                       int colIndex = -1;
-                       int totalWidth = (rowHeadersVisible)? 1 + rowHeadersWidth : 1;
-                       if (rowHeadersVisible && x <= totalWidth) {
-                               colIndex = -1;
+                       
+                       return new Rectangle (x, y, w, h);
+               }
+
+               public virtual DataObject GetClipboardContent () {
+                       
+                       if (clipboardCopyMode == DataGridViewClipboardCopyMode.Disable)
+                               throw new InvalidOperationException ("Generating Clipboard content is not supported when the ClipboardCopyMode property is Disable.");
+                       
+                       int start_row = int.MaxValue, end_row = int.MinValue;
+                       int start_col = int.MaxValue, end_col = int.MinValue;
+                       
+                       bool include_row_headers = false;
+                       bool include_col_headers = false;
+                       bool only_included_headers = false;
+                       bool headers_includable = false;
+                       
+                       switch (ClipboardCopyMode) {
+                       case DataGridViewClipboardCopyMode.EnableWithoutHeaderText:
+                               break;
+                       case DataGridViewClipboardCopyMode.EnableWithAutoHeaderText:
+                               // Headers are included if not selection mode is CellSelect, and any header is selected.
+                               headers_includable = selectionMode != DataGridViewSelectionMode.CellSelect;
+                               break;
+                       case DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText:
+                               include_col_headers = include_row_headers = true;
+                               break;
                        }
-                       else {
-                               foreach (DataGridViewColumn col in columns.ColumnDisplayIndexSortedArrayList) {
-                                       totalWidth += col.Width;
-                                       if (x <= totalWidth) {
-                                               colIndex = col.Index;
+                       
+                       BitArray included_rows = new BitArray (RowCount);
+                       BitArray included_cols = new BitArray (ColumnCount);
+                       
+                       // If there are any selected columns,
+                       // include the column headers (if headers are to be shown).
+                       if (headers_includable && !include_col_headers) {
+                               for (int c = 0; c < ColumnCount; c++) {
+                                       if (Columns [c].Selected) {
+                                               include_col_headers = true;
                                                break;
                                        }
-                                       totalWidth++;
                                }
                        }
-                       HitTestInfo result = new HitTestInfo(colIndex, x, rowIndex, y, (colIndex >= 0 && rowIndex >= 0)? DataGridViewHitTestType.Cell : DataGridViewHitTestType.None);
-                       return result;
-               }
-
-               public void InvalidateCell (DataGridViewCell dataGridViewCell) {
-                       if (dataGridViewCell == null) {
-                               throw new ArgumentNullException("Cell is null");
-                       }
-                       if (dataGridViewCell.DataGridView != this) {
-                               throw new ArgumentException("The specified cell does not belong to this DataGridView.");
-                       }
-                       throw new NotImplementedException();
-               }
+                       
+                       // Find the smallest rectangle that encompasses all selected cells.
+                       for (int r = 0; r < RowCount; r++) {
+                               DataGridViewRow row = Rows [r];
 
-               public void InvalidateCell (int columnIndex, int rowIndex) {
-                       if (columnIndex < 0 || columnIndex >= columns.Count) {
-                               throw new ArgumentOutOfRangeException("Column index is out of range.");
-                       }
-                       if (rowIndex < 0 || rowIndex >= rows.Count) {
-                               throw new ArgumentOutOfRangeException("Row index is out of range.");
+                               if (headers_includable && !include_row_headers && row.Selected) {
+                                       include_row_headers = true;
+                               }
+                               
+                               for (int c = 0; c < ColumnCount; c++) {
+                                       DataGridViewCell cell = row.Cells [c];
+                                       
+                                       if (cell == null || !cell.Selected)
+                                               continue;
+                                       
+                                       included_cols [c] = true;
+                                       included_rows [r] = true;
+                                       
+                                       start_row = Math.Min (start_row, r);
+                                       start_col = Math.Min (start_col, c);
+                                       end_row = Math.Max (end_row, r);
+                                       end_col = Math.Max (end_col, c);
+                               }
                        }
-                       foreach (DataGridViewRow row in rows) {
-                               foreach (DataGridViewCell cell in row.Cells) {
-                                       if (cell.RowIndex == rowIndex && cell.ColumnIndex == columnIndex) {
-                                               InvalidateCell(cell); //// O al revés, que el otro llame a este !!!
-                                               return;
+                       
+                       // Mark rows/columns in between selected cells as included if the selection mode isn't FullHeaderSelect.
+                       switch (selectionMode){
+                       case DataGridViewSelectionMode.CellSelect:
+                       case DataGridViewSelectionMode.ColumnHeaderSelect:
+                       case DataGridViewSelectionMode.RowHeaderSelect:
+                               if (selectionMode != DataGridViewSelectionMode.ColumnHeaderSelect) {
+                                       for (int r = start_row; r <= end_row; r++) {
+                                               included_rows.Set (r, true);
+                                       }
+                               } else if (start_row <= end_row) {
+                                       included_rows.SetAll (true);
+                               }
+                               if (selectionMode != DataGridViewSelectionMode.RowHeaderSelect) {
+                                       for (int c = start_col; c <= end_col; c++) {
+                                               included_cols.Set (c, true);
                                        }
                                }
+                               break;
+                       case DataGridViewSelectionMode.FullColumnSelect:
+                       case DataGridViewSelectionMode.FullRowSelect:
+                               only_included_headers = true;
+                               break;
                        }
-               }
-
-               public void InvalidateColumn (int columnIndex) {
-                       if (columnIndex < 0 || columnIndex >= columns.Count) {
-                               throw new ArgumentOutOfRangeException("Column index is out of range.");
+                       
+                       if (start_row > end_row)
+                               return null;
+                               
+                       if (start_col > end_col)
+                               return null;
+                       
+                       DataObject result = new DataObject ();
+                       
+                       System.Text.StringBuilder text_builder = new System.Text.StringBuilder ();
+                       System.Text.StringBuilder utext_builder = new System.Text.StringBuilder ();
+                       System.Text.StringBuilder html_builder = new System.Text.StringBuilder ();
+                       System.Text.StringBuilder csv_builder = new System.Text.StringBuilder ();
+                       
+                       // Loop through all rows and columns to create the content.
+                       // -1 is the header row/column.
+                       int first_row = start_row;
+                       int first_col = start_col;
+                       if (include_col_headers) {
+                               first_row = -1;
                        }
-                       throw new NotImplementedException();
+                       for (int r = first_row; r <= end_row; r++) {
+                               DataGridViewRow row = null;
+                               
+                               if (r >= 0) {
+                                       if (!included_rows [r])
+                                               continue;
+                                               
+                                       row = Rows [r];
+                               }
+
+                               if (include_row_headers) {
+                                       first_col = -1;
+                               }
+                               
+                               for (int c = first_col; c <= end_col; c++) {
+                                       DataGridViewCell cell = null;
+
+                                       if (c >= 0 && only_included_headers && !included_cols [c])
+                                               continue;
+                               
+                                       if (row == null) {
+                                               if (c == -1) {
+                                                       cell = TopLeftHeaderCell;
+                                               } else {
+                                                       cell = Columns [c].HeaderCell;
+                                               }
+                                       } else {
+                                               if (c == -1) {
+                                                       cell = row.HeaderCell;
+                                               } else {
+                                                       cell = row.Cells [c];
+                                               }
+                                       }
+                               
+                                       string text, utext, html, csv;
+                                       bool is_first_cell = (c == first_col);
+                                       bool is_last_cell = (c == end_col);
+                                       bool is_first_row = (r == first_row);
+                                       bool is_last_row = (r == end_row);
+                                       
+                                       if (cell == null) {
+                                               text = string.Empty;
+                                               utext = string.Empty;
+                                               html = string.Empty;
+                                               csv = string.Empty;
+                                       } else {
+                                               text = cell.GetClipboardContentInternal (r, is_first_cell, is_last_cell, is_first_row, is_last_row, DataFormats.Text) as string;
+                                               utext = cell.GetClipboardContentInternal (r, is_first_cell, is_last_cell, is_first_row, is_last_row, DataFormats.UnicodeText) as string;
+                                               html = cell.GetClipboardContentInternal (r, is_first_cell, is_last_cell, is_first_row, is_last_row, DataFormats.Html) as string;
+                                               csv = cell.GetClipboardContentInternal (r, is_first_cell, is_last_cell, is_first_row, is_last_row, DataFormats.CommaSeparatedValue) as string;
+                                       }
+                                       
+                                       text_builder.Append (text);
+                                       utext_builder.Append (utext);
+                                       html_builder.Append (html);
+                                       csv_builder.Append (csv);
+                                       
+                                       if (c == -1) { // If we just did the row header, jump to the first column.
+                                               c = start_col - 1;
+                                       }
+                               }
+
+                               if (r == -1) {// If we just did the column header, jump to the first row.
+                                       r = start_row - 1;
+                               }
+                       }
+
+                       // 
+                       // Html content always get the \r\n newline
+                       // It's valid html anyway, and it eases testing quite a bit
+                       // (since otherwise we'd have to change the start indices
+                       // in the added prologue/epilogue text)
+                       // 
+                       int fragment_end = 135 + html_builder.Length;
+                       int html_end = fragment_end + 36;
+                       string html_start =
+                       "Version:1.0{0}" +
+                       "StartHTML:00000097{0}" +
+                       "EndHTML:{1:00000000}{0}" +
+                       "StartFragment:00000133{0}" +
+                       "EndFragment:{2:00000000}{0}" +
+                       "<HTML>{0}" +
+                       "<BODY>{0}" +
+                       "<!--StartFragment-->";
+                       
+                       html_start = string.Format (html_start, "\r\n", html_end, fragment_end);
+                       html_builder.Insert (0, html_start);
+                       html_builder.AppendFormat ("{0}<!--EndFragment-->{0}</BODY>{0}</HTML>", "\r\n");
+                       
+                       result.SetData (DataFormats.CommaSeparatedValue, false, csv_builder.ToString ());
+                       result.SetData (DataFormats.Html, false, html_builder.ToString ());
+                       result.SetData (DataFormats.UnicodeText, false, utext_builder.ToString ());
+                       result.SetData (DataFormats.Text, false, text_builder.ToString ());
+                       
+                       return result;
+               }
+
+               [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 void InvalidateRow (int rowIndex) {
-                       if (rowIndex < 0 || rowIndex >= rows.Count) {
-                               throw new ArgumentOutOfRangeException("Row index is out of range.");
+               [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;
                        }
-                       throw new NotImplementedException();
+
+                       return new Rectangle (0, y, Width, h);
+               }
+
+               public HitTestInfo HitTest (int x, int y) {
+                       ///////////////////////////////////////////////////////
+                       //Console.WriteLine ("HitTest ({0}, {1})", x, y);
+                       bool isInColHeader = columnHeadersVisible && y >= 0 && y <= ColumnHeadersHeight;
+                       bool isInRowHeader = rowHeadersVisible && x >= 0 && x <= RowHeadersWidth;
+                       
+                       // TopLeftHeader
+                       if (isInColHeader && isInRowHeader)
+                               return new HitTestInfo (-1, x, -1, y, DataGridViewHitTestType.TopLeftHeader);
+                       
+                       // HorizontalScrollBar
+                       if (horizontalScrollBar.Visible && horizontalScrollBar.Bounds.Contains (x, y))
+                               return new HitTestInfo (-1, x, -1, y, DataGridViewHitTestType.HorizontalScrollBar);
+
+                       // VerticalScrollBar
+                       if (verticalScrollBar.Visible && verticalScrollBar.Bounds.Contains (x, y))
+                               return new HitTestInfo (-1, x, -1, y, DataGridViewHitTestType.VerticalScrollBar);
+                       
+                       // The little box in the bottom right if both scrollbars are shown is None
+                       if (verticalScrollBar.Visible && horizontalScrollBar.Visible)
+                               if (new Rectangle (verticalScrollBar.Left, horizontalScrollBar.Top, verticalScrollBar.Width, horizontalScrollBar.Height).Contains (x, y))
+                                       return new HitTestInfo (-1, x, -1, y, DataGridViewHitTestType.None);
+                       
+                       int rowindex = -1;
+                       int colindex = -1;
+                       
+                       int top = columnHeadersVisible ? columnHeadersHeight : 0;
+                       
+                       for (int i = first_row_index; i < Rows.Count; i++) {
+                               DataGridViewRow row = Rows[i];
+                               
+                               if (y > top && y <= (top + row.Height)) {
+                                       rowindex = i;
+                                       break;
+                               }
+                               
+                               top += row.Height;
+                       }
+                       
+                       int left = rowHeadersVisible ? RowHeadersWidth : 0;
+
+                       List<DataGridViewColumn> cols = columns.ColumnDisplayIndexSortedArrayList;
+                       
+                       for (int i = first_col_index; i < cols.Count; i++) {
+                               if (!cols[i].Visible)
+                                       continue;
+                                       
+                               if (x > left && x <= (left + cols[i].Width)) {
+                                       colindex = cols[i].Index;
+                                       break;
+                               }
+
+                               left += cols[i].Width;
+                       }
+
+                       if (colindex >= 0 && rowindex >= 0)
+                               return new HitTestInfo (colindex, x, rowindex, y, DataGridViewHitTestType.Cell);
+                       
+                       if (isInColHeader && colindex > -1)
+                               return new HitTestInfo (colindex, x, rowindex, y, DataGridViewHitTestType.ColumnHeader);
+                       
+                       if (isInRowHeader && rowindex > -1)
+                               return new HitTestInfo (colindex, x, rowindex, y, DataGridViewHitTestType.RowHeader);
+                               
+                       return new HitTestInfo (-1, x, -1, y, DataGridViewHitTestType.None);
+               }
+
+               [MonoTODO ("Invalidates whole grid")]
+               public void InvalidateCell (DataGridViewCell dataGridViewCell)
+               {
+                       if (dataGridViewCell == null)
+                               throw new ArgumentNullException ("Cell is null");
+
+                       if (dataGridViewCell.DataGridView != this)
+                               throw new ArgumentException ("The specified cell does not belong to this DataGridView.");
+
+                       InvalidateCell (dataGridViewCell.ColumnIndex, dataGridViewCell.RowIndex);
+               }
+
+               [MonoTODO ("Invalidates whole grid")]
+               public void InvalidateCell (int columnIndex, int rowIndex)
+               {
+                       if (columnIndex < 0 || columnIndex >= columns.Count)
+                               throw new ArgumentOutOfRangeException ("Column index is out of range.");
+
+                       if (rowIndex < 0 || rowIndex >= rows.Count)
+                               throw new ArgumentOutOfRangeException ("Row index is out of range.");
+
+                       Invalidate (GetCellDisplayRectangle (columnIndex, rowIndex, true));
+               }
+
+               [MonoTODO ("Invalidates whole grid")]
+               public void InvalidateColumn (int columnIndex)
+               {
+                       if (columnIndex < 0 || columnIndex >= columns.Count)
+                               throw new ArgumentOutOfRangeException ("Column index is out of range.");
+
+                       Invalidate (GetColumnDisplayRectangle (columnIndex, true));
+               }
+
+               [MonoTODO ("Invalidates whole grid")]
+               public void InvalidateRow (int rowIndex)
+               {
+                       if (rowIndex < 0 || rowIndex >= rows.Count)
+                               throw new ArgumentOutOfRangeException ("Row index is out of range.");
+
+                       Invalidate (GetRowDisplayRectangle (rowIndex, true));
                }
 
                public virtual void NotifyCurrentCellDirty (bool dirty) {
                        throw new NotImplementedException();
                }
 
-               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 () {
@@ -2199,39 +2777,118 @@ namespace System.Windows.Forms {
                                        }
                                        break;
                        }
+                       
+                       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;
+
+                       EndEdit ();
+
+                       Rows.Sort (comparer);
+                       
+                       sortedColumn = null;
+                       sortOrder = SortOrder.None;
+                       
+                       currentCell = null;
+                       
+                       Invalidate ();
+                       
+                       OnSorted (EventArgs.Empty);
                }
 
+               public virtual void Sort (DataGridViewColumn dataGridViewColumn, ListSortDirection direction)
+               {
+                       if (dataGridViewColumn == null)
+                               throw new ArgumentNullException ("dataGridViewColumn");
+                       if (dataGridViewColumn.DataGridView != this)
+                               throw new ArgumentException ("dataGridViewColumn");
+                       // XXX: This is thrown too much, disable for now..
+                       //if (DataSource != null && !dataGridViewColumn.IsDataBound)
+                       //        throw new ArgumentException ("dataGridViewColumn");
+                       if (VirtualMode && !dataGridViewColumn.IsDataBound)
+                               throw new InvalidOperationException ();
+
+                       if (SortedColumn != null)
+                               SortedColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
+
+                       EndEdit ();
+                       
+                       ColumnSorter sorter = new ColumnSorter (dataGridViewColumn, direction);
+                       Rows.Sort (sorter);
+
+                       sortedColumn = dataGridViewColumn;
+                       sortOrder = (SortOrder)direction + 1;
+
+                       dataGridViewColumn.HeaderCell.SortGlyphDirection = (SortOrder)direction + 1;
+
+                       Invalidate ();
+
+                       OnSorted (EventArgs.Empty);
+               }
+               
                public void UpdateCellErrorText (int columnIndex, int rowIndex)
                {
-                       throw new NotImplementedException();
+                       if (columnIndex < 0 || columnIndex > Columns.Count - 1)
+                               throw new ArgumentOutOfRangeException ("columnIndex");
+                       if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+                               throw new ArgumentOutOfRangeException ("rowIndex");
+
+                       InvalidateCell (columnIndex, rowIndex);
                }
 
                public void UpdateCellValue (int columnIndex, int rowIndex)
                {
-                       throw new NotImplementedException();
+                       if (columnIndex < 0 || columnIndex > Columns.Count - 1)
+                               throw new ArgumentOutOfRangeException ("columnIndex");
+                       if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+                               throw new ArgumentOutOfRangeException ("rowIndex");
+                       
+                       InvalidateCell (columnIndex, rowIndex);
                }
 
                public void UpdateRowErrorText (int rowIndex)
                {
-                       throw new NotImplementedException();
+                       if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+                               throw new ArgumentOutOfRangeException ("rowIndex");
+
+                       InvalidateRow (rowIndex);
                }
 
-               public void UpdateRowErrorText (int rowIndexStart, int rowIndexEnd) {
-                       throw new NotImplementedException();
+               public void UpdateRowErrorText (int rowIndexStart, int rowIndexEnd)
+               {
+                       if (rowIndexStart < 0 || rowIndexStart > Rows.Count - 1)
+                               throw new ArgumentOutOfRangeException ("rowIndexStart");
+                       if (rowIndexEnd < 0 || rowIndexEnd > Rows.Count - 1)
+                               throw new ArgumentOutOfRangeException ("rowIndexEnd");
+                       if (rowIndexEnd < rowIndexStart)
+                               throw new ArgumentOutOfRangeException ("rowIndexEnd", "rowIndexEnd must be greater than rowIndexStart");
+                               
+                       for (int i = rowIndexStart; i <= rowIndexEnd; i++)
+                               InvalidateRow (i);
                }
 
                public void UpdateRowHeightInfo (int rowIndex, bool updateToEnd) {
                        throw new NotImplementedException();
                }
 
+               protected override bool CanEnableIme {
+                       get {
+                               if (CurrentCell != null && CurrentCell.EditType != null)
+                                       return true;
+                               
+                               return false;
+                       }
+               }
+
                protected override Size DefaultSize {
                        get { return new Size (240, 150); }
                }
@@ -2249,40 +2906,108 @@ 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) {
-                       throw new NotImplementedException();
+                       for (int i = 0; i < Columns.Count; i++) {
+                               AutoResizeColumn (i, (DataGridViewAutoSizeColumnMode) autoSizeColumnsMode, fixedHeight);
+                       }
                }
 
-               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)
+               {
+                       AutoResizeRow (rowIndex, autoSizeRowMode);
                }
 
-               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 fixedMode parameter")]
+               protected void AutoResizeRows (DataGridViewAutoSizeRowsMode autoSizeRowsMode, bool fixedWidth)
+               {
+                       if (autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None)
+                               return;
+                               
+                       bool include_headers = false;
+                       bool include_cells = false;
+                       bool displayed_only = false;
+
+                       switch (autoSizeRowsMode) {
+                               case DataGridViewAutoSizeRowsMode.AllHeaders:
+                                       include_headers = true;
+                                       break;
+                               case DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders:
+                                       include_cells = true;
+                                       break;
+                               case DataGridViewAutoSizeRowsMode.AllCells:
+                                       include_cells = true;
+                                       include_headers = true;
+                                       break;
+                               case DataGridViewAutoSizeRowsMode.DisplayedHeaders:
+                                       include_headers = true;
+                                       displayed_only = true;
+                                       break;
+                               case DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders:
+                                       include_cells = true;
+                                       displayed_only = true;
+                                       break;
+                               case DataGridViewAutoSizeRowsMode.DisplayedCells:
+                                       include_cells = true;
+                                       include_headers = true;
+                                       displayed_only = true;
+                                       break;
+                       }
+                       
+                       foreach (DataGridViewRow row in Rows) {
+                               int new_height = 0;
+                               
+                               if (include_headers)
+                                       if (!displayed_only || row.HeaderCell.Displayed)
+                                               new_height = Math.Max (new_height, row.HeaderCell.PreferredSize.Height);
+
+                               if (include_cells)
+                                       foreach (DataGridViewCell cell in row.Cells)
+                                               if (!displayed_only || cell.Displayed)
+                                                       new_height = Math.Max (new_height, cell.PreferredSize.Height);
+                               
+                               new_height = Math.Max (new_height, row.MinimumHeight);
+                               
+                               if (row.Height != new_height)
+                                       row.Height = 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) {
@@ -2318,7 +3043,7 @@ namespace System.Windows.Forms {
                                                if (selectExceptionElement && row.Index == rowIndexException) {
                                                        continue;
                                                }
-                                               row.Selected = false;
+                                               SetSelectedRowCore (row.Index, false);
                                        }
                                        break;
                                case DataGridViewSelectionMode.FullColumnSelect:
@@ -2326,7 +3051,7 @@ namespace System.Windows.Forms {
                                                if (selectExceptionElement && col.Index == columnIndexException) {
                                                        continue;
                                                }
-                                               col.Selected = false;
+                                               SetSelectedColumnCore (col.Index, false);
                                        }
                                        break;
                                default:
@@ -2334,7 +3059,7 @@ namespace System.Windows.Forms {
                                                if (selectExceptionElement && cell.RowIndex == rowIndexException && cell.ColumnIndex == columnIndexException) {
                                                        continue;
                                                }
-                                               cell.Selected = false;
+                                               SetSelectedCellCore (cell.ColumnIndex, cell.RowIndex, false);
                                        }
                                        break;
                        }
@@ -2372,12 +3097,32 @@ namespace System.Windows.Forms {
 
                protected override bool IsInputChar (char charCode)
                {
-                       return base.IsInputChar(charCode);
+                       return true;
                }
 
                protected override bool IsInputKey (Keys keyData)
                {
-                       return base.IsInputKey(keyData);
+                       // Don't look at the modifiers
+                       keyData = keyData & ~Keys.Modifiers;
+                       
+                       switch (keyData) {
+                               case Keys.Return:
+                               case Keys.PageUp:
+                               case Keys.Next:
+                               case Keys.End:
+                               case Keys.Home:
+                               case Keys.Left:
+                               case Keys.Up:
+                               case Keys.Right:
+                               case Keys.Down:
+                               case Keys.Delete:
+                               case Keys.D0:
+                               case Keys.NumPad0:
+                               case Keys.F2:
+                                       return true;
+                       }
+
+                       return false;
                }
 
                protected virtual void OnAllowUserToAddRowsChanged (EventArgs e)
@@ -2491,6 +3236,10 @@ namespace System.Windows.Forms {
 
                protected virtual void OnCellClick (DataGridViewCellEventArgs e)
                {
+                       DataGridViewCell cell = GetCellInternal (e.ColumnIndex, e.RowIndex);
+
+                       cell.OnClickInternal (e);
+       
                        DataGridViewCellEventHandler eh = (DataGridViewCellEventHandler)(Events [CellClickEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -2498,6 +3247,10 @@ namespace System.Windows.Forms {
 
                protected virtual void OnCellContentClick (DataGridViewCellEventArgs e)
                {
+                       DataGridViewCell cell = GetCellInternal (e.ColumnIndex, e.RowIndex);
+
+                       cell.OnContentClickInternal (e);
+                       
                        DataGridViewCellEventHandler eh = (DataGridViewCellEventHandler)(Events [CellContentClickEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -2505,6 +3258,10 @@ namespace System.Windows.Forms {
 
                protected virtual void OnCellContentDoubleClick (DataGridViewCellEventArgs e)
                {
+                       DataGridViewCell cell = GetCellInternal (e.ColumnIndex, e.RowIndex);
+
+                       cell.OnContentDoubleClickInternal (e);
+                       
                        DataGridViewCellEventHandler eh = (DataGridViewCellEventHandler)(Events [CellContentDoubleClickEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -2526,6 +3283,9 @@ namespace System.Windows.Forms {
 
                protected virtual void OnCellDoubleClick (DataGridViewCellEventArgs e)
                {
+                       DataGridViewCell cell = GetCellInternal (e.ColumnIndex, e.RowIndex);
+
+                       cell.OnDoubleClickInternal (e);
                        DataGridViewCellEventHandler eh = (DataGridViewCellEventHandler)(Events [CellDoubleClickEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -2559,6 +3319,11 @@ namespace System.Windows.Forms {
                                eh (this, e);
                }
 
+               internal void OnCellFormattingInternal (DataGridViewCellFormattingEventArgs e)
+               {
+                       OnCellFormatting (e);
+               }
+
                protected virtual void OnCellFormatting (DataGridViewCellFormattingEventArgs e)
                {
                        DataGridViewCellFormattingEventHandler eh = (DataGridViewCellFormattingEventHandler)(Events [CellFormattingEvent]);
@@ -2575,6 +3340,10 @@ namespace System.Windows.Forms {
 
                protected virtual void OnCellMouseClick (DataGridViewCellMouseEventArgs e)
                {
+                       DataGridViewCell cell = GetCellInternal (e.ColumnIndex, e.RowIndex);
+
+                       cell.OnMouseClickInternal (e);
+                       
                        DataGridViewCellMouseEventHandler eh = (DataGridViewCellMouseEventHandler)(Events [CellMouseClickEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -2582,6 +3351,10 @@ namespace System.Windows.Forms {
 
                protected virtual void OnCellMouseDoubleClick (DataGridViewCellMouseEventArgs e)
                {
+                       DataGridViewCell cell = GetCellInternal (e.ColumnIndex, e.RowIndex);
+
+                       cell.OnMouseDoubleClickInternal (e);
+                       
                        DataGridViewCellMouseEventHandler eh = (DataGridViewCellMouseEventHandler)(Events [CellMouseDoubleClickEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -2589,6 +3362,11 @@ namespace System.Windows.Forms {
 
                protected virtual void OnCellMouseDown (DataGridViewCellMouseEventArgs e)
                {
+
+                       DataGridViewCell cell = GetCellInternal (e.ColumnIndex, e.RowIndex);
+
+                       cell.OnMouseDownInternal (e);
+                       
                        DataGridViewCellMouseEventHandler eh = (DataGridViewCellMouseEventHandler)(Events [CellMouseDownEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -2596,6 +3374,10 @@ namespace System.Windows.Forms {
 
                protected virtual void OnCellMouseEnter (DataGridViewCellEventArgs e)
                {
+                       DataGridViewCell cell = GetCellInternal (e.ColumnIndex, e.RowIndex);
+
+                       cell.OnMouseEnterInternal (e.RowIndex);
+                       
                        DataGridViewCellEventHandler eh = (DataGridViewCellEventHandler)(Events [CellMouseEnterEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -2603,6 +3385,10 @@ namespace System.Windows.Forms {
 
                protected virtual void OnCellMouseLeave (DataGridViewCellEventArgs e)
                {
+                       DataGridViewCell cell = GetCellInternal (e.ColumnIndex, e.RowIndex);
+
+                       cell.OnMouseLeaveInternal (e.RowIndex);
+                       
                        DataGridViewCellEventHandler eh = (DataGridViewCellEventHandler)(Events [CellMouseLeaveEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -2610,6 +3396,10 @@ namespace System.Windows.Forms {
 
                protected virtual void OnCellMouseMove (DataGridViewCellMouseEventArgs e)
                {
+                       DataGridViewCell cell = GetCellInternal (e.ColumnIndex, e.RowIndex);
+                       
+                       cell.OnMouseMoveInternal (e);
+               
                        DataGridViewCellMouseEventHandler eh = (DataGridViewCellMouseEventHandler)(Events [CellMouseMoveEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -2617,11 +3407,20 @@ namespace System.Windows.Forms {
 
                protected virtual void OnCellMouseUp (DataGridViewCellMouseEventArgs e)
                {
+                       DataGridViewCell cell = GetCellInternal (e.ColumnIndex, e.RowIndex);
+
+                       cell.OnMouseUpInternal (e);
+                       
                        DataGridViewCellMouseEventHandler eh = (DataGridViewCellMouseEventHandler)(Events [CellMouseUpEvent]);
                        if (eh != null)
                                eh (this, e);
                }
 
+               internal void OnCellPaintingInternal (DataGridViewCellPaintingEventArgs e)
+               {
+                       OnCellPainting (e);
+               }
+
                protected virtual void OnCellPainting (DataGridViewCellPaintingEventArgs e)
                {
                        DataGridViewCellPaintingEventHandler eh = (DataGridViewCellPaintingEventHandler)(Events [CellPaintingEvent]);
@@ -2704,6 +3503,20 @@ namespace System.Windows.Forms {
                                eh (this, e);
                }
 
+               internal void OnColumnAddedInternal (DataGridViewColumnEventArgs e)
+               {
+                       if (e.Column.CellTemplate != null) {
+                               RowTemplate.Cells.Add ((DataGridViewCell)e.Column.CellTemplate.Clone ());
+
+                               foreach (DataGridViewRow row in Rows)
+                                       row.Cells.Add ((DataGridViewCell)RowTemplate.Cells[RowTemplate.Cells.Count - 1].Clone ());
+                       }
+                       
+                       AutoResizeColumnsInternal ();
+                       OnColumnAdded (e);
+                       PrepareEditingRow (false, true);
+               }
+
                protected virtual void OnColumnAdded (DataGridViewColumnEventArgs e)
                {
                        DataGridViewColumnEventHandler eh = (DataGridViewColumnEventHandler)(Events [ColumnAddedEvent]);
@@ -2762,6 +3575,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);
@@ -2877,16 +3705,14 @@ namespace System.Windows.Forms {
                                eh (this, e);
                }
 
-               protected virtual void OnDataError (bool displayErrorDialogIfNoHandler, DataGridViewDataErrorEventArgs e) {
+               protected virtual void OnDataError (bool displayErrorDialogIfNoHandler, DataGridViewDataErrorEventArgs e)
+               {
                        DataGridViewDataErrorEventHandler eh = (DataGridViewDataErrorEventHandler)(Events [DataErrorEvent]);
-                       if (eh != null) {
+                       
+                       if (eh != null)
                                eh (this, e);
-                       }
-                       else {
-                               if (displayErrorDialogIfNoHandler) {
-                                       /////////////////////////////////// ERROR DIALOG //////////////////////////////////7
-                               }
-                       }
+                       else if (displayErrorDialogIfNoHandler)
+                               MessageBox.Show (e.ToString ());
                }
                protected virtual void OnDataMemberChanged (EventArgs e) {
                        EventHandler eh = (EventHandler)(Events [DataMemberChangedEvent]);
@@ -2942,6 +3768,10 @@ namespace System.Windows.Forms {
                protected override void OnGotFocus(EventArgs e)
                {
                        base.OnGotFocus (e);
+
+                       // To add focus rectangle if needed
+                       if (currentCell != null && ShowFocusCues)
+                               InvalidateCell (currentCell);
                }
 
                protected override void OnFontChanged (EventArgs e)
@@ -2964,6 +3794,9 @@ namespace System.Windows.Forms {
                protected override void OnHandleCreated (EventArgs e)
                {
                        base.OnHandleCreated(e);
+                       
+                       if (Rows.Count > 0 && Columns.Count > 0)
+                               MoveCurrentCell (ColumnDisplayIndexToIndex (0), 0, true, false, false, false);
                }
 
                protected override void OnHandleDestroyed(EventArgs e)
@@ -2974,7 +3807,9 @@ namespace System.Windows.Forms {
                [EditorBrowsable (EditorBrowsableState.Advanced)]
                protected override void OnKeyDown (KeyEventArgs e)
                {
-                       base.OnKeyDown(e);
+                       base.OnKeyDown (e);
+
+                       e.Handled = ProcessDataGridViewKey (e);
                }
 
                [EditorBrowsable (EditorBrowsableState.Advanced)]
@@ -2991,7 +3826,15 @@ namespace System.Windows.Forms {
 
                protected override void OnLayout (LayoutEventArgs e)
                {
-                       base.OnLayout(e);
+                       if (horizontalScrollBar.Visible && verticalScrollBar.Visible) {
+                               horizontalScrollBar.Bounds = new Rectangle (BorderWidth, Height - BorderWidth - horizontalScrollBar.Height, Width - (2 * BorderWidth) - verticalScrollBar.Width, horizontalScrollBar.Height);
+                               verticalScrollBar.Bounds = new Rectangle (Width - BorderWidth - verticalScrollBar.Width, BorderWidth, verticalScrollBar.Width, Height - (2 * BorderWidth) - horizontalScrollBar.Height);
+                       } else if (horizontalScrollBar.Visible)
+                               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));
+                               
+                       Invalidate ();
                }
 
                protected override void OnLeave (EventArgs e)
@@ -3002,12 +3845,41 @@ namespace System.Windows.Forms {
                protected override void OnLostFocus(EventArgs e)
                {
                        base.OnLostFocus (e);
+
+                       // To remove focus rectangle if needed
+                       if (currentCell != null && ShowFocusCues)
+                               InvalidateCell (currentCell);
                }
 
                protected override void OnMouseClick (MouseEventArgs e)
                {
                        base.OnMouseClick(e);
                        //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);
+                                       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);
+                                               cell.OnContentClickInternal (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;
+                       }
                }
 
                protected override void OnMouseDoubleClick (MouseEventArgs e)
@@ -3015,50 +3887,187 @@ namespace System.Windows.Forms {
                        base.OnMouseDoubleClick(e);
                }
 
-               protected override void OnMouseDown (MouseEventArgs e)
+               private void DoSelectionOnMouseDown (HitTestInfo hitTest)
                {
-                       base.OnMouseDown(e);
-                       //Console.WriteLine("Mouse: Clicks: {0}; Delta: {1}; X: {2}; Y: {3};", e.Clicks, e.Delta, e.X, e.Y);
-                       HitTestInfo hitTest = HitTest(e.X, e.Y);
-                       //Console.WriteLine("HitTest: Column: {0}; Row: {1};", hitTest.ColumnIndex, hitTest.RowIndex);
-                       if (hitTest.RowIndex < 0 || hitTest.ColumnIndex < 0) {
+                       Keys modifiers = Control.ModifierKeys;
+                       bool isControl = (modifiers & Keys.Control) != 0;
+                       bool isShift = (modifiers & Keys.Shift) != 0;
+                       //bool isRowHeader = hitTest.Type == DataGridViewHitTestType.RowHeader;
+                       //bool isColHeader = hitTest.Type == DataGridViewHitTestType.ColumnHeader;
+                       DataGridViewSelectionMode mode;
+                       
+                       switch (hitTest.Type) {
+                       case DataGridViewHitTestType.Cell:
+                               mode = selectionMode;
+                               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;
                        }
-                       OnCellClick(new DataGridViewCellEventArgs(hitTest.ColumnIndex, hitTest.RowIndex));
-                       DataGridViewRow row = rows[hitTest.RowIndex];
-                       DataGridViewCell cell = row.Cells[hitTest.ColumnIndex];
-                       ClearSelection(0, 0, false);
-                       switch (selectionMode) {
+                       
+                       if (!isControl) {
+                               // If SHIFT is pressed:
+                               //      Select all from selected_row/column/cell to current row/column/cell, unselect everything else
+                               // otherwise:
+                               //      Unselect all rows/columns/cells, select the clicked one
+                               int min_row, max_row;
+                               int min_col, max_col;
+                               if (!isShift) {
+                                       selected_row = hitTest.RowIndex;
+                                       selected_column = hitTest.ColumnIndex;
+                               } 
+                               if (!isShift) {
+                                       if (selected_row != -1)
+                                               selected_row = hitTest.RowIndex;
+                                       if (selected_column != -1)
+                                               selected_column = hitTest.ColumnIndex;
+                               }
+                               if (selected_row >= hitTest.RowIndex) {
+                                       min_row = hitTest.RowIndex;
+                                       max_row = isShift ? selected_row : min_row;
+                               } else {
+                                       max_row = hitTest.RowIndex;
+                                       min_row = isShift ? selected_row : max_row;
+                               }
+                               if (selected_column >= hitTest.ColumnIndex) {
+                                       min_col = hitTest.ColumnIndex;
+                                       max_col = isShift ? selected_column : min_col;
+                               } else {
+                                       max_col = hitTest.ColumnIndex;
+                                       min_col = isShift ? selected_column : max_col;
+                               }
+
+                               switch (mode) {
                                case DataGridViewSelectionMode.FullRowSelect:
-                                       row.Selected = true;
+                                       for (int i = 0; i < RowCount; i++) {
+                                               bool select = i >= min_row && i <= max_row;
+                                               if (!select) {
+                                                       for (int c = 0; c < ColumnCount; c++) {
+                                                               if (Rows [i].Cells [c].Selected) {
+                                                                       SetSelectedCellCore (c, i, false);
+                                                               }
+                                                       }
+                                               }
+                                               if (select != Rows [i].Selected) {
+                                                       SetSelectedRowCore (i, select);
+                                               }
+                                       }
                                        break;
                                case DataGridViewSelectionMode.FullColumnSelect:
-                                       //////////////////
-                                       break;
-                               default:
-                                       cell.Selected = true;
+                                       for (int i = 0; i < ColumnCount; i++) {
+                                               bool select = i >= min_col && i <= max_col;
+                                               if (!select) {
+                                                       for (int r = 0; r < RowCount; r++) {
+                                                               if (Rows [r].Cells [i].Selected) {
+                                                                       SetSelectedCellCore (i, r, false);
+                                                               }
+                                                       }
+                                               }
+                                               if (select != Columns [i].Selected) {
+                                                       SetSelectedColumnCore (i, select);
+                                               }
+                                       }
+                                       break;
+                               case DataGridViewSelectionMode.ColumnHeaderSelect:
+                               case DataGridViewSelectionMode.RowHeaderSelect:
+                                       //break;
+                               case DataGridViewSelectionMode.CellSelect:
+                                       if (!isShift) {
+                                               for (int c = 0; c < ColumnCount; c++) {
+                                                       if (columns [c].Selected)
+                                                               SetSelectedColumnCore (c, false);
+                                               }
+                                               
+                                               for (int r = 0; r < RowCount; r++) {
+                                                       if (rows [r].Selected)
+                                                               SetSelectedRowCore (r, false);
+                                               }
+                                       }
+                                       for (int r = 0; r < RowCount; r++) {
+                                               for (int c = 0; c < ColumnCount; c++) {
+                                                       bool select = (r >= min_row && r <= max_row) && (c >= min_col && c <= max_col);
+                                                       if (select != Rows [r].Cells [c].Selected)
+                                                               SetSelectedCellCore (c, r, select);
+                                               }
+                                       }
+                                       break;
+                               }
+                               
+                       } else if (isControl) {
+                               // Switch the selected state of the row.
+                               switch (mode) {
+                               case DataGridViewSelectionMode.FullRowSelect:
+                                       SetSelectedRowCore (hitTest.RowIndex, !rows [hitTest.RowIndex].Selected);
                                        break;
+                               case DataGridViewSelectionMode.FullColumnSelect:
+                                       SetSelectedColumnCore (hitTest.ColumnIndex, !columns [hitTest.ColumnIndex].Selected);
+                                       break;
+                               case DataGridViewSelectionMode.ColumnHeaderSelect:
+                               case DataGridViewSelectionMode.RowHeaderSelect:
+                                       //break;
+                               case DataGridViewSelectionMode.CellSelect:
+                                       if (hitTest.ColumnIndex >= 0 && hitTest.RowIndex >= 0) {
+                                               SetSelectedCellCore (hitTest.ColumnIndex, hitTest.RowIndex, !Rows [hitTest.RowIndex].Cells [hitTest.ColumnIndex].Selected);
+                                       }
+                                       break;
+                               }
                        }
-                       if (cell == currentCell) {
-                               currentCell.SetIsInEditMode(true);
-                               OnCellBeginEdit(new DataGridViewCellCancelEventArgs(currentCell.ColumnIndex, currentCell.RowIndex));
-                               Invalidate();
+                       
+               }
+
+               protected override void OnMouseDown (MouseEventArgs e)
+               {
+                       base.OnMouseDown(e);
+                       
+                       HitTestInfo hitTest = HitTest(e.X, e.Y);
+                       
+                       DataGridViewCell cell = null;
+                       DataGridViewRow row = null;
+                       Rectangle cellBounds;
+
+                       if (hitTest.Type == DataGridViewHitTestType.Cell) {
+                               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 (currentCell != null) {
-                               if (currentCell.IsInEditMode) {
-                                       currentCell.SetIsInEditMode(false);
-                                       currentCell.DetachEditingControl();
-                                       OnCellEndEdit(new DataGridViewCellEventArgs(currentCell.ColumnIndex, currentCell.RowIndex));
-                               }
+                       
+                       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) {
-                               currentCell.SetIsInEditMode(true);
-                               OnCellBeginEdit(new DataGridViewCellCancelEventArgs(currentCell.ColumnIndex, currentCell.RowIndex));
+                               BeginEdit (true);
                        }
                        Invalidate();
                        return;
@@ -3071,17 +4080,145 @@ 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);
+                       
+                       HitTestInfo hit = this.HitTest (e.X, e.Y);
+                       
+                       if (hit.Type == DataGridViewHitTestType.Cell) {
+                               EnteredHeaderCell = null;
+
+                               DataGridViewCell new_cell = GetCellInternal (hit.ColumnIndex, hit.RowIndex);
+                               
+                               // Check if we have moved into an error icon area
+                               Rectangle icon = new_cell.ErrorIconBounds;
+
+                               if (!icon.IsEmpty) {
+                                       Point loc = GetCellDisplayRectangle (hit.ColumnIndex, hit.RowIndex, false).Location;
+                                       
+                                       icon.X += loc.X;
+                                       icon.Y += loc.Y;
+                                       
+                                       if (icon.Contains (e.X, e.Y)) {
+                                               if (tooltip_currently_showing != new_cell)
+                                                       MouseEnteredErrorIcon (new_cell);
+                                       } else
+                                               MouseLeftErrorIcon (new_cell);
+                               }
+                               
+                               // We have never been in a cell before
+                               if (hover_cell == null) {
+                                       hover_cell = new_cell;
+                                       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;
+                               }
+                       
+                               // 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;
+
+                               // Check if we have moved into an error icon area
+                               Rectangle icon = new_cell.InternalErrorIconsBounds;
+
+                               if (!icon.IsEmpty) {
+                                       Point loc = GetCellDisplayRectangle (0, hit.RowIndex, false).Location;
+
+                                       icon.X += BorderWidth;
+                                       icon.Y += loc.Y;
+
+                                       if (icon.Contains (e.X, e.Y)) {
+                                               if (tooltip_currently_showing != new_cell)
+                                                       MouseEnteredErrorIcon (new_cell);
+                                       } else
+                                               MouseLeftErrorIcon (new_cell);
+                               }
+                       } else if (hit.Type == DataGridViewHitTestType.TopLeftHeader) {
+                               EnteredHeaderCell = null;
+
+                               DataGridViewTopLeftHeaderCell new_cell = (DataGridViewTopLeftHeaderCell)TopLeftHeaderCell;
+
+                               // Check if we have moved into an error icon area
+                               Rectangle icon = new_cell.InternalErrorIconsBounds;
+
+                               if (!icon.IsEmpty) {
+                                       Point loc = Point.Empty;
+
+                                       icon.X += BorderWidth;
+                                       icon.Y += loc.Y;
+
+                                       if (icon.Contains (e.X, e.Y)) {
+                                               if (tooltip_currently_showing != new_cell)
+                                                       MouseEnteredErrorIcon (new_cell);
+                                       } else
+                                               MouseLeftErrorIcon (new_cell);
+                               }
+                       
+                       } else {
+                               if (hit.Type == DataGridViewHitTestType.ColumnHeader)
+                                       EnteredHeaderCell = Columns [hit.ColumnIndex].HeaderCell;
+                               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;
+                               }
+                       }
                }
 
                protected override void OnMouseUp (MouseEventArgs e)
                {
                        base.OnMouseUp(e);
+
+                       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)
@@ -3100,93 +4237,130 @@ namespace System.Windows.Forms {
                        if (eh != null) eh (this, e);
                }
 
-               protected override void OnPaint (PaintEventArgs e) {
+               int first_row_index = 0;
+               internal int first_col_index = 0;
+
+               protected override void OnPaint (PaintEventArgs e)
+               {
                        base.OnPaint(e);
-                       //Console.WriteLine("DataGridView.OnPaint-ClipRectangle: {0};", e.ClipRectangle);
-                       Rectangle bounds = ClientRectangle; //e.ClipRectangle;
-                       e.Graphics.FillRectangle(new SolidBrush(backgroundColor), bounds);
-                       Pen pen = new Pen(gridColor);
-                       pen.Width = 1;
-                       int i = 0;
-                       ArrayList sortedColumns = columns.ColumnDisplayIndexSortedArrayList;
-                       bounds.Y = -verticalScrollingOffset;
-                       bounds.X = -horizontalScrollingOffset;
-                       gridWidth = 0;
-                       foreach (DataGridViewColumn col in sortedColumns) {
-                               gridWidth += col.Width;
+
+                       Graphics g = e.Graphics;
+                       Rectangle bounds = ClientRectangle;
+                       
+                       // Paint the background
+                       PaintBackground (g, e.ClipRectangle, bounds);
+
+                       List<DataGridViewColumn> sortedColumns = columns.ColumnDisplayIndexSortedArrayList;
+                       
+                       // Take borders into account
+                       bounds.Inflate (-BorderWidth, -BorderWidth);
+                       
+                       // Paint the top left cell
+                       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);
                        }
+                       
+                       // Paint the column headers
                        if (columnHeadersVisible) {
                                Rectangle headerBounds = bounds;
-                               if (rowHeadersVisible) {
-                                       headerBounds.X += rowHeadersWidth;
-                               }
                                headerBounds.Height = columnHeadersHeight;
-                               int j = 0;
-                               foreach (DataGridViewColumn col in sortedColumns) {
+                               
+                               if (rowHeadersVisible)
+                                       headerBounds.X += rowHeadersWidth;
+                               
+                               for (int index = first_col_index; index < sortedColumns.Count; index++) {
+                                       DataGridViewColumn col = sortedColumns[index];
+                                       
+                                       if (!col.Visible)
+                                               continue;
+                                       
                                        headerBounds.Width = col.Width;
                                        DataGridViewCell cell = col.HeaderCell;
-                                       DataGridViewCellStyle style = columnHeadersDefaultCellStyle;
-                                       DataGridViewAdvancedBorderStyle intermediateBorderStyle = (DataGridViewAdvancedBorderStyle) ((ICloneable)this.AdvancedColumnHeadersBorderStyle).Clone();
-                                       DataGridViewAdvancedBorderStyle borderStyle = AdjustColumnHeaderBorderStyle(this.AdvancedColumnHeadersBorderStyle, intermediateBorderStyle, j == 0, j == columns.Count - 1);
-                                       cell.InternalPaint(e.Graphics, e.ClipRectangle, headerBounds, cell.RowIndex, cell.State, cell.Value, cell.FormattedValue, cell.ErrorText, style, borderStyle, DataGridViewPaintParts.All);
+
+                                       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);
+                                       
                                        headerBounds.X += col.Width;
-                                       j++;
                                }
+
                                bounds.Y += columnHeadersHeight;
                        }
+                       
+                       gridWidth = rowHeadersVisible ? rowHeadersWidth : 0;
                        gridHeight = 0;
-                       foreach (DataGridViewRow row in rows) {
-                               gridHeight += row.Height;
-                               if (rowHeadersVisible) {
-                                       Rectangle rowHeaderBounds = bounds;
-                                       rowHeaderBounds.Height = row.Height;
-                                       rowHeaderBounds.Width = rowHeadersWidth;
-                                       DataGridViewCell cell = row.HeaderCell;
-                                       DataGridViewCellStyle style = rowHeadersDefaultCellStyle;
-                                       DataGridViewAdvancedBorderStyle intermediateBorderStyle = (DataGridViewAdvancedBorderStyle) ((ICloneable)this.AdvancedRowHeadersBorderStyle).Clone();
-                                       DataGridViewAdvancedBorderStyle borderStyle = cell.AdjustCellBorderStyle(this.AdvancedRowHeadersBorderStyle, intermediateBorderStyle, true, true, false, cell.RowIndex == 0);
-                                       cell.InternalPaint(e.Graphics, e.ClipRectangle, rowHeaderBounds, cell.RowIndex, cell.State, cell.Value, cell.FormattedValue, cell.ErrorText, style, borderStyle, DataGridViewPaintParts.All);
-                                       //e.Graphics.FillRectangle(new SolidBrush(rowHeadersDefaultCellStyle.BackColor), rowHeadersBounds);
-                                       bounds.X += rowHeadersWidth;
-                               }
+                       
+                       int rows_displayed = 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;
-                               for (int j = 0; j < sortedColumns.Count; j++) {
-                                       DataGridViewColumn col = (DataGridViewColumn) sortedColumns[j];
-                                       foreach (DataGridViewCell cell in row.Cells) {
-                                               if (cell.ColumnIndex == col.Index) {
-                                                       bounds.Width = col.Width;
-                                                       cell.SetSize(new Size(bounds.Width, bounds.Height));
-                                                       DataGridViewCellStyle style = cell.InheritedStyle;
-                                                       if (cell == currentCell && cell.IsInEditMode) {
-                                                               cell.InitializeEditingControl(cell.RowIndex, cell.FormattedValue, style);
-                                                               cell.PositionEditingControl(true, true, bounds, e.ClipRectangle, style, false, false, (columns[currentCell.ColumnIndex].DisplayIndex == 0), (currentCell.RowIndex == 0));
-                                                       }
-                                                       else {
-                                                               DataGridViewAdvancedBorderStyle intermediateBorderStyle = (DataGridViewAdvancedBorderStyle) ((ICloneable)this.AdvancedCellBorderStyle).Clone();
-                                                               DataGridViewAdvancedBorderStyle borderStyle = cell.AdjustCellBorderStyle(this.AdvancedCellBorderStyle, intermediateBorderStyle, true, true, j == 0, cell.RowIndex == 0);
-                                                               OnCellFormatting(new DataGridViewCellFormattingEventArgs(cell.ColumnIndex, cell.RowIndex, cell.Value, cell.FormattedValueType, style));
-                                                               DataGridViewCellPaintingEventArgs args = new DataGridViewCellPaintingEventArgs (this, e.Graphics, e.ClipRectangle, bounds, cell.RowIndex, cell.ColumnIndex, cell.State, cell.Value, cell.FormattedValue, cell.ErrorText, style, borderStyle, DataGridViewPaintParts.All);
-                                                               OnCellPainting(args);
-                                                               if (!args.Handled) {
-                                                                       cell.InternalPaint(e.Graphics, e.ClipRectangle, bounds, cell.RowIndex, cell.State, cell.Value, cell.FormattedValue, cell.ErrorText, style, borderStyle, DataGridViewPaintParts.All);
-                                                               }
-                                                       }
-                                                       bounds.X += bounds.Width;
-                                               }
-                                       }
-                               }
+                               bool is_first = row.Index == 0;
+                               bool is_last = row.Index == rows.Count - 1;
+
+                               row.Paint (g, e.ClipRectangle, bounds, row.Index, row.GetState (row.Index), is_first, is_last);
+
                                bounds.Y += bounds.Height;
-                               bounds.X = -horizontalScrollingOffset;
-                               i++;
+                               bounds.X = BorderWidth;
+                               
+                               if (bounds.Y < ClientSize.Height - (horizontalScrollBar.Visible ? horizontalScrollBar.Height : 0))
+                                       rows_displayed++;
+                               else
+                                       break;
+                                       
+                               gridHeight += row.Height;
                        }
-                       if (rowHeadersVisible) {
+
+                       gridWidth = 0;
+                       
+                       foreach (DataGridViewColumn col in sortedColumns)
+                               if (col.Visible)
+                                       gridWidth += col.Width;
+
+                       gridHeight = 0;
+                       
+                       foreach (DataGridViewRow row in Rows)
+                               gridHeight += row.Height;
+
+                       if (rowHeadersVisible)
                                gridWidth += rowHeadersWidth;
-                       }
-                       if (columnHeadersVisible) {
+
+                       if (columnHeadersVisible)
                                gridHeight += columnHeadersHeight;
-                       }
-                       horizontalScrollBar.Visible = false;
-                       verticalScrollBar.Visible = false;
+                       
+                       bool horizontalVisible = false;
+                       bool verticalVisible = false;
+                       
                        if (AutoSize) {
                                if (gridWidth > Size.Width || gridHeight > Size.Height) {
                                        Size = new Size(gridWidth, gridHeight);
@@ -3194,40 +4368,49 @@ namespace System.Windows.Forms {
                        }
                        else {
                                if (gridWidth > Size.Width) {
-                                       horizontalScrollBar.Visible = true;
+                                       horizontalVisible = true;
                                }
                                if (gridHeight > Size.Height) {
-                                       verticalScrollBar.Visible = true;
+                                       verticalVisible = true;
                                }
                                if (horizontalScrollBar.Visible && (gridHeight + horizontalScrollBar.Height) > Size.Height) {
-                                       verticalScrollBar.Visible = true;
+                                       verticalVisible = true;
                                }
                                if (verticalScrollBar.Visible && (gridWidth + verticalScrollBar.Width) > Size.Width) {
-                                       horizontalScrollBar.Visible = true;
+                                       horizontalVisible = true;
                                }
-                               if (horizontalScrollBar.Visible) {
+                               if (horizontalVisible) {
                                        horizontalScrollBar.Minimum = 0;
-                                       if (verticalScrollBar.Visible) {
-                                               horizontalScrollBar.Maximum = gridWidth - ClientRectangle.Width + verticalScrollBar.Width;
-                                       }
-                                       else {
-                                               horizontalScrollBar.Maximum = gridWidth - ClientRectangle.Width;
-                                       }
-                                       horizontalScrollBar.LargeChange = horizontalScrollBar.Maximum / 10;
-                                       horizontalScrollBar.SmallChange = horizontalScrollBar.Maximum / 20;
+                                       horizontalScrollBar.Maximum = gridWidth;
+                                       horizontalScrollBar.SmallChange = Columns[first_col_index].Width;
+                                       horizontalScrollBar.LargeChange = ClientSize.Width - rowHeadersWidth;
                                }
-                               if (verticalScrollBar.Visible) {
+                               if (verticalVisible) {
                                        verticalScrollBar.Minimum = 0;
-                                       if (horizontalScrollBar.Visible) {
-                                               verticalScrollBar.Maximum = gridHeight - ClientRectangle.Height + horizontalScrollBar.Height;
-                                       }
-                                       else {
-                                               verticalScrollBar.Maximum = gridHeight - ClientRectangle.Height;
-                                       }
-                                       verticalScrollBar.LargeChange = verticalScrollBar.Maximum / 10;
-                                       verticalScrollBar.SmallChange = verticalScrollBar.Maximum / 20;
+                                       verticalScrollBar.Maximum = gridHeight;
+                                       verticalScrollBar.SmallChange = first_row_height + 1;
+                                       verticalScrollBar.LargeChange = ClientSize.Height - columnHeadersHeight;
                                }
                        }
+
+                       horizontalScrollBar.Visible = horizontalVisible;
+                       verticalScrollBar.Visible = verticalVisible;
+                       
+                       // Paint the bottom right square if both scrollbars are displayed
+                       if (horizontalScrollBar.Visible && verticalScrollBar.Visible)
+                               g.FillRectangle (SystemBrushes.Control, new Rectangle (horizontalScrollBar.Right, verticalScrollBar.Bottom, verticalScrollBar.Width, horizontalScrollBar.Height));
+
+                       // Paint the border
+                       bounds = ClientRectangle;
+                       
+                       switch (BorderStyle) {
+                               case BorderStyle.FixedSingle:
+                                       g.DrawRectangle (Pens.Black, new Rectangle (bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1));
+                                       break;
+                               case BorderStyle.Fixed3D:
+                                       ControlPaint.DrawBorder3D (g, bounds, Border3DStyle.Sunken);
+                                       break;
+                       }
                }
 
                protected virtual void OnReadOnlyChanged (EventArgs e) {
@@ -3238,9 +4421,10 @@ namespace System.Windows.Forms {
 
                protected override void OnResize (EventArgs e) {
                        base.OnResize(e);
-                       horizontalScrollingOffset = ((gridWidth - Size.Width) > 0)? (gridWidth - Size.Width) : 0;
-                       verticalScrollingOffset = ((gridHeight - Size.Height) > 0)? (gridHeight - Size.Height) : 0;
-
+                       AutoResizeColumnsInternal ();
+                       
+                       OnVScrollBarScroll (this, new ScrollEventArgs (ScrollEventType.ThumbPosition, verticalScrollBar.Value));
+                       OnHScrollBarScroll (this, new ScrollEventArgs (ScrollEventType.ThumbPosition, horizontalScrollBar.Value));
                }
 
                protected override void OnRightToLeftChanged (EventArgs e) {
@@ -3386,6 +4570,12 @@ namespace System.Windows.Forms {
                        if (eh != null) eh (this, e);
                }
 
+               internal void OnRowsAddedInternal (DataGridViewRowsAddedEventArgs e)
+               {
+                       Invalidate ();
+                       OnRowsAdded (e);
+               }
+
                protected internal virtual void OnRowsAdded (DataGridViewRowsAddedEventArgs e)
                {
                        DataGridViewRowsAddedEventHandler eh = (DataGridViewRowsAddedEventHandler)(Events [RowsAddedEvent]);
@@ -3482,180 +4672,611 @@ namespace System.Windows.Forms {
 
                protected virtual void PaintBackground (Graphics graphics, Rectangle clipBounds, Rectangle gridBounds)
                {
+                       graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (backgroundColor), gridBounds);
                }
 
                protected bool ProcessAKey (Keys keyData)
                {
-                       throw new NotImplementedException();
+                       if (!MultiSelect)
+                               return false;
+                               
+                       if ((keyData & Keys.Control) == Keys.Control) {
+                               SelectAll ();
+                               return true;
+                       }
+                       
+                       return false;
                }
 
                protected virtual bool ProcessDataGridViewKey (KeyEventArgs e)
                {
-                       throw new NotImplementedException();
+                       switch (e.KeyData & ~Keys.Modifiers) {
+                               case Keys.A:
+                                       return ProcessAKey (e.KeyData);
+                               case Keys.Delete:
+                                       return ProcessDeleteKey (e.KeyData);
+                               case Keys.Down:
+                                       return ProcessDownKey (e.KeyData);
+                               case Keys.Escape:
+                                       return ProcessEscapeKey (e.KeyData);
+                               case Keys.End:
+                                       return ProcessEndKey (e.KeyData);
+                               case Keys.Enter:
+                                       return ProcessEnterKey (e.KeyData);
+                               case Keys.F2:
+                                       return ProcessF2Key (e.KeyData);
+                               case Keys.Home:
+                                       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:
+                               case Keys.NumPad0:
+                                       return ProcessZeroKey (e.KeyData);
+                       }
+                       
+                       return false;
                }
 
                protected bool ProcessDeleteKey (Keys keyData)
                {
-                       throw new NotImplementedException();
+                       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);
+                       }
+
+                       if (selected_rows != null)
+                               selected_rows.InternalClear ();
+                       if (selected_columns != null)
+                               selected_columns.InternalClear ();
+
+                       SetSelectedCellCore (0, Math.Min (index, Rows.Count - 1), true);
+                               
+                       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;
+                       }
+                       
                        return base.ProcessDialogKey(keyData);
-                       //throw new NotImplementedException();
                }
 
-               protected bool ProcessDownKey (Keys keyData) {
-                       throw new NotImplementedException();
+               protected bool ProcessDownKey (Keys keyData)
+               {
+                       int current_row = CurrentCellAddress.Y;
+                       
+                       if (current_row < Rows.Count - 1) {
+                               EndEdit ();
+                               
+                               // Move to the last cell in the column
+                               if ((keyData & Keys.Control) == Keys.Control)
+                                       MoveCurrentCell (CurrentCellAddress.X, Rows.Count - 1, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
+                               // Move one cell down
+                               else
+                                       MoveCurrentCell (CurrentCellAddress.X, current_row + 1, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
+                               
+                               return true;
+                       }
+                       
+                       return false;
                }
 
-               protected bool ProcessEndKey (Keys keyData) {
-                       throw new NotImplementedException();
-               }
+               protected bool ProcessEndKey (Keys keyData)
+               {
+                       int disp_index = ColumnIndexToDisplayIndex (currentCellAddress.X);
 
-               protected bool ProcessEnterKey (Keys keyData) {
-                       throw new NotImplementedException();
-               }
+                       // 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, 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, true);
+                               return true;
+                       }
 
-               protected bool ProcessEscapeKey (Keys keyData) {
-                       throw new NotImplementedException();
+                       return false;
                }
 
-               protected bool ProcessF2Key (Keys keyData) {
-                       throw new NotImplementedException();
+               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, true);
+                       }
+                       
+                       return true;
                }
 
-               protected bool ProcessHomeKey (Keys keyData) {
-                       throw new NotImplementedException();
-               }
+               protected bool ProcessEscapeKey (Keys keyData)
+               {
+                       if (!IsCurrentCellInEditMode)
+                               return false;
 
-               protected bool ProcessInsertKey (Keys keyData) {
-                       throw new NotImplementedException();
+                       CancelEdit ();
+                       return true;
                }
 
-               protected override bool ProcessKeyEventArgs (ref Message m) {
-                       return base.ProcessKeyEventArgs(ref m);
-                       //throw new NotImplementedException();
+               protected bool ProcessF2Key (Keys keyData)
+               {
+                       if (editMode == DataGridViewEditMode.EditOnF2 || editMode == DataGridViewEditMode.EditOnKeystrokeOrF2) {
+                               BeginEdit (true);
+                               return true;
+                       }
+                       
+                       return false;
                }
 
-               protected override bool ProcessKeyPreview (ref Message m) {
-                       return base.ProcessKeyPreview(ref m);
-                       //throw new NotImplementedException();
-               }
+               protected bool ProcessHomeKey (Keys keyData)
+               {
+                       int disp_index = ColumnIndexToDisplayIndex (currentCellAddress.X);
 
-               protected bool ProcessLeftKey (Keys keyData) {
-                       throw new NotImplementedException();
-               }
+                       // 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, 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, true);
+                               return true;
+                       }
 
-               protected bool ProcessNextKey (Keys keyData) {
-                       // PAGE DOWN
-                       throw new NotImplementedException();
+                       return false;
                }
 
-               protected bool ProcessPriorKey (Keys keyData) {
-                       // PAGE UP
-                       throw new NotImplementedException();
+               [MonoTODO ("What does insert do?")]
+               protected bool ProcessInsertKey (Keys keyData)
+               {
+                       return false;
                }
 
-               protected bool ProcessRightKey (Keys keyData) {
-                       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);
 
-               protected bool ProcessSpaceKey (Keys keyData) {
-                       throw new NotImplementedException();
+                       return base.ProcessKeyEventArgs (ref m);
                }
 
-               protected bool ProcessTabKey (Keys keyData) {
-                       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;
 
-               protected bool ProcessUpKey (Keys keyData) {
-                       throw new NotImplementedException();
+                               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 ProcessZeroKey (Keys keyData) {
-                       throw new NotImplementedException();
-               }
+               protected bool ProcessLeftKey (Keys keyData)
+               {
+                       int disp_index = ColumnIndexToDisplayIndex (currentCellAddress.X);
 
-               protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified) {
-                       base.SetBoundsCore(x, y, width, height, specified);
+                       if (disp_index > 0) {
+                               EndEdit ();
+                               
+                               // Move to the first cell in the row
+                               if ((keyData & Keys.Control) == Keys.Control)
+                                       MoveCurrentCell (ColumnDisplayIndexToIndex (0), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, 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, true);
+
+                               return true;
+                       }
+
+                       return false;
                }
 
-               protected virtual bool SetCurrentCellAddressCore (int columnIndex, int rowIndex, bool setAnchorCellAddress, bool validateCurrentCell, bool throughMouseClick) {
-                       throw new NotImplementedException();
+               // Page Down
+               protected bool ProcessNextKey (Keys keyData)
+               {
+                       int current_row = CurrentCellAddress.Y;
+
+                       if (current_row < Rows.Count - 1) {
+                               EndEdit ();
+
+                               // 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 virtual void SetSelectedCellCore (int columnIndex, int rowIndex, bool selected) {
-                       throw new NotImplementedException();
+               // Page Up
+               protected bool ProcessPriorKey (Keys keyData)
+               {
+                       int current_row = CurrentCellAddress.Y;
+
+                       if (current_row > 0) {
+                               EndEdit ();
+
+                               // 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 virtual void SetSelectedColumnCore (int columnIndex, bool selected) {
-                       throw new NotImplementedException();
+               protected bool ProcessRightKey (Keys keyData)
+               {
+                       int disp_index = ColumnIndexToDisplayIndex (currentCellAddress.X);
+
+                       if (disp_index < Columns.Count - 1) {
+                               EndEdit ();
+                               
+                               // Move to the last cell in the row
+                               if ((keyData & Keys.Control) == Keys.Control)
+                                       MoveCurrentCell (ColumnDisplayIndexToIndex (Columns.Count - 1), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, 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, true);
+                               
+                               return true;
+                       }
+
+                       return false;
                }
 
-               protected virtual void SetSelectedRowCore (int rowIndex, bool selected) {
-                       throw new NotImplementedException();
+               protected bool ProcessSpaceKey (Keys keyData)
+               {
+                       if ((keyData & Keys.Shift) == Keys.Shift) {
+                               if (selectionMode == DataGridViewSelectionMode.RowHeaderSelect) {
+                                       SetSelectedRowCore (CurrentCellAddress.Y, true);
+                                       InvalidateRow (CurrentCellAddress.Y);
+                                       return true;
+                               }
+                               if (selectionMode == DataGridViewSelectionMode.ColumnHeaderSelect) {
+                                       SetSelectedColumnCore (CurrentCellAddress.X, true);
+                                       InvalidateColumn (CurrentCellAddress.X);
+                                       return true;
+                               }
+                       }
+                       
+                       if (CurrentCell is DataGridViewButtonCell || CurrentCell is DataGridViewLinkCell || CurrentCell is DataGridViewCheckBoxCell) {
+                               DataGridViewCellEventArgs e = new DataGridViewCellEventArgs (CurrentCell.ColumnIndex, CurrentCell.RowIndex);
+                               
+                               OnCellClick (e);
+                               OnCellContentClick (e);
+                               
+                               if (CurrentCell is DataGridViewButtonCell)
+                                       (CurrentCell as DataGridViewButtonCell).OnClickInternal (e);
+                               if (CurrentCell is DataGridViewCheckBoxCell)
+                                       (CurrentCell as DataGridViewCheckBoxCell).OnClickInternal (e);
+                                       
+                               return true;
+                       }
+                       
+                       return false;
                }
 
-               protected override void WndProc (ref Message m) {
-                       base.WndProc(ref m);
+               protected bool ProcessTabKey (Keys keyData)
+               {
+                       EndEdit ();
+                       
+                       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;
                }
 
-               void IDropTarget.OnDragDrop (DragEventArgs e)
+               protected bool ProcessUpKey (Keys keyData)
                {
-                       throw new NotImplementedException ();
+                       int current_row = CurrentCellAddress.Y;
+
+                       if (current_row > 0) {
+                               EndEdit ();
+
+                               // Move to the first cell in the column
+                               if ((keyData & Keys.Control) == Keys.Control)
+                                       MoveCurrentCell (CurrentCellAddress.X, 0, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
+                               // Move one cell up
+                               else
+                                       MoveCurrentCell (CurrentCellAddress.X, current_row - 1, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, true);
+
+                               return true;
+                       }
+
+                       return false;
                }
 
-               void IDropTarget.OnDragEnter (DragEventArgs e)
+               protected bool ProcessZeroKey (Keys keyData)
                {
-                       throw new NotImplementedException ();
+                       if ((keyData & Keys.Control) == Keys.Control && CurrentCell.EditType != null) {
+                               CurrentCell.Value = DBNull.Value;
+                               InvalidateCell (CurrentCell);
+                               return true;
+                       }
+                       
+                       return false;
                }
 
-               void IDropTarget.OnDragLeave (EventArgs e)
+               protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified) {
+                       base.SetBoundsCore(x, y, width, height, specified);
+               }
+
+               [MonoTODO ("Does not use validateCurrentCell or throughMouseClick")]
+               protected virtual bool SetCurrentCellAddressCore (int columnIndex, int rowIndex, bool setAnchorCellAddress, bool validateCurrentCell, bool throughMouseClick)
                {
-                       throw new NotImplementedException ();
+                       if ((columnIndex < 0 || columnIndex > Columns.Count - 1) && rowIndex != -1)
+                               throw new ArgumentOutOfRangeException ("columnIndex");
+                       if ((rowIndex < 0 || rowIndex > Rows.Count - 1) && columnIndex != -1)
+                               throw new ArgumentOutOfRangeException ("rowIndex");
+                       
+                       DataGridViewCell cell;
+                       
+                       if (columnIndex == -1 && rowIndex == -1)
+                               cell = null;
+                       else
+                               cell = Rows.SharedRow (rowIndex).Cells[columnIndex];
+                       
+                       if (cell != null && !cell.Visible)
+                               throw new InvalidOperationException ("cell is not visible");
+                               
+                       if (setAnchorCellAddress)
+                               anchor_cell = new Point (columnIndex, rowIndex);
+
+                       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) {
+                       SetSelectedColumnCore (columnIndex, selected);
+               }       
+               
+               protected virtual void SetSelectedColumnCore (int columnIndex, bool selected) {
+                       if (selectionMode != DataGridViewSelectionMode.ColumnHeaderSelect && selectionMode != DataGridViewSelectionMode.FullColumnSelect)
+                               return; 
+                       
+                       DataGridViewColumn col = columns [columnIndex];
+                       
+                       col.SelectedInternal = selected;
+                       
+                       if (selected_columns == null)
+                               selected_columns = new DataGridViewSelectedColumnCollection ();
+                       
+                       if (!selected && selected_columns.Contains (col)) {
+                               selected_columns.InternalRemove (col);
+                       } else if (selected && !selected_columns.Contains (col)) {
+                               selected_columns.InternalAdd (col);
+                       }
+               }
+
+               internal void SetSelectedRowCoreInternal (int rowIndex, bool selected) {
+                       SetSelectedRowCore (rowIndex, selected);
+               }       
+
+               protected virtual void SetSelectedRowCore (int rowIndex, bool selected) {
+                       DataGridViewRow row = rows [rowIndex];
+                       
+                       row.SelectedInternal = selected;
+                       
+                       if (selected_rows == null)
+                               selected_rows = new DataGridViewSelectedRowCollection (this);
+                               
+                       if (!selected && selected_rows.Contains (row)) {
+                               selected_rows.InternalRemove (row);
+                       } else if (selected && !selected_rows.Contains (row)) {
+                               selected_rows.InternalAdd (row);
+                       }
                }
 
-               void IDropTarget.OnDragOver (DragEventArgs e)
+               protected override void WndProc (ref Message m)
                {
-                       throw new NotImplementedException ();
+                       base.WndProc (ref m);
                }
 
-               internal void InternalOnCellClick (DataGridViewCellEventArgs e) {
-                       OnCellClick(e);
+               internal void InternalOnCellClick (DataGridViewCellEventArgs e)
+               {
+                       OnCellClick (e);
                }
 
-               internal void InternalOnCellContentClick (DataGridViewCellEventArgs e) {
-                       OnCellContentClick(e);
+               internal void InternalOnCellContentClick (DataGridViewCellEventArgs e)
+               {
+                       OnCellContentClick (e);
                }
 
-               internal void InternalOnCellContentDoubleClick (DataGridViewCellEventArgs e) {
-                       OnCellContentDoubleClick(e);
+               internal void InternalOnCellContentDoubleClick (DataGridViewCellEventArgs e)
+               {
+                       OnCellContentDoubleClick (e);
                }
 
-               internal void InternalOnCellValueChanged (DataGridViewCellEventArgs e) {
-                       OnCellValueChanged(e);
+               internal void InternalOnCellValueChanged (DataGridViewCellEventArgs e)
+               {
+                       OnCellValueChanged (e);
+                       
+                       if (editing_row != null && e.RowIndex == editing_row.Index)
+                               PrepareEditingRow (true, false);
                }
 
-               internal void InternalOnDataError (DataGridViewDataErrorEventArgs e) {
+               internal void 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) {
+               internal void OnHScrollBarScroll (object sender, ScrollEventArgs e)
+               {
                        horizontalScrollingOffset = e.NewValue;
-                       Invalidate();
-                       OnScroll(e);
+                       int left = 0;
+
+                       for (int index = 0; index < Columns.Count; index++) {
+                               DataGridViewColumn col = Columns[index];
+
+                               if (e.NewValue < left + col.Width) {
+                                       if (first_col_index != index) {
+                                               first_col_index = index;
+                                               Invalidate ();
+                                               OnScroll (e);
+                                       }
+
+                                       return;
+                               }
+
+                               left += col.Width;
+                       }
                }
 
-               internal void OnVScrollBarScroll (object sender, ScrollEventArgs e) {
+               internal void OnVScrollBarScroll (object sender, ScrollEventArgs e)
+               {
                        verticalScrollingOffset = e.NewValue;
-                       Invalidate();
-                       OnScroll(e);
+                       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;
+                                               Invalidate ();
+                                               OnScroll (e);
+                                       }
+                                       
+                                       return;
+                               }
+                               
+                               top += row.Height;
+                       }
+                       
+                       if (Rows.Count == 0)
+                               return;
+                               
+                       first_row_index = Rows.Count - DisplayedRowCount (false) + 1;
+                       Invalidate ();
+                       OnScroll (e);
                }
 
                internal void RaiseCellStyleChanged (DataGridViewCellEventArgs e) {
@@ -3675,40 +5296,368 @@ 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);
+               // Resizes all columns according to their AutoResizeMode property.
+               // First all the columns that aren't Filled are resized, then we resize all the Filled columns.
+               internal void AutoResizeColumnsInternal ()
+               {
+                       for (int i = 0; i < Columns.Count; i++)
+                               AutoResizeColumnInternal (i, Columns [i].InheritedAutoSizeMode);
+                       
+                       AutoFillColumnsInternal ();
+               }
+
+               internal void AutoFillColumnsInternal ()
+               {
+                       float totalFillWeight = 0;
+                       int FillCount = 0; // The number of columns that has AutoSizeMode.Fill set
+                       int spaceLeft = ClientSize.Width;
+
+                       if (RowHeadersVisible) {
+                               spaceLeft -= RowHeadersWidth;
+                       }
+                       spaceLeft -= BorderWidth * 2;
+                       
+                       int [] fixed_widths = new int [Columns.Count];
+                       int [] new_widths = new int [Columns.Count];
+                       bool fixed_any = false;
+                       
+                       for (int i = 0; i < Columns.Count; i++) {
+                               DataGridViewColumn col = Columns [i];
+
+                               switch (col.InheritedAutoSizeMode) {
+                               case DataGridViewAutoSizeColumnMode.Fill:
+                                       FillCount++;
+                                       totalFillWeight += col.FillWeight;
+                                       break;
+                               case DataGridViewAutoSizeColumnMode.AllCellsExceptHeader:
+                               case DataGridViewAutoSizeColumnMode.AllCells:
+                               case DataGridViewAutoSizeColumnMode.DisplayedCells:
+                               case DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader:
+                               case DataGridViewAutoSizeColumnMode.None:
+                               case DataGridViewAutoSizeColumnMode.NotSet:
+                                       spaceLeft -= Columns [i].Width;
+                                       break;
+                               }
+                       }
+
+                       spaceLeft = Math.Max (0, spaceLeft);
+                       
+                       do {
+                               fixed_any = false;
+                               for (int i = 0; i < columns.Count; i++) {
+                                       DataGridViewColumn col = Columns [i];
+                                       int width;
+                                       
+                                       if (col.InheritedAutoSizeMode != DataGridViewAutoSizeColumnMode.Fill)
+                                               continue;
+                                               
+                                       if (fixed_widths [i] != 0)
+                                               continue;
+                                       
+                                       width = (totalFillWeight == 0) ? 0 : (int) Math.Round (spaceLeft * (col.FillWeight / totalFillWeight), 0);
+                                       
+                                       if (width < 0)
+                                               width = 0;
+                                       
+                                       if (width < col.MinimumWidth) {
+                                               width = col.MinimumWidth;
+                                               fixed_widths [i] = width;
+                                               fixed_any = true;
+                                               spaceLeft -= width;
+                                               totalFillWeight -= col.FillWeight;
+                                       }
+
+                                       new_widths [i] = width;
+                               }
+                       } while (fixed_any);
+
+                       for (int i = 0; i < columns.Count; i++) {
+                               if (Columns [i].InheritedAutoSizeMode != DataGridViewAutoSizeColumnMode.Fill)
+                                       continue;
+                                       
+                               Columns [i].Width = new_widths [i];
+                       }
+               }
+
+               internal void AutoResizeColumnInternal (int columnIndex, DataGridViewAutoSizeColumnMode mode)
+               {
+                       // http://msdn2.microsoft.com/en-us/library/ms171605.aspx
+                       int size = 0;
+
+                       DataGridViewColumn col = Columns [columnIndex];
+                       
+                       switch (mode) {
+                       case DataGridViewAutoSizeColumnMode.Fill:
+                               return;
+                       case DataGridViewAutoSizeColumnMode.AllCellsExceptHeader:
+                       case DataGridViewAutoSizeColumnMode.AllCells:
+                       case DataGridViewAutoSizeColumnMode.DisplayedCells:
+                       case DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader:
+                               size  = CalculateColumnCellWidth (columnIndex, col.InheritedAutoSizeMode);
+                               break;
+                       case DataGridViewAutoSizeColumnMode.ColumnHeader:
+                               size = col.HeaderCell.ContentBounds.Width;
+                               break;
+                       default:
+                               size = col.Width;
+                               break;
+                       }
+
+                       if (size < 0)
+                               size = 0;
+                       if (size < col.MinimumWidth)
+                               size = col.MinimumWidth;
+
+                       col.Width = size;
+               }
+               
+               internal int CalculateColumnCellWidth (int index, DataGridViewAutoSizeColumnMode mode)
+               {
+                       int first_row = 0;
+                       int result = 0;
+                       bool only_visible = false;
+                       
+                       if (mode == DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader || 
+                               mode == DataGridViewAutoSizeColumnMode.AllCellsExceptHeader)
+                               first_row++;
+                       
+                       only_visible = (mode == DataGridViewAutoSizeColumnMode.DisplayedCells || mode == DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader);
+                       
+                       for (int i = first_row; i < Rows.Count; i++) {
+                               if (only_visible) {
+                                       Rectangle row_rect = this.GetRowDisplayRectangle (i, false);
+                                       if (!ClientRectangle.IntersectsWith (row_rect))
+                                               continue;
+                               }
+                               
+                               Rectangle cell_rect = GetCellDisplayRectangle (index, i, false);
+                               
+                               result = Math.Max (result, cell_rect.Width);
+                       }
+                       
+                       return result;
+               }
+
+               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;
                                }
-                               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;
-                                       columns.Add(col);
+                       return bounds;
+               }
+
+               private void PrepareEditingRow (bool cell_changed, bool column_changed)
+               {
+                       bool show = false;
+                       
+                       show = ColumnCount > 0 && AllowUserToAddRows;
+
+                       if (!show && editing_row != null) {
+                               Rows.Remove (editing_row);
+                               editing_row = null;
+                       } else if (show) {
+                               if (editing_row != null) {
+                                       if (cell_changed) {
+                                               // The row changed, it's no longer an editing row.
+                                               editing_row = null;
+                                       } else if (column_changed) {
+                                               // The number of columns has changed, we need a new editing row.
+                                               Rows.Remove (editing_row);
+                                               editing_row = null;
+                                       }
+                               }
+                               if (editing_row == null) {
+                                       editing_row = RowTemplateFull;
+                                       Rows.AddInternal (editing_row, false);
                                }
                        }
-                       foreach (object element in list) {
-                               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);
+                               
+                       
+               }
+               
+               internal DataGridViewRow EditingRow {
+                       get { return editing_row; }
+               }
+
+               private void BindIList (IList list) {
+                       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);
+                                       }
+                               }
+                               // 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 ());
                                }
                        }
+               
+                       // Subscribe to the dataset's change notification
+                       if (list is DataView) {
+                               (list as DataView).ListChanged += OnListChanged;
+                               (list as DataView).Table.ColumnChanged += OnTableColumnChanged;
+                       }
+                       
+                       // Add the rows
+                       foreach (object element in list)
+                               AddBoundRow (element);
                }
 
+               private void AddBoundRow (object element)
+               {
+                       // Don't add rows if there are no columns
+                       if (ColumnCount == 0)
+                               return;
+                               
+                       DataGridViewRow row = (DataGridViewRow)RowTemplate.Clone ();
+                       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;
+                       }
+               }
+               
+               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)
+                                       value = (value as BindingSource).List;
+                                       
+                               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);
+
+                               OnDataBindingComplete (new DataGridViewBindingCompleteEventArgs (ListChangedType.Reset));
+                       }
+
+                       Invalidate ();
+               }
+               
                private void BindIListSource (IListSource list) {
                        BindIList(list.GetList());
                }
@@ -3721,24 +5670,212 @@ namespace System.Windows.Forms {
                        BindIList(list);
                }
 
-               private void OnListChanged (object sender, ListChangedEventArgs args) {
-                       if (args.OldIndex >= 0) {
+               private void MoveCurrentCell (int x, int y, bool select, bool isControl, bool isShift, bool scroll)
+               {
+                       bool full_row_selected = Rows.SharedRow(CurrentCellAddress.Y).Selected;
+                       bool full_col_selected = Columns[CurrentCellAddress.X].Selected;
+                       
+                       // Move Selection
+                       DataGridViewSelectionMode mode = selectionMode;
+                       
+                       // If we are row header select and we clicked a row header, use full row
+                       if (mode == DataGridViewSelectionMode.RowHeaderSelect && (x == -1 || (full_row_selected && CurrentCellAddress.X == x)))
+                               mode = DataGridViewSelectionMode.FullRowSelect;
+                       else if (mode == DataGridViewSelectionMode.RowHeaderSelect)
+                               mode = DataGridViewSelectionMode.CellSelect;
+                               
+                       // If we are col header select and we clicked a col header, use full col
+                       if (mode == DataGridViewSelectionMode.ColumnHeaderSelect && (y == -1 || (full_col_selected && CurrentCellAddress.Y == y)))
+                               mode = DataGridViewSelectionMode.FullColumnSelect;
+                       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;
+
+                               if (disp_y < first_row_index) {
+                                       int delta_y = 0;
+
+                                       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 + DisplayedRowCount (false) - 2) {
+                                       int delta_y = 0;
+                                       
+                                       if (disp_y == Rows.Count - 1)
+                                               delta_y = verticalScrollBar.Maximum - verticalScrollBar.Value;
+                                       else
+                                               for (int i = first_row_index + DisplayedRowCount (false) - 2; 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;
+                       
+                       // Clear old selection unless multi-selecting
+                       if (!isShift)
+                               ClearSelection ();
+                       
+                       switch (mode) {
+                               case DataGridViewSelectionMode.CellSelect:
+                                       SetSelectedCellCore (x, y, true);
+                                       break;
+                               case DataGridViewSelectionMode.FullRowSelect:
+                                       SetSelectedRowCore (y, true);
+                                       break;
+                               case DataGridViewSelectionMode.FullColumnSelect:
+                                       SetSelectedColumnCore (x, true);
+                                       break;
+                       }
+                       
+                       Invalidate ();
+               }
+               
+               private int ColumnIndexToDisplayIndex (int index)
+               {
+                       return Columns[index].DisplayIndex;
+               }
+               
+               private int ColumnDisplayIndexToIndex (int index)
+               {
+                       return Columns.ColumnDisplayIndexSortedArrayList[index].Index;
+               }
+               
+               private void OnListChanged (object sender, ListChangedEventArgs args)
+               {
+                       switch (args.ListChangedType) {
+                               case ListChangedType.ItemAdded:
+                                       AddBoundRow ((sender as DataView)[args.NewIndex]);
+                                       break;
+                               case ListChangedType.ItemDeleted:
+                                       Rows.RemoveAt (args.NewIndex);
+                                       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 ();
+               }
+
+               #region Stuff for ToolTips
+               private void MouseEnteredErrorIcon (DataGridViewCell item)
+               {
+                       tooltip_currently_showing = item;
+                       ToolTipTimer.Start ();
+               }
+
+               private void MouseLeftErrorIcon (DataGridViewCell item)
+               {
+                       ToolTipTimer.Stop ();
+                       ToolTipWindow.Hide (this);
+                       tooltip_currently_showing = null;
+               }
+
+               private Timer ToolTipTimer {
+                       get {
+                               if (tooltip_timer == null) {
+                                       tooltip_timer = new Timer ();
+                                       tooltip_timer.Enabled = false;
+                                       tooltip_timer.Interval = 500;
+                                       tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
                                }
-                               Invalidate();
+
+                               return tooltip_timer;
+                       }
+               }
+
+               private ToolTip ToolTipWindow {
+                       get {
+                               if (tooltip_window == null)
+                                       tooltip_window = new ToolTip ();
+
+                               return tooltip_window;
                        }
                }
 
+               private void ToolTipTimer_Tick (object o, EventArgs args)
+               {
+                       string tooltip = tooltip_currently_showing.ErrorText;
+
+                       if (!string.IsNullOrEmpty (tooltip))
+                               ToolTipWindow.Present (this, tooltip);
+
+                       ToolTipTimer.Stop ();
+               }
+               #endregion
+
+               private class ColumnSorter : IComparer
+               {
+                       int column;
+                       int direction = 1;
+
+                       public ColumnSorter (DataGridViewColumn column, ListSortDirection direction)
+                       {
+                               this.column = column.Index;
+
+                               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;
+
+                               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;
+
+                               return string.Compare (val1.ToString (), val2.ToString ()) * direction;
+                       }
+                       #endregion
+               }
+
                public sealed class HitTestInfo {
 
                        public static readonly HitTestInfo Nowhere = new HitTestInfo(-1, -1, -1, -1, DataGridViewHitTestType.None);
@@ -3792,11 +5929,12 @@ namespace System.Windows.Forms {
                        }
 
                        public override string ToString () {
-                               return GetType().Name;
+                               return string.Format ("Type:{0}, Column:{1}, Row:{2}", type, columnIndex, rowIndex);
                        }
 
                }
 
+               [ComVisible (false)]
                public class DataGridViewControlCollection : Control.ControlCollection
                {
                        private new DataGridView owner;
@@ -3840,6 +5978,11 @@ namespace System.Windows.Forms {
                                base.Remove (value);
                        }
                        
+                       internal void RemoveInternal (Control value)
+                       {
+                               base.Remove (value);
+                       }
+                       
                        
                }
 
@@ -3853,6 +5996,10 @@ namespace System.Windows.Forms {
                                get { return base.Role; }
                        }
 
+                       public override string Name {
+                               get { return base.Name; }
+                       }
+                       
                        public override AccessibleObject GetChild (int index) {
                                return base.GetChild(index);
                        }
@@ -3878,9 +6025,71 @@ namespace System.Windows.Forms {
                        }
 
                }
+               
+               [ComVisible (true)]
+               protected class DataGridViewTopRowAccessibleObject : AccessibleObject
+               {
+                       #region Constructors
+                       public DataGridViewTopRowAccessibleObject ()
+                       {
+                       }
+                       
+                       public DataGridViewTopRowAccessibleObject (DataGridView owner)
+                       {
+                               this.owner = owner;
+                       }
+                       #endregion
+                       
+                       #region Public Methods
+                       public override AccessibleObject GetChild (int index)
+                       {
+                               return base.GetChild (index);
+                       }
 
-       }
+                       public override int GetChildCount ()
+                       {
+                               return base.GetChildCount ();
+                       }
+
+                       public override AccessibleObject Navigate (AccessibleNavigation navigationDirection)
+                       {
+                               return base.Navigate (navigationDirection);
+                       }
+                       #endregion
+                       
+                       #region Public Properties
+                       public override Rectangle Bounds {
+                               get { return base.Bounds; }
+                       }
+                       
+                       public override string Name {
+                               get { return base.Name; }
+                       }
+
+                       public DataGridView Owner {
+                               get { return (DataGridView)owner; }
+                               set { 
+                                       if (owner != null)
+                                               throw new InvalidOperationException ("owner has already been set");
+                               
+                                       owner = value;
+                               }
+                       }
+                       
+                       public override AccessibleObject Parent {
+                               get { return base.Parent; }
+                       }
 
+                       public override AccessibleRole Role {
+                               get { return base.Role; }
+                       }
+
+                       public override string Value {
+                               get { return base.Value; }
+                       }
+                       #endregion
+               }
+       }
 }
 
 #endif