if (!(value == null || value is IList || value is IListSource || value is IBindingList || value is IBindingListView))
throw new NotSupportedException ("Type cannot be bound.");
- ClearBinding ();
- dataSource = value;
- if (BindingContext != null)
- ReBind ();
- OnDataSourceChanged (EventArgs.Empty);
+ if (value != DataSource) {
+ if (IsHandleCreated && value != null && BindingContext != null && BindingContext[value] != null)
+ DataMember = String.Empty;
+ ClearBinding ();
+
+
+ // Do not set dataSource prior to te 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;
+ ReBind ();
+ } else {
+ dataSource = value;
+ }
+
+ OnDataSourceChanged (EventArgs.Empty);
+ }
}
}
[Browsable (false)]
public bool IsCurrentRowDirty {
get {
- if (!virtualMode) {
+ if (!virtualMode)
return IsCurrentCellDirty;
- }
- // Calcular
- throw new NotImplementedException();
+
+ QuestionEventArgs args = new QuestionEventArgs ();
+ OnRowDirtyStateNeeded (args);
+ return args.Response;
}
}
if (ColumnCount == 0)
ColumnCount = 1;
- for (int i = rows.Count; i < value; i++) {
- DataGridViewRow row = (DataGridViewRow) RowTemplateFull;
- rows.AddInternal (row, false);
- }
+ List<DataGridViewRow> newRows = new List<DataGridViewRow> (value - rows.Count);
+ for (int i = rows.Count; i < value; i++)
+ newRows.Add ((DataGridViewRow) RowTemplateFull);
+ rows.AddRange (newRows.ToArray());
}
}
}
}
set {
rowTemplate = value;
- rowTemplate.SetDataGridView(this);
}
}
return true;
try {
- currentCell.Value = currentCell.ParseFormattedValue (currentCell.EditedFormattedValue,
- currentCell.InheritedStyle, null, null);
+ // convert
+ object newValue = currentCell.ParseFormattedValue (currentCell.EditedFormattedValue,
+ currentCell.InheritedStyle, null, null);
+
+ DataGridViewCellValidatingEventArgs validateArgs = new DataGridViewCellValidatingEventArgs (currentCell.ColumnIndex,
+ currentCell.RowIndex,
+ newValue);
+ // validate
+ OnCellValidating (validateArgs);
+ if (validateArgs.Cancel)
+ return false;
+ OnCellValidated (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
+
+ // commit
+ currentCell.Value = newValue;
+
} catch (Exception e) {
DataGridViewDataErrorEventArgs args = new DataGridViewDataErrorEventArgs (e, currentCell.ColumnIndex, currentCell.RowIndex,
DataGridViewDataErrorContexts.Commit);
return true;
}
- [MonoTODO ("Always includes partial columns")]
public int DisplayedColumnCount (bool includePartialColumns)
{
int result = 0;
-
- for (int i = first_col_index; i < Columns.Count; i++)
- if (Columns.ColumnDisplayIndexSortedArrayList[i].Displayed)
+ int columnLeft = 0;
+
+ if (RowHeadersVisible)
+ columnLeft += RowHeadersWidth;
+
+ Size visibleClientArea = ClientSize;
+ if (verticalScrollBar.Visible)
+ visibleClientArea.Width -= verticalScrollBar.Width;
+ if (horizontalScrollBar.Visible)
+ visibleClientArea.Height -= horizontalScrollBar.Height;
+
+ for (int index = first_col_index; index < Columns.Count; index++) {
+ DataGridViewColumn column = Columns[ColumnDisplayIndexToIndex (index)];
+ if (columnLeft + column.Width <= visibleClientArea.Width) {
result++;
- else
+ columnLeft += column.Width;
+ } else {
+ if (includePartialColumns)
+ result++;
break;
-
+ }
+ }
+
return result;
}
return new HitTestInfo (-1, x, -1, y, DataGridViewHitTestType.None);
}
- [MonoTODO ("Invalidates whole grid")]
public void InvalidateCell (DataGridViewCell dataGridViewCell)
{
if (dataGridViewCell == null)
InvalidateCell (dataGridViewCell.ColumnIndex, dataGridViewCell.RowIndex);
}
- [MonoTODO ("Invalidates whole grid")]
public void InvalidateCell (int columnIndex, int rowIndex)
{
if (columnIndex < 0 || columnIndex >= columns.Count)
if (rowIndex < 0 || rowIndex >= rows.Count)
throw new ArgumentOutOfRangeException ("Row index is out of range.");
- Invalidate (GetCellDisplayRectangle (columnIndex, rowIndex, true));
+ if (!is_binding)
+ 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));
+ if (!is_binding)
+ 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));
+ if (!is_binding)
+ Invalidate (GetRowDisplayRectangle (rowIndex, true));
}
public virtual void NotifyCurrentCellDirty (bool dirty) {
InvalidateRow (i);
}
- public void UpdateRowHeightInfo (int rowIndex, bool updateToEnd) {
- throw new NotImplementedException();
+ public void UpdateRowHeightInfo (int rowIndex, bool updateToEnd)
+ {
+ if (rowIndex < 0 && updateToEnd)
+ throw new ArgumentOutOfRangeException ("rowIndex");
+ if (rowIndex < -1 && !updateToEnd)
+ throw new ArgumentOutOfRangeException ("rowIndex");
+ if (rowIndex >= Rows.Count)
+ throw new ArgumentOutOfRangeException ("rowIndex");
+
+ if (!VirtualMode && DataManager == null)
+ return;
+
+ if (rowIndex == -1) {
+ updateToEnd = true;
+ rowIndex = 0;
+ }
+
+ 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));
+ }
+ }
+ } 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));
+ }
+ }
}
protected override bool CanEnableIme {
//
if (!is_autogenerating_columns && columns.Count == 1)
ReBind ();
- foreach (DataGridViewRow row in Rows)
- row.Cells.Add ((DataGridViewCell)e.Column.CellTemplate.Clone ());
+
+ foreach (DataGridViewRow row in Rows) {
+ DataGridViewCell newCell = (DataGridViewCell)e.Column.CellTemplate.Clone ();
+ if (row.Cells.Count == columns.Count)
+ row.Cells.Replace (e.Column.Index, newCell);
+ else if (e.Column.Index >= row.Cells.Count)
+ row.Cells.Add (newCell);
+ else
+ row.Cells.Insert (e.Column.Index, newCell);
+ }
}
+ e.Column.DataColumnIndex = FindDataColumnIndex (e.Column);
AutoResizeColumnsInternal ();
OnColumnAdded (e);
PrepareEditingRow (false, true);
}
+ private int FindDataColumnIndex (DataGridViewColumn column)
+ {
+ if (column != null && DataManager != null) {
+ PropertyDescriptorCollection properties = DataManager.GetItemProperties();
+ for (int i = 0; i < properties.Count; i++) {
+ if (String.Compare (column.DataPropertyName, properties[i].Name, true) == 0)
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
protected virtual void OnColumnAdded (DataGridViewColumnEventArgs e)
{
DataGridViewColumnEventHandler eh = (DataGridViewColumnEventHandler)(Events [ColumnAddedEvent]);
protected override void OnDoubleClick (EventArgs e) {
base.OnDoubleClick(e);
+
+ Point mouseLocation = this.PointToClient (Control.MousePosition);
+ HitTestInfo hitInfo = HitTest (mouseLocation.X, mouseLocation.Y);
+ if (hitInfo.Type == DataGridViewHitTestType.Cell)
+ OnCellDoubleClick (new DataGridViewCellEventArgs (hitInfo.ColumnIndex, hitInfo.RowIndex));
}
protected virtual void OnEditingControlShowing (DataGridViewEditingControlShowingEventArgs e) {
base.OnHandleCreated(e);
ReBind ();
- if (CurrentCell == null && Rows.Count > 0 && Columns.Count > 0)
+ if (DataManager == null && CurrentCell == null && Rows.Count > 0 && Columns.Count > 0)
MoveCurrentCell (ColumnDisplayIndexToIndex (0), 0, true, false, false, false);
}
DataGridViewRow row = null;
Rectangle cellBounds;
- if (hitTest.Type == DataGridViewHitTestType.ColumnHeader && MouseOverColumnResize (hitTest.ColumnIndex, e.X)) {
+ if ((hitTest.Type == DataGridViewHitTestType.ColumnHeader ||
+ (hitTest.Type == DataGridViewHitTestType.Cell && !ColumnHeadersVisible))
+ && MouseOverColumnResize (hitTest.ColumnIndex, e.X)) {
if (e.Clicks == 2) {
AutoResizeColumn (hitTest.ColumnIndex);
return;
Cursor new_cursor = Cursors.Default;
HitTestInfo hit = this.HitTest (e.X, e.Y);
- if (hit.Type == DataGridViewHitTestType.Cell) {
+ if (hit.Type == DataGridViewHitTestType.ColumnHeader ||
+ (!ColumnHeadersVisible && hit.Type == DataGridViewHitTestType.Cell && MouseOverColumnResize (hit.ColumnIndex, e.X))) {
+ EnteredHeaderCell = Columns [hit.ColumnIndex].HeaderCell;
+ if (MouseOverColumnResize (hit.ColumnIndex, e.X))
+ new_cursor = Cursors.VSplit;
+ } else if (hit.Type == DataGridViewHitTestType.Cell) {
EnteredHeaderCell = null;
DataGridViewCell new_cell = GetCellInternal (hit.ColumnIndex, hit.RowIndex);
MouseLeftErrorIcon (new_cell);
}
+ Cursor = new_cursor;
+
// We have never been in a cell before
if (hover_cell == null) {
hover_cell = new_cell;
}
} else {
- if (hit.Type == DataGridViewHitTestType.ColumnHeader) {
- EnteredHeaderCell = Columns [hit.ColumnIndex].HeaderCell;
-
- if (MouseOverColumnResize (hit.ColumnIndex, e.X))
- new_cursor = Cursors.VSplit;
- } else
- EnteredHeaderCell = null;
+ EnteredHeaderCell = null;
// We have left the cell area
if (hover_cell != null) {
protected override void OnPaint (PaintEventArgs e)
{
- base.OnPaint(e);
-
Graphics g = e.Graphics;
Rectangle bounds = ClientRectangle;
ControlPaint.DrawBorder3D (g, bounds, Border3DStyle.Sunken);
break;
}
+
+ // Call the base impl at the end.
+ base.OnPaint(e);
}
private void RefreshScrollBars ()
if (scrollBars != ScrollBars.Horizontal && scrollBars != ScrollBars.Both)
horizontalVisible = false;
+ // MSNET compatibility here
+ if (RowCount <= 1)
+ verticalVisible = false;
+
if (horizontalVisible) {
horizontalScrollBar.Minimum = 0;
horizontalScrollBar.Maximum = gridWidth;
protected internal virtual void OnRowHeightChanged (DataGridViewRowEventArgs e)
{
+ UpdateRowHeightInfo (e.Row.Index, false);
DataGridViewRowEventHandler eh = (DataGridViewRowEventHandler)(Events [RowHeightChangedEvent]);
if (eh != null) eh (this, e);
}
if (hover_cell != null && hover_cell.RowIndex >= e.RowIndex)
hover_cell = null;
+ // Select the first row if we are not databound.
+ // If we are databound selection is managed by the data manager.
+ if (IsHandleCreated && DataManager == null && CurrentCell == null && Rows.Count > 0 && Columns.Count > 0)
+ MoveCurrentCell (ColumnDisplayIndexToIndex (0), 0, true, false, false, true);
+
AutoResizeColumnsInternal ();
Invalidate ();
OnRowsAdded (e);
return false;
}
- [MonoTODO ("What does insert do?")]
+ [MonoInternalNote ("What does insert do?")]
protected bool ProcessInsertKey (Keys keyData)
{
return false;
return false;
else if (currentCell.RowIndex == NewRowIndex && new_row_editing)
CancelEdit ();
+ } else {
+ // CancelEdit will replace the uncommited real editing row with a place holder row
+ if (new_row_editing && currentCell.RowIndex == NewRowIndex)
+ CancelEdit ();
}
OnCellLeave (new DataGridViewCellEventArgs(currentCell.ColumnIndex, currentCell.RowIndex));
OnRowLeave (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
OnCurrentCellChanged (EventArgs.Empty);
if (cell != null) {
- // If the user begins an edit in the NewRow, add a new row
+ // If the user begins an edit in the NewRow, add a new real row
if (AllowUserToAddRows && cell.RowIndex == NewRowIndex && !is_binding && !new_row_editing) {
// OnUserAddedRow will add a real row and reset the current cell
OnUserAddedRow (new DataGridViewRowEventArgs (Rows[NewRowIndex]));
internal void OnHScrollBarScroll (object sender, ScrollEventArgs e)
{
+ int lastRightVisibleColumntIndex = Columns.Count - DisplayedColumnCount (false);
horizontalScrollingOffset = e.NewValue;
int left = 0;
for (int index = 0; index < Columns.Count; index++) {
DataGridViewColumn col = Columns[index];
- if (e.NewValue < left + col.Width) {
+ if (col.Index >= lastRightVisibleColumntIndex) {
+ first_col_index = lastRightVisibleColumntIndex;
+ Invalidate ();
+ OnScroll (e);
+ } else if (e.NewValue < left + col.Width) {
if (first_col_index != index) {
first_col_index = index;
Invalidate ();
if (row.Index >= lastTopVisibleRowIndex) {
first_row_index = lastTopVisibleRowIndex;
+ Invalidate ();
+ OnScroll (e);
} else if (e.NewValue < top + row.Height) {
if (first_row_index != index) {
first_row_index = index;
OnColumnPostRemovedInternal(new DataGridViewColumnEventArgs(e.Element as DataGridViewColumn));
break;
case CollectionChangeAction.Refresh:
+ hover_cell = null;
+ MoveCurrentCell (-1, -1, true, false, false, true);
break;
}
}
for (int i = 0; i < Columns.Count; i++) {
DataGridViewColumn col = Columns [i];
+ if (!col.Visible)
+ continue;
+
switch (col.InheritedAutoSizeMode) {
case DataGridViewAutoSizeColumnMode.Fill:
FillCount++;
if (col.InheritedAutoSizeMode != DataGridViewAutoSizeColumnMode.Fill)
continue;
+
+ if (!col.Visible)
+ continue;
if (fixed_widths [i] != 0)
continue;
for (int i = 0; i < columns.Count; i++) {
if (Columns [i].InheritedAutoSizeMode != DataGridViewAutoSizeColumnMode.Fill)
continue;
-
+
+ if (!Columns[i].Visible)
+ continue;
+
Columns [i].Width = new_widths [i];
}
}
internal int CalculateColumnCellWidth (int index, DataGridViewAutoSizeColumnMode mode)
{
int first_row = 0;
+ int last_row = Rows.Count;
int result = 0;
- bool only_visible = false;
-
- if (mode == DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader ||
- mode == DataGridViewAutoSizeColumnMode.AllCellsExceptHeader)
- first_row++;
-
- only_visible = (mode == DataGridViewAutoSizeColumnMode.DisplayedCells || mode == DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader);
+
+ if (mode == DataGridViewAutoSizeColumnMode.DisplayedCells ||
+ mode == DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader) {
+ first_row = first_row_index;
+ last_row = DisplayedRowCount (true);;
+ }
- for (int i = first_row; i < Rows.Count; i++) {
+ for (int i = first_row; i < last_row; i++) {
if (!Rows[i].Visible)
continue;
- if (only_visible) {
- Rectangle row_rect = this.GetRowDisplayRectangle (i, false);
- if (!ClientRectangle.IntersectsWith (row_rect))
- continue;
- }
int cell_width = Rows[i].Cells[index].PreferredSize.Width;
-
result = Math.Max (result, cell_width);
}
return;
DataGridViewRow row = (DataGridViewRow)RowTemplateFull;
- rows.InternalAdd (row);
-
- PropertyDescriptorCollection properties = TypeDescriptor.GetProperties (element);
-
- foreach (PropertyDescriptor property in properties) {
- if (property.PropertyType == typeof (IBindingList))
- continue;
-
- // We do it this way because there may not be a column
- // for every cell, ignore cells with no column
- DataGridViewCell cell = row.Cells.GetBoundCell (property.Name);
-
- if (cell == null)
- continue;
-
- cell.Value = property.GetValue (element);
- cell.ValueType = property.PropertyType;
- }
+ rows.AddInternal (row, false);
}
private bool IsColumnAlreadyBound (string name)
{
foreach (DataGridViewColumn col in Columns)
- if (col.DataPropertyName == name)
+ if (String.Compare (col.DataPropertyName, name, true) == 0)
return true;
return false;
if (!property.IsBrowsable)
continue;
- if (IsColumnAlreadyBound (property.DisplayName))
+ if (IsColumnAlreadyBound (property.Name))
continue;
DataGridViewColumn col = CreateColumnByType (property.PropertyType);
col.Name = property.DisplayName;
- col.DataPropertyName = property.DisplayName;
+ col.DataPropertyName = property.Name;
col.ReadOnly = !DataManager.AllowEdit || property.IsReadOnly;
col.SetIsDataBound (true);
col.ValueType = property.PropertyType;
}
// DataBind both autogenerated and not columns if there is a matching property
- foreach (PropertyDescriptor property in DataManager.GetItemProperties()) {
- foreach (DataGridViewColumn col in Columns) {
- if (col.DataPropertyName == property.Name)
- col.SetIsDataBound (true);
- }
+ foreach (DataGridViewColumn column in columns) {
+ column.DataColumnIndex = FindDataColumnIndex (column);
+ if (column.DataColumnIndex != -1)
+ column.SetIsDataBound (true);
}
foreach (object element in DataManager.List)
}
PrepareEditingRow (false, true);
- PerformLayout();
- Invalidate ();
}
private void MoveCurrentCell (int x, int y, bool select, bool isControl, bool isShift, bool scroll)
if (scroll) {
int disp_x = ColumnIndexToDisplayIndex (x);
bool scrollbarsRefreshed = false;
+ int displayedColumnsCount = DisplayedColumnCount (false);
+ int delta_x = 0;
+ // The trick here is that in order to avoid unnecessary calculations each time a row/column
+ // is added/removed we recalculate the whole grid size just before the scroll to selection.
if (disp_x < first_col_index) {
- // The trick here is that in order to avoid unnecessary calculations each time a row/column
- // is added/removed we recalculate the whole grid size just before just before the scroll
- // to selection.
RefreshScrollBars ();
scrollbarsRefreshed = true;
- int delta_x = 0;
if (disp_x == 0)
delta_x = horizontalScrollBar.Value;
horizontalScrollBar.SafeValueSet (horizontalScrollBar.Value - delta_x);
OnHScrollBarScroll (this, new ScrollEventArgs (ScrollEventType.ThumbPosition, horizontalScrollBar.Value));
+ } else if (disp_x > first_col_index + displayedColumnsCount - 1) {
+ RefreshScrollBars ();
+ scrollbarsRefreshed = true;
+
+ if (disp_x == Columns.Count - 1)
+ delta_x = horizontalScrollBar.Maximum - horizontalScrollBar.Value;
+ else
+ for (int i = first_col_index + displayedColumnsCount - 1; i < disp_x; 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;
private void ReBind ()
{
if (!is_binding) {
+ SuspendLayout ();
+
is_binding = true;
ClearBinding ();
DoBinding ();
is_binding = false;
+
+ ResumeLayout (true);
+ Invalidate ();
}
}