private HScrollBar horizontalScrollBar;
private VScrollBar verticalScrollBar;
private Control editingControl;
- private bool new_row_commited = true;
private bool is_autogenerating_columns = false;
- private bool in_binding_context_changed = false;
+ private bool is_binding = false;
+ private bool new_row_editing = false;
// These are used to implement selection behaviour with SHIFT pressed.
private int selected_row = -1;
[DefaultValue (true)]
public bool AllowUserToAddRows {
- get { return allowUserToAddRows; }
+ get {
+ if (allowUserToAddRows && DataManager != null)
+ return DataManager.AllowNew;
+ return allowUserToAddRows;
+ }
set {
if (allowUserToAddRows != value) {
allowUserToAddRows = value;
[DefaultValue (true)]
public bool AllowUserToDeleteRows {
- get { return allowUserToDeleteRows; }
+ get {
+ if (allowUserToDeleteRows && DataManager != null)
+ return DataManager.AllowRemove;
+ return allowUserToDeleteRows;
+ }
set {
if (allowUserToDeleteRows != value) {
allowUserToDeleteRows = value;
get { return dataMember; }
set {
if (dataMember != value) {
- ClearBinding ();
-
dataMember = value;
+ ReBind ();
OnDataMemberChanged(EventArgs.Empty);
-
- DoBinding ();
}
}
}
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;
+ ReBind ();
OnDataSourceChanged (EventArgs.Empty);
-
- DoBinding ();
}
}
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public int NewRowIndex {
get {
- if (!allowUserToAddRows || ColumnCount == 0) {
+ if (!AllowUserToAddRows || ColumnCount == 0) {
return -1;
}
return rows.Count - 1;
if (value < 0) {
throw new ArgumentException("RowCount must be >= 0.");
}
- if (value < 1 && allowUserToAddRows) {
+ if (value < 1 && AllowUserToAddRows) {
throw new ArgumentException("RowCount must be >= 1 if AllowUserToAddRows is true.");
}
if (dataSource != null) {
return false;
}
}
-
+
DataGridViewCell cell = currentCell;
Type editType = cell.EditType;
if (e.Cancel)
return false;
- // If the user begins an edit in the NewRow, add a new row
- if (CurrentCell.RowIndex == NewRowIndex) {
- new_row_commited = false;
- OnUserAddedRow (new DataGridViewRowEventArgs (Rows[NewRowIndex]));
- }
-
cell.SetIsInEditMode (true);
// The cell has an editing control we need to setup
public bool CancelEdit ()
{
- if (currentCell != null && currentCell.IsInEditMode) {
- // The user's typing caused a new row to be created, but
- // now they are canceling that typing, we have to remove
- // the new row we added.
- if (!new_row_commited) {
- DataGridViewRow delete_row = EditingRow;
- Rows.RemoveInternal (delete_row);
- editing_row = Rows[currentCell.RowIndex];
- OnUserDeletedRow (new DataGridViewRowEventArgs (delete_row));
- new_row_commited = true;
+ if (currentCell != null) {
+ if (currentCell.IsInEditMode) {
+ currentCell.SetIsInEditMode (false);
+ currentCell.DetachEditingControl ();
}
- currentCell.SetIsInEditMode (false);
- currentCell.DetachEditingControl ();
- OnCellEndEdit (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
+ if (currentCell.RowIndex == NewRowIndex) {
+ if (DataManager != null)
+ DataManager.CancelCurrentEdit ();
+
+ new_row_editing = false;
+ PrepareEditingRow (true, false);
+ OnUserDeletedRow (new DataGridViewRowEventArgs (EditingRow));
+ }
}
return true;
for (int index = first_row_index; index < Rows.Count; index++) {
DataGridViewRow row = GetRowInternal (index);
- if (rowTop + row.Height < ClientSize.Height) {
+ if (rowTop + row.Height <= ClientSize.Height) {
result++;
rowTop += row.Height;
} else {
return true;
if (!CommitEdit (context)) {
+ if (DataManager != null)
+ DataManager.EndCurrentEdit ();
if (EditingControl != null)
EditingControl.Focus ();
return false;
currentCell.SetIsInEditMode (false);
currentCell.DetachEditingControl ();
- new_row_commited = true;
OnCellEndEdit (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
Focus ();
+ if (currentCell.RowIndex == NewRowIndex) {
+ new_row_editing = false;
+ PrepareEditingRow (false, false);
+ }
return true;
}
protected override void OnBindingContextChanged (EventArgs e)
{
base.OnBindingContextChanged(e);
- if (!in_binding_context_changed) {
- in_binding_context_changed = true;
- ReBind();
- in_binding_context_changed = true;
- }
+ ReBind();
}
protected virtual void OnBorderStyleChanged (EventArgs e)
int nextRowIndex = e.RowIndex;
if (nextRowIndex >= Rows.Count)
nextRowIndex = Rows.Count - 1;
- MoveCurrentCell (0, nextRowIndex, true, false, false, true);
+ MoveCurrentCell (currentCell != null ? currentCell.ColumnIndex : 0, nextRowIndex,
+ true, false, false, true);
}
Invalidate ();
protected virtual void OnUserAddedRow (DataGridViewRowEventArgs e)
{
- editing_row = null;
+ // Switch the current editing row with a real
+ int newRowIndex = NewRowIndex;
+ int currentColumnIndex = currentCell != null ? currentCell.ColumnIndex : 0;
+ new_row_editing = true;
PrepareEditingRow (false, false);
+ if (DataManager != null)
+ DataManager.AddNew (); // will raise OnListPositionChanged
+ else
+ MoveCurrentCell (currentColumnIndex, NewRowIndex, true, false, false, true);
- e = new DataGridViewRowEventArgs (editing_row);
-
+ e = new DataGridViewRowEventArgs (Rows[NewRowIndex]);
DataGridViewRowEventHandler eh = (DataGridViewRowEventHandler)(Events [UserAddedRowEvent]);
if (eh != null) eh (this, e);
}
{
DataGridViewRowEventHandler eh = (DataGridViewRowEventHandler)(Events [UserDeletedRowEvent]);
if (eh != null) eh (this, e);
-
}
protected virtual void OnUserDeletingRow (DataGridViewRowCancelEventArgs e)
if (currentCell != null) {
if (currentCell.IsInEditMode && !EndEdit ())
return false;
+ else if (currentCell.RowIndex == NewRowIndex && new_row_editing)
+ CancelEdit ();
OnCellLeave (new DataGridViewCellEventArgs(currentCell.ColumnIndex, currentCell.RowIndex));
OnRowLeave (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
}
OnCellEnter (new DataGridViewCellEventArgs(cell.ColumnIndex, cell.RowIndex));
}
OnCurrentCellChanged (EventArgs.Empty);
- if (cell != null && editMode == DataGridViewEditMode.EditOnEnter)
- BeginEdit (true);
+
+ if (cell != null) {
+ // If the user begins an edit in the NewRow, add a new 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]));
+ } else {
+ if (editMode == DataGridViewEditMode.EditOnEnter)
+ BeginEdit (true);
+ }
+ }
} else {
if (cell != null && throughMouseClick)
BeginEdit (true);
}
internal void SetSelectedRowCoreInternal (int rowIndex, bool selected) {
- SetSelectedRowCore (rowIndex, selected);
+ if (rowIndex >= 0 && rowIndex < Rows.Count)
+ SetSelectedRowCore (rowIndex, selected);
}
protected virtual void SetSelectedRowCore (int rowIndex, bool selected) {
internal void PrepareEditingRow (bool cell_changed, bool column_changed)
{
+ if (new_row_editing) {
+ if (editing_row != null) {
+ Rows.RemoveInternal (editing_row);
+ editing_row = null;
+ }
+ return;
+ }
+
bool show = false;
show = ColumnCount > 0 && AllowUserToAddRows;
Rows.RemoveInternal (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.RemoveInternal (editing_row);
- editing_row = null;
- }
+ if (editing_row != null && (cell_changed || column_changed)) {
+ // The row changed, it's no longer an editing row.
+ // or
+ // The number of columns has changed, we need a new editing row.
+ Rows.RemoveInternal (editing_row);
+ editing_row = null;
}
if (editing_row == null) {
editing_row = RowTemplateFull;
columns.ClearAutoGeneratedColumns ();
rows.Clear ();
PrepareEditingRow (false, true);
- if (DataManager != null)
+ if (DataManager != null) {
DataManager.ListChanged -= OnListChanged;
+ DataManager.PositionChanged -= OnListPositionChanged;
+ }
}
private void DoBinding ()
DataGridViewColumn col = CreateColumnByType (property.PropertyType);
col.Name = property.DisplayName;
col.DataPropertyName = property.DisplayName;
- col.ReadOnly = property.IsReadOnly;
+ col.ReadOnly = !DataManager.AllowEdit || property.IsReadOnly;
col.SetIsDataBound (true);
col.ValueType = property.PropertyType;
col.AutoGenerated = true;
AddBoundRow (element);
DataManager.ListChanged += OnListChanged;
+ DataManager.PositionChanged += OnListPositionChanged;
OnDataBindingComplete (new DataGridViewBindingCompleteEventArgs (ListChangedType.Reset));
+ OnListPositionChanged (this, EventArgs.Empty);
+ } else {
+ if (Rows.Count > 0 && Columns.Count > 0)
+ MoveCurrentCell (0, 0, true, false, false, false);
}
- if (Rows.Count > 0 && Columns.Count > 0)
- MoveCurrentCell (0, 0, true, false, false, false);
+
PerformLayout();
Invalidate ();
}
AddBoundRow (DataManager[args.NewIndex]);
break;
case ListChangedType.ItemDeleted:
- Rows.RemoveAt (args.NewIndex);
+ Rows.RemoveAtInternal (args.NewIndex);
break;
case ListChangedType.ItemChanged:
break;
Invalidate ();
}
+ private void OnListPositionChanged (object sender, EventArgs args)
+ {
+ if (Rows.Count > 0 && Columns.Count > 0 && DataManager.Position != -1)
+ MoveCurrentCell (currentCell != null ? currentCell.ColumnIndex : 0, DataManager.Position,
+ true, false, false, true);
+ else
+ MoveCurrentCell (-1, -1, true, false, false, true);
+ }
private void ReBind ()
{
- ClearBinding ();
- DoBinding ();
+ if (!is_binding) {
+ is_binding = true;
+ ClearBinding ();
+ DoBinding ();
+ is_binding = false;
+ }
}
private bool MouseOverColumnResize (int col, int mousex)