/// to the data cache, or the new cell is in a hidden
/// row.
/////////////////////////////////////////////////////
- if (value.DataGridView != this) {
+ if (value.DataGridView != this)
throw new ArgumentException("The cell is not in this DataGridView.");
- }
- SetCurrentCellAddressCore (value.ColumnIndex, value.RowIndex, false, true, false);
+
+ if (value != null)
+ MoveCurrentCell (value.OwningColumn.Index, value.OwningRow.Index, true, false, false, true);
+ else
+ MoveCurrentCell (-1, -1, true, false, false, true);
}
}
public virtual bool BeginEdit (bool selectAll) {
if (currentCell == null || currentCell.IsInEditMode)
return false;
-
+
if (currentCell.RowIndex >= 0) {
if ((currentCell.InheritedState & DataGridViewElementStates.ReadOnly) == DataGridViewElementStates.ReadOnly) {
return false;
// Show the editing control
EditingControlInternal.Visible = true;
- // Allow editing control to set focus as needed
- (EditingControlInternal as IDataGridViewEditingControl).PrepareEditingControlForEdit (selectAll);
-
+ IDataGridViewEditingControl dgvEditingControl = (IDataGridViewEditingControl) EditingControlInternal;
+ if (dgvEditingControl != null) {
+ dgvEditingControl.EditingControlDataGridView = this;
+ dgvEditingControl.EditingControlRowIndex = currentCell.OwningRow.Index;
+ dgvEditingControl.ApplyCellStyleToEditingControl (style);
+ dgvEditingControl.PrepareEditingControlForEdit (selectAll);
+ dgvEditingControl.EditingControlFormattedValue = currentCell.EditedFormattedValue;
+ }
return true;
}
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;
+ if (currentCell != null && currentCell.OwningRow.DataBoundItem != null) {
+ Object ob = currentCell.OwningRow.DataBoundItem;
+ PropertyDescriptor property = TypeDescriptor.GetProperties (ob)[currentCell.OwningColumn.DataPropertyName];
+ if (property != null && !property.IsReadOnly) {
+ try {
+ object value = currentCell.Value;
+ if (property.Converter != null &&
+ property.Converter.CanConvertFrom (value.GetType()))
+ value = property.Converter.ConvertFrom (value);
+ property.SetValue (ob, value);
+ return true;
+ } catch (Exception exc) {
+ DataGridViewDataErrorEventArgs args = new DataGridViewDataErrorEventArgs (exc, currentCell.ColumnIndex,
+ currentCell.RowIndex, context);
+ InternalOnDataError (args);
+ if (args.ThrowException)
+ throw exc;
+ return false;
+ }
+ }
}
-
- return false;
+
+ return true;
}
[MonoTODO ("Always includes partial columns")]
return result;
}
- [MonoTODO ("Always includes partial rows")]
public int DisplayedRowCount (bool includePartialRow)
{
int result = 0;
-
- for (int i = first_row_index; i < Rows.Count; i++)
- if (Rows[i].Displayed)
+ int rowTop = 0;
+
+ if (ColumnHeadersVisible)
+ rowTop += ColumnHeadersHeight;
+
+ for (int index = first_row_index; index < Rows.Count; index++) {
+ DataGridViewRow row = GetRowInternal (index);
+ if (rowTop + row.Height < ClientSize.Height) {
result++;
- else
+ rowTop += row.Height;
+ } else {
+ if (includePartialRow)
+ result++;
break;
+ }
+ }
return result;
}
public bool EndEdit ()
{
- if (currentCell != null && currentCell.IsInEditMode) {
- if (EditingControl != null) {
- IDataGridViewEditingControl ctrl = EditingControl as IDataGridViewEditingControl;
- ctrl.GetEditingControlFormattedValue (DataGridViewDataErrorContexts.Commit);
- currentCell.Value = ctrl.GetEditingControlFormattedValue (DataGridViewDataErrorContexts.Commit);
-
- currentCell.SetIsInEditMode (false);
- currentCell.DetachEditingControl ();
- } else if (currentCell is IDataGridViewEditingCell) {
- currentCell.Value = (currentCell as IDataGridViewEditingCell).EditingCellFormattedValue;
- currentCell.SetIsInEditMode (false);
- }
-
- new_row_commited = true;
- OnCellEndEdit (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
- }
-
- return true;
+ return EndEdit (DataGridViewDataErrorContexts.Commit);
}
[MonoTODO ("Does not use context parameter")]
public bool EndEdit (DataGridViewDataErrorContexts context)
{
- return EndEdit ();
+ if (currentCell == null || !currentCell.IsInEditMode)
+ return true;
+
+ if (EditingControl != null) {
+ IDataGridViewEditingControl ctrl = EditingControl as IDataGridViewEditingControl;
+ currentCell.Value = ctrl.GetEditingControlFormattedValue (DataGridViewDataErrorContexts.Commit);
+ if (!CommitEdit (context)) {
+ EditingControl.Focus ();
+ return false;
+ }
+ currentCell.DetachEditingControl ();
+ } else if (currentCell is IDataGridViewEditingCell) {
+ currentCell.Value = (currentCell as IDataGridViewEditingCell).EditingCellFormattedValue;
+ if (!CommitEdit (context))
+ return false;
+ }
+
+ currentCell.SetIsInEditMode (false);
+ new_row_commited = true;
+ OnCellEndEdit (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
+ Focus ();
+ return true;
}
public int GetCellCount (DataGridViewElementStates includeFilter) {
}
public virtual void NotifyCurrentCellDirty (bool dirty) {
- throw new NotImplementedException();
+ if (currentCell != null)
+ InvalidateCell (currentCell);
}
public bool RefreshEdit ()
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 (!EndEdit ())
+ return;
if (SortedColumn != null)
SortedColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
- EndEdit ();
-
- // Figure out if this is a numeric sort or text sort
- bool is_numeric = true;
- double n;
+ sortedColumn = dataGridViewColumn;
+ sortOrder = direction == ListSortDirection.Ascending ? SortOrder.Ascending : SortOrder.Descending;
- foreach (DataGridViewRow row in Rows) {
- object val = row.Cells[dataGridViewColumn.Index].Value;
+ if (Rows.Count == 0)
+ return;
+
+ IBindingList bindingList = DataSource as IBindingList;
+ if (dataGridViewColumn.IsDataBound) {
+ if (bindingList != null && bindingList.SupportsSorting) {
+ CurrencyManager currencyManager = (CurrencyManager) this.BindingContext[DataSource];
+ bindingList.ApplySort (currencyManager.GetItemProperties()[dataGridViewColumn.DataPropertyName], direction);
+ dataGridViewColumn.HeaderCell.SortGlyphDirection = sortOrder;
+ }
+ } else {
+ // Figure out if this is a numeric sort or text sort
+ bool is_numeric = true;
+ double n;
- if (val != null && !double.TryParse (val.ToString (), out n)) {
- is_numeric = false;
- break;
+ foreach (DataGridViewRow row in Rows) {
+ object val = row.Cells[dataGridViewColumn.Index].Value;
+
+ if (val != null && !double.TryParse (val.ToString (), out n)) {
+ is_numeric = false;
+ break;
+ }
}
+
+ ColumnSorter sorter = new ColumnSorter (dataGridViewColumn, direction, is_numeric);
+ Rows.Sort (sorter);
+ dataGridViewColumn.HeaderCell.SortGlyphDirection = sortOrder;
}
-
- ColumnSorter sorter = new ColumnSorter (dataGridViewColumn, direction, is_numeric);
- Rows.Sort (sorter);
-
- sortedColumn = dataGridViewColumn;
- sortOrder = (SortOrder)direction + 1;
-
- dataGridViewColumn.HeaderCell.SortGlyphDirection = (SortOrder)direction + 1;
Invalidate ();
-
OnSorted (EventArgs.Empty);
}
eh (this, e);
}
+ internal void OnCellStateChangedInternal (DataGridViewCellStateChangedEventArgs e) {
+ this.OnCellStateChanged (e);
+ }
+
protected virtual void OnCellStateChanged (DataGridViewCellStateChangedEventArgs e)
{
DataGridViewCellStateChangedEventHandler eh = (DataGridViewCellStateChangedEventHandler)(Events [CellStateChangedEvent]);
{
base.OnHandleCreated(e);
- if (Rows.Count > 0 && Columns.Count > 0)
+ if (CurrentCell == null && Rows.Count > 0 && Columns.Count > 0)
MoveCurrentCell (ColumnDisplayIndexToIndex (0), 0, true, false, false, false);
}
{
base.OnMouseDown(e);
+ if (!EndEdit ())
+ return;
+
HitTestInfo hitTest = HitTest(e.X, e.Y);
DataGridViewCell cell = null;
if (hitTest.Type == DataGridViewHitTestType.ColumnHeader && MouseOverColumnResize (hitTest.ColumnIndex, e.X)) {
if (e.Clicks == 2) {
- EndEdit ();
AutoResizeColumn (hitTest.ColumnIndex);
return;
}
column_resize_active = true;
resize_band_start = e.X;
resize_band_delta = 0;
- EndEdit ();
DrawVerticalResizeLine (resize_band_start);
return;
}
if (hitTest.Type == DataGridViewHitTestType.RowHeader && MouseOverRowResize (hitTest.RowIndex, e.Y)) {
if (e.Clicks == 2) {
- EndEdit ();
AutoResizeRow (hitTest.RowIndex);
return;
}
row_resize_active = true;
resize_band_start = e.Y;
resize_band_delta = 0;
- EndEdit ();
DrawHorizontalResizeLine (resize_band_start);
return;
}
private void UpdateBindingPosition (int position)
{
- BindingSource source = dataSource as BindingSource;
- if (source != null && source.CurrencyManager != null)
- source.CurrencyManager.Position = position;
+ if (DataSource != null && BindingContext != null) {
+ CurrencyManager currencyManager = this.BindingContext[DataSource] as CurrencyManager;
+ if (currencyManager != null)
+ currencyManager.Position = position;
+ }
}
protected override void OnMouseEnter (EventArgs e)
gridWidth = rowHeadersVisible ? rowHeadersWidth : 0;
gridHeight = 0;
- 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;
bounds.Y += bounds.Height;
bounds.X = BorderWidth;
- if (bounds.Y < ClientSize.Height - (horizontalScrollBar.Visible ? horizontalScrollBar.Height : 0))
- rows_displayed++;
- else
+ if (bounds.Y >= ClientSize.Height - (horizontalScrollBar.Visible ? horizontalScrollBar.Height : 0))
break;
gridHeight += row.Height;
if (eh != null) eh (this, e);
}
- protected internal virtual void OnRowsRemoved (DataGridViewRowsRemovedEventArgs e)
+ internal void OnRowsRemovedInternal (DataGridViewRowsRemovedEventArgs e)
+ {
+ if (selected_rows != null)
+ selected_rows.InternalClear ();
+ if (selected_columns != null)
+ selected_columns.InternalClear ();
+
+ if (Rows.Count > 0 && Columns.Count > 0 && currentCell != null &&
+ currentCell.RowIndex >= e.RowIndex)
+ MoveCurrentCell (0, Math.Min (e.RowIndex, Rows.Count - 2), true, false, false, true);
+ Invalidate ();
+ OnRowsRemoved (e);
+ }
+
+ protected virtual void OnRowsRemoved (DataGridViewRowsRemovedEventArgs e)
{
DataGridViewRowsRemovedEventHandler eh = (DataGridViewRowsRemovedEventHandler)(Events [RowsRemovedEvent]);
if (eh != null) eh (this, e);
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);
- Invalidate ();
-
return true;
}
if (cell != null && !cell.Visible)
throw new InvalidOperationException ("cell is not visible");
- if (setAnchorCellAddress)
- anchor_cell = new Point (columnIndex, rowIndex);
-
- DataGridViewCell oldCell = CurrentCell;
- currentCell = cell;
- currentCellAddress = new Point (columnIndex, rowIndex);
- if (currentCell != oldCell) {
- if (oldCell != null) {
- EndEdit ();
- OnCellLeave (new DataGridViewCellEventArgs(oldCell.ColumnIndex, oldCell.RowIndex));
- OnRowLeave (new DataGridViewCellEventArgs (oldCell.ColumnIndex, oldCell.RowIndex));
+ if (cell != currentCell) {
+ if (currentCell != null) {
+ if (currentCell.IsInEditMode && !EndEdit ())
+ return false;
+ OnCellLeave (new DataGridViewCellEventArgs(currentCell.ColumnIndex, currentCell.RowIndex));
+ OnRowLeave (new DataGridViewCellEventArgs (currentCell.ColumnIndex, currentCell.RowIndex));
}
+
+ currentCell = cell;
+ if (setAnchorCellAddress)
+ anchor_cell = new Point (columnIndex, rowIndex);
+ currentCellAddress = new Point (columnIndex, rowIndex);
+
UpdateBindingPosition (currentCell.RowIndex);
OnRowEnter (new DataGridViewCellEventArgs (cell.ColumnIndex, cell.RowIndex));
OnCellEnter (new DataGridViewCellEventArgs(cell.ColumnIndex, cell.RowIndex));
OnCurrentCellChanged (EventArgs.Empty);
- if (throughMouseClick && editMode == DataGridViewEditMode.EditOnEnter)
+ if (throughMouseClick || editMode == DataGridViewEditMode.EditOnEnter)
BeginEdit (true);
} else {
if (throughMouseClick)
} else if (selected && !selected_columns.Contains (col)) {
selected_columns.InternalAdd (col);
}
+
+ Invalidate();
}
internal void SetSelectedRowCoreInternal (int rowIndex, bool selected) {
} else if (selected && !selected_rows.Contains (row)) {
selected_rows.InternalAdd (row);
}
+
+ Invalidate();
}
protected override void WndProc (ref Message m)
internal void OnVScrollBarScroll (object sender, ScrollEventArgs e)
{
verticalScrollingOffset = e.NewValue;
+ if (Rows.Count == 0)
+ return;
+
int top = 0;
for (int index = 0; index < Rows.Count; index++) {
DataGridViewRow row = Rows[index];
-
- if (e.NewValue <= top + row.Height) {
+ if (e.NewValue < top + row.Height) {
if (first_row_index != index) {
first_row_index = index;
Invalidate ();
top += row.Height;
}
- if (Rows.Count == 0)
- return;
-
- first_row_index = Rows.Count - DisplayedRowCount (false) + 1;
+ first_row_index = Rows.Count - DisplayedRowCount (false);
Invalidate ();
OnScroll (e);
}
(list as DataView).Table.ColumnChanged += OnTableColumnChanged;
(list as DataView).Table.TableCleared += OnTableCleared;
}
-
+
// Add the rows
foreach (object element in list)
AddBoundRow (element);
}
+ private void OnBindingSourceDataSourceChanged (object sender, EventArgs args)
+ {
+ ClearBinding();
+ DoBinding();
+ }
+
private void AddBoundRow (object element)
{
// Don't add rows if there are no columns
(dataSource as DataView).Table.ColumnChanged -= OnTableColumnChanged;
} else if (dataSource is DataTable)
((dataSource as IListSource).GetList () as DataView).ListChanged -= OnListChanged;
+
+ if (dataSource is IBindingList)
+ (dataSource as IBindingList).ListChanged -= OnListChanged;
+ if (dataSource is BindingSource)
+ (dataSource as BindingSource).DataSourceChanged -= OnBindingSourceDataSourceChanged;
}
}
(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)
+ BindBindingSource (value as BindingSource);
+ else if (value is IBindingListView)
+ BindIBindingListView (value as IBindingListView);
+ else if (value is IBindingList)
+ BindIBindingList (value as IBindingList);
+ else 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));
}
+ if (Rows.Count > 0 && Columns.Count > 0)
+ MoveCurrentCell (0, 0, true, false, false, false);
PerformLayout();
Invalidate ();
}
+ private void BindBindingSource (BindingSource bindingSource)
+ {
+ BindIList (bindingSource.List);
+ bindingSource.ListChanged += OnBindingSourceDataSourceChanged;
+ bindingSource.DataSourceChanged += OnBindingSourceDataSourceChanged;
+ }
+
private void BindIListSource (IListSource list) {
- BindIList(list.GetList());
+ BindIList (list.GetList());
}
private void BindIBindingList (IBindingList list) {
- BindIList(list);
+ BindIList (list);
+ list.ListChanged += OnListChanged;
}
private void BindIBindingListView (IBindingListView list) {
private void MoveCurrentCell (int x, int y, bool select, bool isControl, bool isShift, bool scroll)
{
+ if (!SetCurrentCellAddressCore (x, y, true, false, false))
+ return;
+
bool full_row_selected = Rows.SharedRow(CurrentCellAddress.Y).Selected;
bool full_col_selected = Columns[CurrentCellAddress.X].Selected;
else if (mode == DataGridViewSelectionMode.ColumnHeaderSelect)
mode = DataGridViewSelectionMode.CellSelect;
- SetCurrentCellAddressCore (x, y, true, false, false);
-
// If the current cell isn't visible, scroll to it
if (scroll) {
int disp_x = ColumnIndexToDisplayIndex (x);
}
int disp_y = y;
+ int displayedRowsCount = DisplayedRowCount (false);
+ int delta_y = 0;
if (disp_y < first_row_index) {
- int delta_y = 0;
-
if (disp_y == 0)
delta_y = verticalScrollBar.Value;
else
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;
-
+ } else if (disp_y > first_row_index + displayedRowsCount - 1) {
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++)
+ for (int i = first_row_index + displayedRowsCount - 1; i < disp_y; i++)
delta_y += GetRowInternal (i).Height;
verticalScrollBar.SafeValueSet (verticalScrollBar.Value + delta_y);
{
switch (args.ListChangedType) {
case ListChangedType.ItemAdded:
- AddBoundRow ((sender as DataView)[args.NewIndex]);
+ AddBoundRow ((sender as IBindingList)[args.NewIndex]);
break;
case ListChangedType.ItemDeleted:
Rows.RemoveAt (args.NewIndex);
break;
+ default:
+ ClearBinding ();
+ DoBinding ();
+ break;
}
Invalidate ();