Warnings cleanup
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridView.cs
index 2889ccf694cab52297809085e585f5f85c46d3d7..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;
@@ -120,10 +122,27 @@ namespace System.Windows.Forms {
                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;
 
-               public DataGridView () {
+               DataGridViewHeaderCell pressed_header_cell;
+               DataGridViewHeaderCell entered_header_cell;
+
+               public DataGridView ()
+               {
+                       SetStyle (ControlStyles.Opaque, true);
+                       //SetStyle (ControlStyles.UserMouse, true);
+                       SetStyle (ControlStyles.OptimizedDoubleBuffer, true);
+                       
                        adjustedTopLeftHeaderBorderStyle = new DataGridViewAdvancedBorderStyle();
                        adjustedTopLeftHeaderBorderStyle.All = DataGridViewAdvancedCellBorderStyle.Single;
                        advancedCellBorderStyle = new DataGridViewAdvancedBorderStyle();
@@ -186,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 ()
@@ -239,6 +257,8 @@ namespace System.Windows.Forms {
                                if (allowUserToAddRows != value) {
                                        allowUserToAddRows = value;
                                        OnAllowUserToAddRowsChanged(EventArgs.Empty);
+                                       PrepareEditingRow (false, false);
+                                       Invalidate ();
                                }
                        }
                }
@@ -344,7 +364,10 @@ namespace System.Windows.Forms {
                                                }
                                        }
                                }
+                               
                                autoSizeColumnsMode = value;
+                               AutoResizeColumns (value);
+                               Invalidate ();
                        }
                }
 
@@ -360,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 ();
                                        ////////////////////////////////////////////////////////////////
                                }
                        }
@@ -425,17 +450,16 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal Size BorderWidth {
+               internal int BorderWidth {
                        get {
                                switch (BorderStyle) {
                                case BorderStyle.Fixed3D:
-                                       return ThemeEngine.Current.Border3DSize;
+                                       return 2;
                                case BorderStyle.FixedSingle:
-                                       return ThemeEngine.Current.BorderSize;
+                                       return 1;
                                case BorderStyle.None:
-                                       return Size.Empty;
                                default:
-                                       return Size.Empty;
+                                       return 0;
                                }
                        }
                }
@@ -480,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);
                                        }
                                }
@@ -525,6 +549,9 @@ namespace System.Windows.Forms {
                                        }
                                        columnHeadersHeight = value;
                                        OnColumnHeadersHeightChanged(EventArgs.Empty);
+                                       
+                                       if (columnHeadersVisible)
+                                               Invalidate ();
                                }
                        }
                }
@@ -547,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)]
@@ -572,6 +604,7 @@ namespace System.Windows.Forms {
                                        throw new ArgumentException("The cell is not in this DataGridView.");
                                }
                                currentCell = value;
+                               currentRow = currentCell.OwningRow;
                        }
                }
 
@@ -591,8 +624,12 @@ namespace System.Windows.Forms {
                        get { return dataMember; }
                        set {
                                if (dataMember != value) {
+                                       ClearBinding ();
+                                       
                                        dataMember = value;
                                        OnDataMemberChanged(EventArgs.Empty);
+                                       
+                                       DoBinding ();
                                }
                        }
                }
@@ -600,7 +637,6 @@ namespace System.Windows.Forms {
                [RefreshProperties (RefreshProperties.Repaint)]
                [DefaultValue (null)]
                [AttributeProvider (typeof (IListSource))]
-               // XXX AttributeProviderAtribute
                public object DataSource {
                        get { return dataSource; }
                        set {
@@ -614,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 ();
                                }
                        }
                }
@@ -694,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 {
@@ -850,6 +883,10 @@ namespace System.Windows.Forms {
                        set { }
                }
 
+               internal DataGridViewHeaderCell PressedHeaderCell {
+                       get { return pressed_header_cell; }
+               }
+
                [Browsable (true)]
                [DefaultValue (false)]
                public bool ReadOnly {
@@ -884,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();
-                               }
                        }
                }
 
@@ -927,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)]
@@ -945,6 +986,9 @@ namespace System.Windows.Forms {
                                        }
                                        rowHeadersWidth = value;
                                        OnRowHeadersWidthChanged(EventArgs.Empty);
+                                       
+                                       if (rowHeadersVisible)
+                                               Invalidate ();
                                }
                        }
                }
@@ -983,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 {
@@ -999,13 +1043,22 @@ namespace System.Windows.Forms {
                                DataGridViewRow row = (DataGridViewRow) RowTemplate.Clone ();
                                
                                for (int i = row.Cells.Count; i < Columns.Count; i++) {
-                                       row.Cells.Add ((DataGridViewCell) columns [i].CellTemplate.Clone ());
+                                       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 {
@@ -1041,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.FullRowSelect || 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;
                        }
                }
 
@@ -1074,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;
                        }
                }
@@ -1133,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)]
@@ -1149,6 +1215,7 @@ namespace System.Windows.Forms {
                        get { return verticalScrollingOffset; }
                }
 
+               [MonoTODO ("VirtualMode is not supported.")]
                [EditorBrowsable (EditorBrowsableState.Advanced)]
                [DefaultValue (false)]
                public bool VirtualMode {
@@ -1175,8 +1242,11 @@ namespace System.Windows.Forms {
                                        }
                                }
                                
-                               if (value != null)
+                               
+                               if (value != null) {
+                                       value.Visible = false;
                                        Controls.Add (value);
+                               }
 
                                editingControl = value;
                        }
@@ -1991,16 +2061,26 @@ namespace System.Windows.Forms {
                        AutoResizeColumn (columnIndex, DataGridViewAutoSizeColumnMode.AllCells);
                }
 
-               public void AutoResizeColumn (int columnIndex, DataGridViewAutoSizeColumnMode autoSizeColumnMode) {
-                       AutoResizeColumn (columnIndex, autoSizeColumnMode, true);
+               public void AutoResizeColumn (int columnIndex, DataGridViewAutoSizeColumnMode autoSizeColumnMode)
+               {
+                       AutoResizeColumnInternal (columnIndex, autoSizeColumnMode);
                }
 
-               public void AutoResizeColumnHeadersHeight () {
-                       throw new NotImplementedException();
+               public void AutoResizeColumnHeadersHeight ()
+               {
+                       int new_height = 0;
+                       
+                       foreach (DataGridViewColumn col in Columns)
+                               new_height = Math.Max (new_height, col.HeaderCell.PreferredSize.Height);
+                       
+                       if (ColumnHeadersHeight != new_height)
+                               ColumnHeadersHeight = new_height;
                }
 
-               public void AutoResizeColumnHeadersHeight (int columnIndex) {
-                       throw new NotImplementedException();
+               [MonoTODO ("columnIndex parameter is not used")]
+               public void AutoResizeColumnHeadersHeight (int columnIndex)
+               {
+                       AutoResizeColumnHeadersHeight ();
                }
 
                public void AutoResizeColumns () {
@@ -2011,36 +2091,88 @@ namespace System.Windows.Forms {
                        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.");
-                       }
-                       if ((autoSizeRowsMode == DataGridViewAutoSizeRowsMode.AllHeaders || autoSizeRowsMode == DataGridViewAutoSizeRowsMode.DisplayedHeaders) && rowHeadersVisible == false) {
-                               throw new InvalidOperationException("Parameter AutoSizeRowsMode cant be AllHeaders or DisplayedHeaders in this DataGridView.");
-                       }
-                       if (autoSizeRowsMode == DataGridViewAutoSizeRowsMode.None) {
-                               throw new ArgumentException("Parameter AutoSieRowsMode cant be None.");
-                       }
+               public void AutoResizeRows (DataGridViewAutoSizeRowsMode autoSizeRowsMode)
+               {
+                       if (!Enum.IsDefined(typeof(DataGridViewAutoSizeRowsMode), autoSizeRowsMode))
+                               throw new InvalidEnumArgumentException ("Parameter AutoSizeRowsMode is not 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) {
@@ -2057,7 +2189,14 @@ namespace System.Windows.Forms {
                        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;
@@ -2072,62 +2211,96 @@ namespace System.Windows.Forms {
                        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)
-                               edControl.PrepareEditingControlForEdit (selectAll);
-                       ctrl.Visible = true;
+                               (EditingControlInternal as IDataGridViewEditingControl).PrepareEditingControlForEdit (selectAll);
 
-                       OnCellBeginEdit (new DataGridViewCellCancelEventArgs (cell.ColumnIndex, cell.RowIndex));
                        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 () {
+               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) {
@@ -2159,22 +2332,30 @@ namespace System.Windows.Forms {
                        
                        int x = 0, y = 0, w = 0, h = 0;
                        
+                       x = BorderWidth;
+                       y = BorderWidth;
+                       
                        if (ColumnHeadersVisible)
-                               y = ColumnHeadersHeight;
+                               y += ColumnHeadersHeight;
                        
                        if (RowHeadersVisible)
-                               x = RowHeadersWidth;
-                               
-                       for (int i = 0; i < Columns.Count; i++) {
-                               if (i == columnIndex) {
-                                       w = columns [i].Width;
+                               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 += columns [i].Width;
+
+                               x += cols[i].Width;
                        }
                        
-                       for (int i = 0; i < Rows.Count; i++) {
+                       for (int i = first_row_index; i < Rows.Count; i++) {
                                if (i == rowIndex) {
                                        h = rows [i].Height;
                                        break;
@@ -2187,113 +2368,395 @@ namespace System.Windows.Forms {
                }
 
                public virtual DataObject GetClipboardContent () {
-                       throw new NotImplementedException();
-               }
-
-               public Rectangle GetColumnDisplayRectangle (int columnIndex, bool cutOverflow) {
-                       throw new NotImplementedException();
-               }
-
-               public Rectangle GetRowDisplayRectangle (int rowIndex, bool cutOverflow) {
-                       throw new NotImplementedException();
-               }
-
-               public HitTestInfo HitTest (int x, int y) {
-                       ///////////////////////////////////////////////////////
-                       //Console.WriteLine ("HitTest ({0}, {1})", x, y);
-                       x += horizontalScrollingOffset;
-                       y += verticalScrollingOffset;
-                       int rowIndex = -1;
-                       int totalHeight = (columnHeadersVisible)? 1 + columnHeadersHeight : 1;
-                       if (columnHeadersVisible && y <= totalHeight) {
-                               rowIndex = -1;
+                       
+                       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 (DataGridViewRow row in rows.RowIndexSortedArrayList) {
-                                       totalHeight += row.Height;
-                                       if (y <= totalHeight) {
-                                               rowIndex = row.Index;
-                                               if (rowIndex == -1) {
-                                                       rowIndex = rows.SharedRowIndexOf (row);
-                                               }
+                       
+                       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;
                                        }
-                                       totalHeight++; // sumar el ancho de las lineas...
                                }
                        }
-                       int colIndex = -1;
-                       int totalWidth = (rowHeadersVisible)? 1 + rowHeadersWidth : 1;
-                       if (rowHeadersVisible && x <= totalWidth) {
-                               colIndex = -1;
+                       
+                       // Find the smallest rectangle that encompasses all selected cells.
+                       for (int r = 0; r < RowCount; r++) {
+                               DataGridViewRow row = Rows [r];
+
+                               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);
+                               }
                        }
-                       else {
-                               foreach (DataGridViewColumn col in columns.ColumnDisplayIndexSortedArrayList) {
-                                       totalWidth += col.Width;
-                                       if (x <= totalWidth) {
-                                               colIndex = col.Index;
-                                               break;
+                       
+                       // 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);
                                        }
-                                       totalWidth++;
                                }
+                               break;
+                       case DataGridViewSelectionMode.FullColumnSelect:
+                       case DataGridViewSelectionMode.FullRowSelect:
+                               only_included_headers = true;
+                               break;
                        }
-                       HitTestInfo result = new HitTestInfo(colIndex, x, rowIndex, y, (colIndex >= 0 && rowIndex >= 0)? DataGridViewHitTestType.Cell : DataGridViewHitTestType.None);
-                       return result;
-               }
+                       
+                       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;
+                       }
+                       for (int r = first_row; r <= end_row; r++) {
+                               DataGridViewRow row = null;
+                               
+                               if (r >= 0) {
+                                       if (!included_rows [r])
+                                               continue;
+                                               
+                                       row = Rows [r];
+                               }
 
-               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();
-               }
+                               if (include_row_headers) {
+                                       first_col = -1;
+                               }
+                               
+                               for (int c = first_col; c <= end_col; c++) {
+                                       DataGridViewCell cell = null;
 
-               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.");
-                       }
-                       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;
+                                       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;
                                        }
                                }
-                       }
-               }
 
-               public void InvalidateColumn (int columnIndex) {
-                       if (columnIndex < 0 || columnIndex >= columns.Count) {
-                               throw new ArgumentOutOfRangeException("Column index is out of range.");
+                               if (r == -1) {// If we just did the column header, jump to the first row.
+                                       r = start_row - 1;
+                               }
                        }
-                       throw new NotImplementedException();
-               }
 
-               public void InvalidateRow (int rowIndex) {
-                       if (rowIndex < 0 || rowIndex >= rows.Count) {
-                               throw new ArgumentOutOfRangeException("Row index is out of range.");
-                       }
-                       throw new NotImplementedException();
+                       // 
+                       // 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;
                }
 
-               public virtual void NotifyCurrentCellDirty (bool dirty) {
-                       throw new NotImplementedException();
-               }
+               [MonoTODO ("Does not use cutOverflow parameter")]
+               public Rectangle GetColumnDisplayRectangle (int columnIndex, bool cutOverflow)
+               {
+                       if (columnIndex < 0 || columnIndex > Columns.Count - 1)
+                               throw new ArgumentOutOfRangeException ("columnIndex");
+                               
+                       int x = 0;
+                       int w = 0;
 
-               public bool RefreshEdit () {
-                       throw new NotImplementedException();
+                       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);
                }
 
-               [EditorBrowsable (EditorBrowsableState.Never)]
-               public override void ResetText () {
+               [MonoTODO ("Does not use cutOverflow parameter")]
+               public Rectangle GetRowDisplayRectangle (int rowIndex, bool cutOverflow)
+               {
+                       if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+                               throw new ArgumentOutOfRangeException ("rowIndex");
+
+                       int y = 0;
+                       int h = 0;
+
+                       y = BorderWidth;
+
+                       if (ColumnHeadersVisible)
+                               y += ColumnHeadersHeight;
+
+                       for (int i = first_row_index; i < Rows.Count; i++) {
+                               if (i == rowIndex) {
+                                       h = rows[i].Height;
+                                       break;
+                               }
+
+                               y += rows[i].Height;
+                       }
+
+                       return new Rectangle (0, y, Width, h);
+               }
+
+               public HitTestInfo HitTest (int x, int y) {
+                       ///////////////////////////////////////////////////////
+                       //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 ()
+               {
+                       if (IsCurrentCellInEditMode) {
+                               currentCell.InitializeEditingControl (currentCell.RowIndex, currentCell.FormattedValue, currentCell.InheritedStyle);
+                               return true;
+                       }
+                       
+                       return false;
+               }
+
+               [EditorBrowsable (EditorBrowsableState.Never)]
+               public override void ResetText ()
+               {
+                       Text = string.Empty;
+               }
+
                public void SelectAll () {
                        switch (selectionMode) {
                                case DataGridViewSelectionMode.FullRowSelect:
@@ -2314,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); }
                }
@@ -2364,16 +2906,22 @@ namespace System.Windows.Forms {
                        throw new NotImplementedException ();
                }
 
-               protected void AutoResizeColumn (int columnIndex, DataGridViewAutoSizeColumnMode autoSizeColumnMode, bool fixedHeight) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use fixedHeight parameter")]
+               protected void AutoResizeColumn (int columnIndex, DataGridViewAutoSizeColumnMode autoSizeColumnMode, bool fixedHeight)
+               {
+                       AutoResizeColumn (columnIndex, autoSizeColumnMode);
                }
 
-               protected void AutoResizeColumnHeadersHeight (bool fixedRowHeadersWidth, bool fixedColumnsWidth) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use fixedRowHeadersWidth or fixedColumnsWidth parameters")]
+               protected void AutoResizeColumnHeadersHeight (bool fixedRowHeadersWidth, bool fixedColumnsWidth)
+               {
+                       AutoResizeColumnHeadersHeight ();
                }
 
-               protected void AutoResizeColumnHeadersHeight (int columnIndex, bool fixedRowHeadersWidth, bool fixedColumnWidth) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use columnIndex or fixedRowHeadersWidth or fixedColumnsWidth parameters")]
+               protected void AutoResizeColumnHeadersHeight (int columnIndex, bool fixedRowHeadersWidth, bool fixedColumnWidth)
+               {
+                       AutoResizeColumnHeadersHeight (columnIndex);
                }
 
                protected void AutoResizeColumns (DataGridViewAutoSizeColumnsMode autoSizeColumnsMode, bool fixedHeight) {
@@ -2382,24 +2930,84 @@ namespace System.Windows.Forms {
                        }
                }
 
-               protected void AutoResizeRow (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use fixedWidth parameter")]
+               protected void AutoResizeRow (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth)
+               {
+                       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) {
@@ -2489,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)
@@ -2877,8 +3505,16 @@ namespace System.Windows.Forms {
 
                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)
@@ -2939,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);
@@ -3054,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]);
@@ -3119,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)
@@ -3141,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)
@@ -3151,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)]
@@ -3168,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)
@@ -3179,6 +3845,10 @@ 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)
@@ -3187,13 +3857,28 @@ namespace System.Windows.Forms {
                        //Console.WriteLine("Mouse: Clicks: {0}; Delta: {1}; X: {2}; Y: {3};", e.Clicks, e.Delta, e.X, e.Y);
                        HitTestInfo hit = HitTest (e.X, e.Y);
 
-                       switch (hit.Type) 
-                       {
-                       case DataGridViewHitTestType.Cell:
-                               Rectangle display = GetCellDisplayRectangle (hit.ColumnIndex, hit.RowIndex, false);
-                               OnCellMouseClick (new DataGridViewCellMouseEventArgs (hit.ColumnIndex, hit.RowIndex, e.X - display.X, e.Y - display.Y, e));
-                               break;
-                       
+                       switch (hit.Type) {
+                               case DataGridViewHitTestType.Cell:
+                                       Rectangle display = GetCellDisplayRectangle (hit.ColumnIndex, hit.RowIndex, false);
+                                       Point cellpoint = new Point (e.X - display.X, e.Y - display.Y);
+
+                                       OnCellMouseClick (new DataGridViewCellMouseEventArgs (hit.ColumnIndex, hit.RowIndex, cellpoint.X, cellpoint.Y, e));
+                                       
+                                       DataGridViewCell cell = GetCellInternal (hit.ColumnIndex, hit.RowIndex);
+                                       
+                                       if (cell.GetContentBounds (hit.RowIndex).Contains (cellpoint)) {
+                                               DataGridViewCellEventArgs dgvcea = new DataGridViewCellEventArgs (hit.ColumnIndex, hit.RowIndex);
+                                               OnCellContentClick (dgvcea);
+                                               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;
                        }
                }
 
@@ -3207,6 +3892,29 @@ namespace System.Windows.Forms {
                        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;
+                       }
                        
                        if (!isControl) {
                                // If SHIFT is pressed:
@@ -3240,10 +3948,17 @@ namespace System.Windows.Forms {
                                        min_col = isShift ? selected_column : max_col;
                                }
 
-                               switch (selectionMode) {
+                               switch (mode) {
                                case DataGridViewSelectionMode.FullRowSelect:
                                        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);
                                                }
@@ -3252,6 +3967,13 @@ namespace System.Windows.Forms {
                                case DataGridViewSelectionMode.FullColumnSelect:
                                        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);
                                                }
@@ -3261,6 +3983,17 @@ namespace System.Windows.Forms {
                                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);
@@ -3273,7 +4006,7 @@ namespace System.Windows.Forms {
                                
                        } else if (isControl) {
                                // Switch the selected state of the row.
-                               switch (selectionMode) {
+                               switch (mode) {
                                case DataGridViewSelectionMode.FullRowSelect:
                                        SetSelectedRowCore (hitTest.RowIndex, !rows [hitTest.RowIndex].Selected);
                                        break;
@@ -3284,7 +4017,9 @@ namespace System.Windows.Forms {
                                case DataGridViewSelectionMode.RowHeaderSelect:
                                        //break;
                                case DataGridViewSelectionMode.CellSelect:
-                                       SetSelectedCellCore (hitTest.ColumnIndex, hitTest.RowIndex, !Rows [hitTest.RowIndex].Cells [hitTest.ColumnIndex].Selected);
+                                       if (hitTest.ColumnIndex >= 0 && hitTest.RowIndex >= 0) {
+                                               SetSelectedCellCore (hitTest.ColumnIndex, hitTest.RowIndex, !Rows [hitTest.RowIndex].Cells [hitTest.ColumnIndex].Selected);
+                                       }
                                        break;
                                }
                        }
@@ -3294,18 +4029,32 @@ namespace System.Windows.Forms {
                protected override void OnMouseDown (MouseEventArgs e)
                {
                        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) {
-                               return;
+                       
+                       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];
                        }
-                       Rectangle 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));
-                       DataGridViewRow row = rows[hitTest.RowIndex];
-                       DataGridViewCell cell = row.Cells[hitTest.ColumnIndex];
+                       
                        DoSelectionOnMouseDown (hitTest);
+                       
+                       if (hitTest.Type != DataGridViewHitTestType.Cell) {
+                               if (hitTest.Type == DataGridViewHitTestType.ColumnHeader)
+                                       pressed_header_cell = columns [hitTest.ColumnIndex].HeaderCell;
+                               else if (hitTest.Type == DataGridViewHitTestType.RowHeader)
+                                       pressed_header_cell = rows [hitTest.RowIndex].HeaderCell;
+                               Invalidate ();
+                               return;
+                       }
+                       
                        if (cell == currentCell) {
                                BeginEdit (true);
                        } else if (currentCell != null) {
@@ -3313,6 +4062,8 @@ namespace System.Windows.Forms {
                                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) {
@@ -3329,36 +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);
-                       HitTestInfo hit = this.HitTest (e.X, e.Y);
+                       base.OnMouseMove (e);
                        
-                       switch (hit.Type)
-                       {
-                       case DataGridViewHitTestType.Cell:
-                               Rectangle display = GetCellDisplayRectangle (hit.ColumnIndex, hit.RowIndex, false);
-                               OnCellMouseMove (new DataGridViewCellMouseEventArgs (hit.ColumnIndex, hit.RowIndex, e.X - display.X, e.Y - display.Y, e));
-                               break;
-                       case DataGridViewHitTestType.ColumnHeader:
-                       case DataGridViewHitTestType.RowHeader:
-                       case DataGridViewHitTestType.TopLeftHeader:
+                       HitTestInfo hit = this.HitTest (e.X, e.Y);
                        
-                       case DataGridViewHitTestType.HorizontalScrollBar:
-                       case DataGridViewHitTestType.VerticalScrollBar:
+                       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;
+                               }
                        
-                       case DataGridViewHitTestType.None:
-                               break;
-                       }
-               }
+                               // We are changing cells
+                               OnCellMouseLeave (new DataGridViewCellEventArgs (hover_cell.ColumnIndex, hover_cell.RowIndex));
 
-               protected override void OnMouseUp (MouseEventArgs e)
-               {
-                       base.OnMouseUp(e);
+                               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)
@@ -3377,70 +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;
-                       PaintBackground (e.Graphics, e.ClipRectangle, 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;
-                               row.Paint (e.Graphics, e.ClipRectangle, bounds, row.Index, row.State, row.Index == 0, row.Index == rows.Count - 1);
+                               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);
@@ -3448,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) {
@@ -3492,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) {
@@ -3747,175 +4677,606 @@ namespace System.Windows.Forms {
 
                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);
                }
 
-               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);
+
+                       // 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;
+                       }
+
+                       return false;
                }
 
-               protected bool ProcessEnterKey (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 ProcessEscapeKey (Keys keyData) {
-                       throw new NotImplementedException();
+               protected bool ProcessEscapeKey (Keys keyData)
+               {
+                       if (!IsCurrentCellInEditMode)
+                               return false;
+
+                       CancelEdit ();
+                       return true;
                }
 
-               protected bool ProcessF2Key (Keys keyData) {
-                       throw new NotImplementedException();
+               protected bool ProcessF2Key (Keys keyData)
+               {
+                       if (editMode == DataGridViewEditMode.EditOnF2 || editMode == DataGridViewEditMode.EditOnKeystrokeOrF2) {
+                               BeginEdit (true);
+                               return true;
+                       }
+                       
+                       return false;
                }
 
-               protected bool ProcessHomeKey (Keys keyData) {
-                       throw new NotImplementedException();
+               protected bool ProcessHomeKey (Keys keyData)
+               {
+                       int disp_index = ColumnIndexToDisplayIndex (currentCellAddress.X);
+
+                       // 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;
+                       }
+
+                       return false;
                }
 
-               protected bool ProcessInsertKey (Keys keyData) {
-                       throw new NotImplementedException();
+               [MonoTODO ("What does insert do?")]
+               protected bool ProcessInsertKey (Keys keyData)
+               {
+                       return false;
                }
 
-               protected override bool ProcessKeyEventArgs (ref Message m) {
-                       return base.ProcessKeyEventArgs(ref m);
-                       //throw new NotImplementedException();
+               protected override bool ProcessKeyEventArgs (ref Message m)
+               {
+                       DataGridViewCell cell = CurrentCell;
+                       
+                       if (cell != null)
+                               if (cell.KeyEntersEditMode (new KeyEventArgs ((Keys)m.WParam.ToInt32 ())))
+                                       BeginEdit (true);
+
+                       return base.ProcessKeyEventArgs (ref m);
                }
 
-               protected override bool ProcessKeyPreview (ref Message m) {
-                       return base.ProcessKeyPreview(ref m);
-                       //throw new NotImplementedException();
+               protected override bool ProcessKeyPreview (ref Message m)
+               {
+                       if ((Msg)m.Msg == Msg.WM_KEYDOWN && (IsCurrentCellInEditMode || m.HWnd == horizontalScrollBar.Handle || m.HWnd == verticalScrollBar.Handle)) {
+                               KeyEventArgs e = new KeyEventArgs ((Keys)m.WParam.ToInt32 ());
+                       
+                               IDataGridViewEditingControl ctrl = (IDataGridViewEditingControl)EditingControlInternal;
+                               
+                               if (ctrl != null)
+                                       if (ctrl.EditingControlWantsInputKey (e.KeyData, false))
+                                               return false;
+
+                               switch (e.KeyData) {
+                                       case Keys.Escape:
+                                       case Keys.Down:
+                                       case Keys.Up:
+                                       case Keys.Left:
+                                       case Keys.Right:
+                                       case Keys.Tab:
+                                       case Keys.Prior:
+                                       case Keys.Next:
+                                               return ProcessDataGridViewKey (e);
+                               }
+                       }
+                       
+                       return base.ProcessKeyPreview (ref m);
                }
 
-               protected bool ProcessLeftKey (Keys keyData) {
-                       throw new NotImplementedException();
+               protected bool ProcessLeftKey (Keys keyData)
+               {
+                       int disp_index = ColumnIndexToDisplayIndex (currentCellAddress.X);
+
+                       if (disp_index > 0) {
+                               EndEdit ();
+                               
+                               // Move to the first cell in the row
+                               if ((keyData & Keys.Control) == Keys.Control)
+                                       MoveCurrentCell (ColumnDisplayIndexToIndex (0), currentCellAddress.Y, true, (keyData & Keys.Control) == Keys.Control, (keyData & Keys.Shift) == Keys.Shift, 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 bool ProcessNextKey (Keys keyData) {
-                       // PAGE DOWN
-                       throw new NotImplementedException();
+               // Page Down
+               protected bool ProcessNextKey (Keys keyData)
+               {
+                       int current_row = CurrentCellAddress.Y;
+
+                       if (current_row < Rows.Count - 1) {
+                               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 bool ProcessPriorKey (Keys keyData) {
-                       // PAGE UP
-                       throw new NotImplementedException();
+               // Page Up
+               protected bool ProcessPriorKey (Keys keyData)
+               {
+                       int current_row = CurrentCellAddress.Y;
+
+                       if (current_row > 0) {
+                               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 bool ProcessRightKey (Keys keyData) {
-                       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 bool ProcessSpaceKey (Keys keyData) {
-                       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 bool ProcessTabKey (Keys keyData) {
-                       throw new NotImplementedException();
+               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;
                }
 
-               protected bool ProcessUpKey (Keys keyData) {
-                       throw new NotImplementedException();
+               protected bool ProcessUpKey (Keys keyData)
+               {
+                       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;
                }
 
-               protected bool ProcessZeroKey (Keys keyData) {
-                       throw new NotImplementedException();
+               protected bool ProcessZeroKey (Keys keyData)
+               {
+                       if ((keyData & Keys.Control) == Keys.Control && CurrentCell.EditType != null) {
+                               CurrentCell.Value = DBNull.Value;
+                               InvalidateCell (CurrentCell);
+                               return true;
+                       }
+                       
+                       return false;
                }
 
                protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified) {
                        base.SetBoundsCore(x, y, width, height, specified);
                }
 
-               protected virtual bool SetCurrentCellAddressCore (int columnIndex, int rowIndex, bool setAnchorCellAddress, bool validateCurrentCell, bool throughMouseClick) {
-                       throw new NotImplementedException();
+               [MonoTODO ("Does not use validateCurrentCell or throughMouseClick")]
+               protected virtual bool SetCurrentCellAddressCore (int columnIndex, int rowIndex, bool setAnchorCellAddress, bool validateCurrentCell, bool throughMouseClick)
+               {
+                       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) {
-                       columns [columnIndex].Selected = 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) {
-                       rows [rowIndex].Selected = 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);
+                       }
                }
 
-               protected override void WndProc (ref Message m) {
-                       base.WndProc(ref m);
+               protected override void WndProc (ref Message m)
+               {
+                       base.WndProc (ref m);
                }
 
-               void IDropTarget.OnDragDrop (DragEventArgs e)
+               internal void InternalOnCellClick (DataGridViewCellEventArgs e)
                {
-                       throw new NotImplementedException ();
+                       OnCellClick (e);
                }
 
-               void IDropTarget.OnDragEnter (DragEventArgs e)
+               internal void InternalOnCellContentClick (DataGridViewCellEventArgs e)
                {
-                       throw new NotImplementedException ();
+                       OnCellContentClick (e);
                }
 
-               void IDropTarget.OnDragLeave (EventArgs e)
+               internal void InternalOnCellContentDoubleClick (DataGridViewCellEventArgs e)
                {
-                       throw new NotImplementedException ();
+                       OnCellContentDoubleClick (e);
                }
 
-               void IDropTarget.OnDragOver (DragEventArgs e)
+               internal void InternalOnCellValueChanged (DataGridViewCellEventArgs e)
                {
-                       throw new NotImplementedException ();
+                       OnCellValueChanged (e);
+                       
+                       if (editing_row != null && e.RowIndex == editing_row.Index)
+                               PrepareEditingRow (true, false);
                }
 
-               internal void InternalOnCellClick (DataGridViewCellEventArgs e) {
-                       OnCellClick(e);
+               internal void InternalOnDataError (DataGridViewDataErrorEventArgs e)
+               {
+                       /////////////// false? ////////////
+                       OnDataError (false, e);
                }
 
-               internal void InternalOnCellContentClick (DataGridViewCellEventArgs e) {
-                       OnCellContentClick(e);
+               internal void InternalOnMouseWheel (MouseEventArgs e)
+               {
+                       OnMouseWheel (e);
                }
 
-               internal void InternalOnCellContentDoubleClick (DataGridViewCellEventArgs e) {
-                       OnCellContentDoubleClick(e);
-               }
+               internal void OnHScrollBarScroll (object sender, ScrollEventArgs e)
+               {
+                       horizontalScrollingOffset = e.NewValue;
+                       int left = 0;
 
-               internal void InternalOnCellValueChanged (DataGridViewCellEventArgs e) {
-                       OnCellValueChanged(e);
-               }
+                       for (int index = 0; index < Columns.Count; index++) {
+                               DataGridViewColumn col = Columns[index];
 
-               internal void InternalOnDataError (DataGridViewDataErrorEventArgs e) {
-                       /////////////// false? ////////////
-                       OnDataError(false, e);
-               }
+                               if (e.NewValue < left + col.Width) {
+                                       if (first_col_index != index) {
+                                               first_col_index = index;
+                                               Invalidate ();
+                                               OnScroll (e);
+                                       }
 
-               internal void InternalOnMouseWheel (MouseEventArgs e) {
-                       OnMouseWheel(e);
-               }
+                                       return;
+                               }
 
-               internal void OnHScrollBarScroll (object sender, ScrollEventArgs e) {
-                       horizontalScrollingOffset = e.NewValue;
-                       Invalidate();
-                       OnScroll(e);
+                               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) {
@@ -3954,7 +5315,7 @@ namespace System.Windows.Forms {
                        if (RowHeadersVisible) {
                                spaceLeft -= RowHeadersWidth;
                        }
-                       spaceLeft -= BorderWidth.Width * 2;
+                       spaceLeft -= BorderWidth * 2;
                        
                        int [] fixed_widths = new int [Columns.Count];
                        int [] new_widths = new int [Columns.Count];
@@ -4077,40 +5438,226 @@ namespace System.Windows.Forms {
                        return result;
                }
 
-               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);
+               Rectangle GetHeaderCellBounds (DataGridViewHeaderCell cell)
+               {
+                       Rectangle bounds = new Rectangle (ClientRectangle.Location, cell.Size);
+                       if (cell is DataGridViewColumnHeaderCell) {
+                               if (RowHeadersVisible)
+                                       bounds.X += RowHeadersWidth;
+                               List<DataGridViewColumn> sortedColumns = columns.ColumnDisplayIndexSortedArrayList;
+                               for (int index = first_col_index; index < sortedColumns.Count; index++) {
+                                       DataGridViewColumn column = sortedColumns [index];
+                                       if (column.Index == cell.ColumnIndex)
+                                               break;
+                                       bounds.X += column.Width;
+                               }
+                       } else {
+                               if (ColumnHeadersVisible)
+                                       bounds.Y += ColumnHeadersHeight;
+                               for (int index = first_row_index; index < Rows.Count; index++) {
+                                       DataGridViewRow row = GetRowInternal (index);
+                                       if (row.HeaderCell == cell)
+                                               break;
+                                       bounds.Y += row.Height;
+                               }
+                       }
+                       return bounds;
+               }
+
+               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;
+                                       }
                                }
-                               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);
+                               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());
                }
@@ -4123,22 +5670,210 @@ 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 {
@@ -4194,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;
@@ -4260,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);
                        }
@@ -4285,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