Merge pull request #948 from ermshiperete/bug-xamarin-2394
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridView.cs
index 358207b51eafcce90a2c4e27a1f243b0a9a9e11d..393d5cba9aebfd3d0da99fd14f52067b5b2f70e6 100644 (file)
@@ -740,7 +740,7 @@ namespace System.Windows.Forms {
                                        ClearBinding ();
        
        
-                                       // Do not set dataSource prior to te BindingContext check because there is some lazy initialization 
+                                       // Do not set dataSource prior to the BindingContext check because there is some lazy initialization 
                                        // code which might result in double call to ReBind here and in OnBindingContextChanged
                                        if (BindingContext != null) {
                                                dataSource = value;
@@ -1036,8 +1036,14 @@ namespace System.Windows.Forms {
                                } else if (value > rows.Count) {
                                        // If we need to add rows and don't have any columns,
                                        // we create one column
-                                       if (ColumnCount == 0)
-                                               ColumnCount = 1;
+                                       if (ColumnCount == 0) {
+                                               System.Diagnostics.Debug.Assert (rows.Count == 0);
+                                               ColumnCount = 1; // this creates the edit row
+                                               if (VirtualMode) {
+                                                       // update edit row height
+                                                       UpdateRowHeightInfo (0, false);
+                                               }
+                                       }
 
                                        List<DataGridViewRow> newRows = new List<DataGridViewRow> (value - rows.Count);
                                        for (int i = rows.Count; i < value; i++)
@@ -1362,6 +1368,7 @@ namespace System.Windows.Forms {
                                        } else {
                                                Controls.Remove (editingControl);
                                        }
+                                       editingControl.Dispose();
                                }
                                
                                
@@ -2233,10 +2240,20 @@ namespace System.Windows.Forms {
                        int new_width = 0;
                        
                        if (rowHeadersWidthSizeMode == DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders) {
-                               foreach (DataGridViewRow row in Rows)
-                                       if (row.Displayed)
+                               bool anyRowsDisplayed = false;
+                               foreach(DataGridViewRow row in Rows)
+                                       if(row.Displayed) {
+                                               anyRowsDisplayed = true;
                                                new_width = Math.Max (new_width, row.HeaderCell.PreferredSize.Width);
-                                               
+                                       }
+       
+                               // if there are no rows which are displayed, we still have to set new_width
+                               // to a value >= 4 as RowHeadersWidth will throw an exception otherwise 
+                               if(!anyRowsDisplayed) {
+                                       foreach (DataGridViewRow row in Rows)
+                                                       new_width = Math.Max (new_width, row.HeaderCell.PreferredSize.Width);
+                               }               
+                               
                                if (RowHeadersWidth != new_width)
                                        RowHeadersWidth = new_width;
                                        
@@ -2320,8 +2337,8 @@ namespace System.Windows.Forms {
                                
                                // Call some functions that allows the editing control to get setup
                                DataGridViewCellStyle style = cell.RowIndex == -1 ? DefaultCellStyle : cell.InheritedStyle;
-                               
                                cell.InitializeEditingControl (cell.RowIndex, cell.FormattedValue, style);
+                               OnEditingControlShowing (new DataGridViewEditingControlShowingEventArgs (EditingControlInternal, style));
                                cell.PositionEditingControl (true, true, this.GetCellDisplayRectangle (cell.ColumnIndex, cell.RowIndex, false), bounds, style, false, false, (columns [cell.ColumnIndex].DisplayIndex == 0), (cell.RowIndex == 0));
 
                                // Show the editing control
@@ -2491,7 +2508,8 @@ namespace System.Windows.Forms {
                        currentCell.SetIsInEditMode (false);
                        currentCell.DetachEditingControl ();
                        OnCellEndEdit (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
-                       Focus ();
+                       if (context != DataGridViewDataErrorContexts.LeaveControl)
+                               Focus ();
                        if (currentCell.RowIndex == NewRowIndex) {
                                new_row_editing = false;
                                editing_row = null; // editing row becomes a real row
@@ -3122,6 +3140,20 @@ namespace System.Windows.Forms {
                                InvalidateRow (i);
                }
 
+               private void UpdateRowHeightInfo (DataGridViewRow row)
+               {
+                       DataGridViewRowHeightInfoNeededEventArgs rowInfo =
+                               new DataGridViewRowHeightInfoNeededEventArgs (row.Index, row.Height, row.MinimumHeight);
+                       OnRowHeightInfoNeeded (rowInfo);
+
+                       if (row.Height != rowInfo.Height || row.MinimumHeight != rowInfo.MinimumHeight) {
+                               row.MinimumHeight = rowInfo.MinimumHeight;
+                               row.Height = rowInfo.Height;
+                               OnRowHeightInfoPushed (new DataGridViewRowHeightInfoPushedEventArgs (row.Index, rowInfo.Height,
+                                                                                                       rowInfo.MinimumHeight));
+                       }
+               }
+
                public void UpdateRowHeightInfo (int rowIndex, bool updateToEnd)
                {
                        if (rowIndex < 0 && updateToEnd)
@@ -3141,33 +3173,12 @@ namespace System.Windows.Forms {
 
                        if (updateToEnd) {
                                for (int i = rowIndex; i < Rows.Count; i++) {
-                                       DataGridViewRow row = Rows[i];
-                                       if (!row.Visible)
-                                               continue;
-
-                                       DataGridViewRowHeightInfoNeededEventArgs rowInfo = 
-                                               new DataGridViewRowHeightInfoNeededEventArgs (row.Index, row.Height, row.MinimumHeight);
-                                       OnRowHeightInfoNeeded (rowInfo);
-
-                                       if (row.Height != rowInfo.Height || row.MinimumHeight != rowInfo.MinimumHeight) {
-                                               row.Height = rowInfo.Height;
-                                               row.MinimumHeight = rowInfo.MinimumHeight;
-                                               OnRowHeightInfoPushed (new DataGridViewRowHeightInfoPushedEventArgs (row.Index, rowInfo.Height, 
-                                                                                                                    rowInfo.MinimumHeight));
-                                       }
+                                       DataGridViewRow row = Rows [i];
+                                       if (row.Visible)
+                                               UpdateRowHeightInfo (row);
                                }
                        } else {
-                               DataGridViewRow row = Rows[rowIndex];
-                               DataGridViewRowHeightInfoNeededEventArgs rowInfo = 
-                                       new DataGridViewRowHeightInfoNeededEventArgs (row.Index, row.Height, row.MinimumHeight);
-                               OnRowHeightInfoNeeded (rowInfo);
-
-                               if (row.Height != rowInfo.Height || row.MinimumHeight != rowInfo.MinimumHeight) {
-                                       row.Height = rowInfo.Height;
-                                       row.MinimumHeight = rowInfo.MinimumHeight;
-                                       OnRowHeightInfoPushed (new DataGridViewRowHeightInfoPushedEventArgs (row.Index, rowInfo.Height, 
-                                                                                                            rowInfo.MinimumHeight));
-                               }
+                               UpdateRowHeightInfo (Rows [rowIndex]);
                        }
                }
 
@@ -3379,6 +3390,19 @@ namespace System.Windows.Forms {
                }
 
                protected override void Dispose (bool disposing) {
+                       if (disposing) {
+                               ClearSelection();
+                               currentCell = null;
+                               foreach (DataGridViewColumn column in Columns)
+                                       column.Dispose();
+                               Columns.Clear();
+                               foreach (DataGridViewRow row in Rows)
+                                       row.Dispose();
+                               Rows.Clear();
+                       }
+                       editingControl = null;
+
+                       base.Dispose(disposing);
                }
 
                protected override AccessibleObject GetAccessibilityObjectById (int objectId)
@@ -3984,6 +4008,10 @@ namespace System.Windows.Forms {
 
                internal void OnColumnPreRemovedInternal (DataGridViewColumnEventArgs e)
                {
+                       // The removed column should be removed from the selection too.
+                       if (selected_columns != null)
+                               SetSelectedColumnCore (e.Column.Index, false);
+
                        if (Columns.Count - 1 == 0) {
                                MoveCurrentCell (-1, -1, true, false, false, true);
                                rows.ClearInternal ();
@@ -4214,6 +4242,7 @@ namespace System.Windows.Forms {
 
                protected override void OnLeave (EventArgs e)
                {
+                       EndEdit (DataGridViewDataErrorContexts.LeaveControl);
                        base.OnLeave(e);
                }
 
@@ -5073,6 +5102,11 @@ namespace System.Windows.Forms {
                                MoveCurrentCell (ColumnDisplayIndexToIndex (0), 0, true, false, false, true);
 
                        AutoResizeColumnsInternal ();
+                       if (VirtualMode) {
+                               for (int i = 0; i < e.RowCount; i++)
+                                       UpdateRowHeightInfo (e.RowIndex + i, false);
+                       }
+
                        Invalidate ();
                        OnRowsAdded (e);
                }
@@ -5091,10 +5125,13 @@ namespace System.Windows.Forms {
 
                internal void OnRowsPreRemovedInternal (DataGridViewRowsRemovedEventArgs e)
                {
+                       // All removed rows should be removed from the selection too.
                        if (selected_rows != null)
-                               selected_rows.InternalClear ();
-                       if (selected_columns != null)
-                               selected_columns.InternalClear ();
+                       {
+                               int lastRowIndex = e.RowIndex + e.RowCount;
+                               for (int rowIndex = e.RowIndex; rowIndex < lastRowIndex; ++rowIndex)
+                                       SetSelectedRowCore (rowIndex, false);
+                       }
 
                        if (Rows.Count - e.RowCount <= 0) {
                                MoveCurrentCell (-1, -1, true, false, false, true);
@@ -5424,7 +5461,7 @@ namespace System.Windows.Forms {
                        DataGridViewCell cell = CurrentCell;
                        
                        if (cell != null) {
-                               if (cell.KeyEntersEditMode (new KeyEventArgs ((Keys)m.WParam.ToInt32 ())))
+                               if (cell.KeyEntersEditMode (new KeyEventArgs (((Keys)m.WParam.ToInt32 ()) | XplatUI.State.ModifierKeys)))
                                        BeginEdit (true);
                                if (EditingControl != null && ((Msg)m.Msg == Msg.WM_KEYDOWN || (Msg)m.Msg == Msg.WM_CHAR))
                                        XplatUI.SendMessage (EditingControl.Handle, (Msg)m.Msg, m.WParam, m.LParam);
@@ -5436,7 +5473,7 @@ namespace System.Windows.Forms {
                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 ());
+                               KeyEventArgs e = new KeyEventArgs (((Keys)m.WParam.ToInt32 ()) | XplatUI.State.ModifierKeys);
                        
                                IDataGridViewEditingControl ctrl = (IDataGridViewEditingControl)EditingControlInternal;
                                
@@ -5730,13 +5767,19 @@ namespace System.Windows.Forms {
                        
                        if (selected_columns == null)
                                selected_columns = new DataGridViewSelectedColumnCollection ();
-                       
+
+                       bool selectionChanged = false;
                        if (!selected && selected_columns.Contains (col)) {
                                selected_columns.InternalRemove (col);
+                               selectionChanged = true;
                        } else if (selected && !selected_columns.Contains (col)) {
                                selected_columns.InternalAdd (col);
+                               selectionChanged = true;
                        }
 
+                       if (selectionChanged)
+                               OnSelectionChanged (EventArgs.Empty);
+
                        Invalidate();
                }
 
@@ -5752,13 +5795,19 @@ namespace System.Windows.Forms {
                        
                        if (selected_rows == null)
                                selected_rows = new DataGridViewSelectedRowCollection (this);
-                               
+
+                       bool selectionChanged = false;
                        if (!selected && selected_rows.Contains (row)) {
                                selected_rows.InternalRemove (row);
+                               selectionChanged = true;
                        } else if (selected && !selected_rows.Contains (row)) {
                                selected_rows.InternalAdd (row);
+                               selectionChanged = true;
                        }
 
+                       if (selectionChanged)
+                               OnSelectionChanged (EventArgs.Empty);
+
                        Invalidate();
                }
 
@@ -6287,7 +6336,7 @@ namespace System.Windows.Forms {
                                
                                        horizontalScrollBar.SafeValueSet (horizontalScrollBar.Value - delta_x);
                                        OnHScrollBarScroll (this, new ScrollEventArgs (ScrollEventType.ThumbPosition, horizontalScrollBar.Value));
-                               } else if (disp_x > first_col_index + displayedColumnsCount - 1) {
+                               } else if (disp_x > first_col_index + displayedColumnsCount - 1 && disp_x != 0) {
                                        RefreshScrollBars ();
                                        scrollbarsRefreshed = true;
                                        
@@ -6321,7 +6370,7 @@ namespace System.Windows.Forms {
 
                                        verticalScrollBar.SafeValueSet (verticalScrollBar.Value - delta_y);
                                        OnVScrollBarScroll (this, new ScrollEventArgs (ScrollEventType.ThumbPosition, verticalScrollBar.Value));
-                               } else if (disp_y > first_row_index + displayedRowsCount - 1) {
+                               } else if (disp_y > first_row_index + displayedRowsCount - 1 && disp_y != 0) {
                                        if (!scrollbarsRefreshed)
                                                RefreshScrollBars ();