1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
23 // Pedro MartÃnez Juliá <pedromj@gmail.com>
24 // Ivan N. Zlatev <contact@i-nz.net>
32 using System.ComponentModel;
33 using System.Runtime.InteropServices;
35 namespace System.Windows.Forms {
37 [TypeConverter (typeof (DataGridViewCellConverter))]
38 public abstract class DataGridViewCell : DataGridViewElement, ICloneable, IDisposable
40 private DataGridView dataGridViewOwner;
42 private AccessibleObject accessibilityObject;
43 private int columnIndex;
44 private ContextMenuStrip contextMenuStrip;
45 private bool displayed;
46 private string errorText;
47 private bool isInEditMode;
48 private DataGridViewRow owningRow;
49 private DataGridViewTriState readOnly;
50 private bool selected;
51 private DataGridViewCellStyle style;
53 private string toolTipText;
54 private object valuex;
55 private Type valueType;
57 protected DataGridViewCell ()
60 dataGridViewOwner = null;
61 errorText = string.Empty;
70 public AccessibleObject AccessibilityObject {
72 if (accessibilityObject == null) {
73 accessibilityObject = CreateAccessibilityInstance();
75 return accessibilityObject;
79 public int ColumnIndex {
81 if (DataGridView == null)
88 public Rectangle ContentBounds {
90 return GetContentBounds (RowIndex);
95 public virtual ContextMenuStrip ContextMenuStrip {
96 get { return contextMenuStrip; }
97 set { contextMenuStrip = value; }
101 public virtual object DefaultNewRowValue {
106 public virtual bool Displayed {
107 get { return displayed; }
111 [EditorBrowsable (EditorBrowsableState.Advanced)]
112 public object EditedFormattedValue {
114 return GetEditedFormattedValue (RowIndex, DataGridViewDataErrorContexts.Formatting);
119 [EditorBrowsable (EditorBrowsableState.Advanced)]
120 public virtual Type EditType {
122 return typeof (DataGridViewTextBoxEditingControl);
127 [EditorBrowsable (EditorBrowsableState.Advanced)]
128 public Rectangle ErrorIconBounds {
130 if (this is DataGridViewTopLeftHeaderCell)
131 return GetErrorIconBounds (null, null, RowIndex);
133 if (DataGridView == null || columnIndex < 0)
134 throw new InvalidOperationException ();
135 if (RowIndex < 0 || RowIndex >= DataGridView.Rows.Count)
136 throw new ArgumentOutOfRangeException ("rowIndex", "Specified argument was out of the range of valid values.");
138 return GetErrorIconBounds (null, null, RowIndex);
143 public string ErrorText {
145 if (this is DataGridViewTopLeftHeaderCell)
146 return GetErrorText (-1);
148 if (OwningRow == null)
151 return GetErrorText (OwningRow.Index);
154 if (errorText != value) {
156 OnErrorTextChanged(new DataGridViewCellEventArgs(ColumnIndex, RowIndex));
162 public object FormattedValue {
164 if (DataGridView == null)
167 DataGridViewCellStyle style = InheritedStyle;
168 return GetFormattedValue (Value, RowIndex, ref style, null, null, DataGridViewDataErrorContexts.Formatting);
173 public virtual Type FormattedValueType {
178 public virtual bool Frozen {
180 if (DataGridView == null)
184 return OwningRow.Frozen && OwningColumn.Frozen;
191 public bool HasStyle {
192 get { return style != null; }
196 public DataGridViewElementStates InheritedState {
198 return GetInheritedState (RowIndex);
203 public DataGridViewCellStyle InheritedStyle {
205 return GetInheritedStyle (null, RowIndex, true);
210 public bool IsInEditMode {
212 if (DataGridView == null)
216 throw new InvalidOperationException ("Operation cannot be performed on a cell of a shared row.");
223 [EditorBrowsable (EditorBrowsableState.Advanced)]
224 public DataGridViewColumn OwningColumn {
226 if (DataGridView == null || columnIndex == -1)
229 return DataGridView.Columns[columnIndex];
234 [EditorBrowsable (EditorBrowsableState.Advanced)]
235 public DataGridViewRow OwningRow {
236 get { return owningRow; }
240 public Size PreferredSize {
242 if (DataGridView == null)
243 return new Size (-1, -1);
245 return GetPreferredSize (Hwnd.GraphicsContext, InheritedStyle, RowIndex, Size.Empty);
250 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
251 public virtual bool ReadOnly {
253 if (DataGridView != null && DataGridView.ReadOnly)
256 if (readOnly != DataGridViewTriState.NotSet)
257 return readOnly == DataGridViewTriState.True;
259 if (OwningRow != null && !OwningRow.IsShared && OwningRow.ReadOnly)
262 if (OwningColumn != null && OwningColumn.ReadOnly)
268 readOnly = value ? DataGridViewTriState.True : DataGridViewTriState.False;
270 SetState (DataGridViewElementStates.ReadOnly | State);
272 SetState (~DataGridViewElementStates.ReadOnly & State);
278 public virtual bool Resizable {
280 if (DataGridView == null)
283 // Shared cells aren't resizable
284 if (RowIndex == -1 || columnIndex == -1)
287 return OwningRow.Resizable == DataGridViewTriState.True || OwningColumn.Resizable == DataGridViewTriState.True;
292 public int RowIndex {
294 if (owningRow == null) {
297 return owningRow.Index;
302 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
303 public virtual bool Selected {
308 if (DataGridView != null) {
309 if (RowIndex >= 0 && RowIndex < DataGridView.Rows.Count && DataGridView.Rows [RowIndex].Selected)
312 if (ColumnIndex >= 0 && ColumnIndex < DataGridView.Columns.Count && DataGridView.Columns [ColumnIndex].Selected)
321 if (value != ((State & DataGridViewElementStates.Selected) != 0)) {
322 SetState(State ^ DataGridViewElementStates.Selected);
325 // If our row is selected, unselect it and select
326 // the first cell in it that isn't us
327 if (!selected && OwningRow != null && OwningRow.Selected) {
328 OwningRow.Selected = false;
330 if (columnIndex != 0 && OwningRow.Cells.Count > 0)
331 OwningRow.Cells[0].Selected = true;
332 else if (OwningRow.Cells.Count > 1)
333 OwningRow.Cells[1].Selected = true;
341 if (DataGridView == null)
342 return new Size (-1, -1);
344 return GetSize (RowIndex);
349 public DataGridViewCellStyle Style {
352 style = new DataGridViewCellStyle();
353 style.StyleChanged += OnStyleChanged;
357 set { style = value; }
360 [Bindable (true, BindingDirection.OneWay)]
361 [DefaultValue (null)]
362 [Localizable (false)]
363 [TypeConverter ("System.ComponentModel.StringConverter, " + Consts.AssemblySystem)]
370 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
371 public string ToolTipText {
372 get { return toolTipText == null ? string.Empty : toolTipText; }
373 set { toolTipText = value; }
377 public object Value {
379 return GetValue (RowIndex);
382 SetValue (RowIndex, value);
387 public virtual Type ValueType {
388 get { return valueType; }
389 set { valueType = value; }
393 public virtual bool Visible {
395 // This is independent from State...
396 DataGridViewColumn col = OwningColumn;
397 DataGridViewRow row = OwningRow;
399 bool rowVisible = true, colVisible = true;
401 if (row == null && col == null)
405 rowVisible = !row.IsShared && row.Visible;
409 colVisible = col.Index >= 0 && col.Visible;
412 return rowVisible && colVisible;
416 internal override void SetState (DataGridViewElementStates state) {
417 base.SetState (state);
418 if (DataGridView != null)
419 DataGridView.OnCellStateChangedInternal (new DataGridViewCellStateChangedEventArgs (this, state));
422 [EditorBrowsable (EditorBrowsableState.Advanced)]
423 public virtual DataGridViewAdvancedBorderStyle AdjustCellBorderStyle (DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStyleInput, DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) {
424 return dataGridViewAdvancedBorderStyleInput;
427 public virtual object Clone ()
429 DataGridViewCell result = (DataGridViewCell) Activator.CreateInstance (GetType ());
430 result.accessibilityObject = this.accessibilityObject;
431 result.columnIndex = this.columnIndex;
432 result.displayed = this.displayed;
433 result.errorText = this.errorText;
434 result.isInEditMode = this.isInEditMode;
435 result.owningRow = this.owningRow;
436 result.readOnly = this.readOnly;
437 result.selected = this.selected;
438 result.style = this.style;
439 result.tag = this.tag;
440 result.toolTipText = this.toolTipText;
441 result.valuex = this.valuex;
442 result.valueType = this.valueType;
446 [EditorBrowsable (EditorBrowsableState.Advanced)]
447 public virtual void DetachEditingControl ()
451 public void Dispose ()
455 public Rectangle GetContentBounds (int rowIndex)
457 if (DataGridView == null)
458 return Rectangle.Empty;
460 return GetContentBounds (Hwnd.GraphicsContext, InheritedStyle, rowIndex);
463 public object GetEditedFormattedValue (int rowIndex, DataGridViewDataErrorContexts context)
465 if (DataGridView == null)
468 if (rowIndex < 0 || rowIndex >= DataGridView.RowCount)
469 throw new ArgumentOutOfRangeException ("rowIndex", "Specified argument was out of the range of valid values.");
471 // If we are in edit mode, this returns the value of the editing control
472 // If we aren't in edit mode, return the cell's value
473 // Basically, return what the user is currently seeing
475 if (DataGridView.EditingControl != null)
476 return (DataGridView.EditingControl as IDataGridViewEditingControl).GetEditingControlFormattedValue (context);
478 return (this as IDataGridViewEditingCell).GetEditingCellFormattedValue (context);
481 DataGridViewCellStyle style = InheritedStyle;
483 return GetFormattedValue (GetValue (rowIndex), rowIndex, ref style, null, null, context);
486 public virtual ContextMenuStrip GetInheritedContextMenuStrip (int rowIndex)
488 if (DataGridView == null)
491 if (rowIndex < 0 || rowIndex >= DataGridView.Rows.Count)
492 throw new ArgumentOutOfRangeException ("rowIndex");
494 throw new InvalidOperationException ("cannot perform this on a column header cell");
496 if (contextMenuStrip != null)
497 return contextMenuStrip;
498 if (OwningRow.ContextMenuStrip != null)
499 return OwningRow.ContextMenuStrip;
500 if (OwningColumn.ContextMenuStrip != null)
501 return OwningColumn.ContextMenuStrip;
503 return DataGridView.ContextMenuStrip;
506 public virtual DataGridViewElementStates GetInheritedState (int rowIndex)
509 if (DataGridView == null && rowIndex != -1)
510 throw new ArgumentException ("msg?");
512 if (DataGridView != null && (rowIndex < 0 || rowIndex >= DataGridView.Rows.Count))
513 throw new ArgumentOutOfRangeException ("rowIndex", "Specified argument was out of the range of valid values.");
515 DataGridViewElementStates result;
517 result = DataGridViewElementStates.ResizableSet | State;
519 DataGridViewColumn col = OwningColumn;
520 DataGridViewRow row = OwningRow;
522 if (DataGridView == null) {
524 if (row.Resizable == DataGridViewTriState.True)
525 result |= DataGridViewElementStates.Resizable;
528 result |= DataGridViewElementStates.Visible;
531 result |= DataGridViewElementStates.ReadOnly;
534 result |= DataGridViewElementStates.Frozen;
537 result |= DataGridViewElementStates.Displayed;
540 result |= DataGridViewElementStates.Selected;
547 if (col.Resizable == DataGridViewTriState.True && row.Resizable == DataGridViewTriState.True)
548 result |= DataGridViewElementStates.Resizable;
550 if (col.Visible && row.Visible)
551 result |= DataGridViewElementStates.Visible;
553 if (col.ReadOnly || row.ReadOnly)
554 result |= DataGridViewElementStates.ReadOnly;
556 if (col.Frozen || row.Frozen)
557 result |= DataGridViewElementStates.Frozen;
559 if (col.Displayed && row.Displayed)
560 result |= DataGridViewElementStates.Displayed;
562 if (col.Selected || row.Selected)
563 result |= DataGridViewElementStates.Selected;
569 public virtual DataGridViewCellStyle GetInheritedStyle (DataGridViewCellStyle inheritedCellStyle, int rowIndex, bool includeColors) {
571 * System.InvalidOperationException :: The cell has no associated System.Windows.Forms.DataGridView, or the cell's System.Windows.Forms.DataGridViewCell.ColumnIndex is less than 0.
572 * System.ArgumentOutOfRangeException :: rowIndex is less than 0, or greater than or equal to the number of rows in the parent System.Windows.Forms.DataGridView.
575 if (DataGridView == null)
576 throw new InvalidOperationException ("Cell is not in a DataGridView. The cell cannot retrieve the inherited cell style.");
578 if (rowIndex < 0 || rowIndex >= DataGridView.Rows.Count)
579 throw new ArgumentOutOfRangeException ("rowIndex");
581 // Start with DataGridView.DefaultCellStyle
582 DataGridViewCellStyle result = new DataGridViewCellStyle (DataGridView.DefaultCellStyle);
584 // If we have a column, add OwningColumn.DefaultCellStyle
585 if (OwningColumn != null)
586 result.ApplyStyle (OwningColumn.DefaultCellStyle);
588 // Add DataGridView.RowsDefaultCellStyle
589 result.ApplyStyle (DataGridView.RowsDefaultCellStyle);
591 // If we are an odd row, add DataGridView.AlternatingRowsDefaultCellStyle
592 if (rowIndex % 2 == 1)
593 result.ApplyStyle (DataGridView.AlternatingRowsDefaultCellStyle);
595 // Add Row.DefaultCellStyle
596 result.ApplyStyle (DataGridView.Rows.SharedRow (rowIndex).DefaultCellStyle);
600 result.ApplyStyle (Style);
605 [EditorBrowsable (EditorBrowsableState.Advanced)]
606 public virtual void InitializeEditingControl (int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) {
607 if (DataGridView == null || DataGridView.EditingControl == null) {
608 throw new InvalidOperationException("No editing control defined");
612 public virtual bool KeyEntersEditMode (KeyEventArgs e)
617 [EditorBrowsable (EditorBrowsableState.Advanced)]
618 public static int MeasureTextHeight (Graphics graphics, string text, Font font, int maxWidth, TextFormatFlags flags)
620 if (graphics == null)
621 throw new ArgumentNullException ("Graphics argument null");
623 throw new ArgumentNullException ("Font argument null");
625 throw new ArgumentOutOfRangeException ("maxWidth is less than 1.");
627 return TextRenderer.MeasureText (graphics, text, font, new Size (maxWidth, 0), flags).Height;
630 [MonoTODO ("does not use widthTruncated parameter")]
631 [EditorBrowsable (EditorBrowsableState.Advanced)]
632 public static int MeasureTextHeight (Graphics graphics, string text, Font font, int maxWidth, TextFormatFlags flags, out bool widthTruncated)
634 widthTruncated = false;
635 return TextRenderer.MeasureText (graphics, text, font, new Size (maxWidth, 0), flags).Height;
638 [EditorBrowsable (EditorBrowsableState.Advanced)]
639 public static Size MeasureTextPreferredSize (Graphics graphics, string text, Font font, float maxRatio, TextFormatFlags flags)
641 if (graphics == null)
642 throw new ArgumentNullException ("Graphics argument null");
644 throw new ArgumentNullException ("Font argument null");
646 throw new ArgumentOutOfRangeException ("maxRatio is less than or equals to 0.");
648 // I couldn't find a case where maxRatio
649 // affected anything on MS
650 return MeasureTextSize (graphics, text, font, flags);
653 [EditorBrowsable (EditorBrowsableState.Advanced)]
654 public static Size MeasureTextSize (Graphics graphics, string text, Font font, TextFormatFlags flags)
656 return TextRenderer.MeasureText (graphics, text, font, Size.Empty, flags);
659 [EditorBrowsable (EditorBrowsableState.Advanced)]
660 public static int MeasureTextWidth (Graphics graphics, string text, Font font, int maxHeight, TextFormatFlags flags)
662 if (graphics == null)
663 throw new ArgumentNullException ("Graphics argument null");
665 throw new ArgumentNullException ("Font argument null");
667 throw new ArgumentOutOfRangeException ("maxHeight is less than 1.");
669 return TextRenderer.MeasureText (graphics, text, font, new Size (0, maxHeight), flags).Width;
672 public virtual object ParseFormattedValue (object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
674 if (cellStyle == null)
675 throw new ArgumentNullException ("cellStyle is null.");
676 if (FormattedValueType == null)
677 throw new FormatException ("The System.Windows.Forms.DataGridViewCell.FormattedValueType property value is null.");
678 if (formattedValue == null)
679 throw new ArgumentException ("formattedValue is null.");
680 if (ValueType == null)
681 throw new FormatException ("valuetype is null");
682 if (!FormattedValueType.IsAssignableFrom (formattedValue.GetType ()))
683 throw new ArgumentException ("formattedValue is not of formattedValueType.");
685 if (formattedValueTypeConverter == null)
686 formattedValueTypeConverter = FormattedValueTypeConverter;
687 if (valueTypeConverter == null)
688 valueTypeConverter = ValueTypeConverter;
690 if (valueTypeConverter != null && valueTypeConverter.CanConvertFrom (FormattedValueType))
691 return valueTypeConverter.ConvertFrom (formattedValue);
692 if (formattedValueTypeConverter != null && formattedValueTypeConverter.CanConvertTo (ValueType))
693 return formattedValueTypeConverter.ConvertTo (formattedValue, ValueType);
694 return Convert.ChangeType (formattedValue, ValueType);
697 [EditorBrowsable (EditorBrowsableState.Advanced)]
698 public virtual void PositionEditingControl (bool setLocation, bool setSize, Rectangle cellBounds, Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow)
700 if (setLocation && setSize)
701 DataGridView.EditingControl.Bounds = cellBounds;
702 else if (setLocation)
703 DataGridView.EditingControl.Location = cellBounds.Location;
705 DataGridView.EditingControl.Size = cellBounds.Size;
708 [EditorBrowsable (EditorBrowsableState.Advanced)]
709 public virtual Rectangle PositionEditingPanel (Rectangle cellBounds, Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) {
710 throw new NotImplementedException();
713 public override string ToString () {
714 return String.Format("{0} {RowIndex = {1}, ColumnIndex = {2}}", this.GetType().FullName, RowIndex, columnIndex);
717 protected virtual Rectangle BorderWidths (DataGridViewAdvancedBorderStyle advancedBorderStyle)
719 Rectangle r = Rectangle.Empty;
721 r.X = BorderToWidth (advancedBorderStyle.Left);
722 r.Y = BorderToWidth (advancedBorderStyle.Top);
723 r.Width = BorderToWidth (advancedBorderStyle.Right);
724 r.Height = BorderToWidth (advancedBorderStyle.Bottom);
726 if (OwningColumn != null)
727 r.Width += OwningColumn.DividerWidth;
728 if (OwningRow != null)
729 r.Height += OwningRow.DividerHeight;
734 private int BorderToWidth (DataGridViewAdvancedCellBorderStyle style)
737 case DataGridViewAdvancedCellBorderStyle.None:
739 case DataGridViewAdvancedCellBorderStyle.NotSet:
740 case DataGridViewAdvancedCellBorderStyle.Single:
741 case DataGridViewAdvancedCellBorderStyle.Inset:
742 case DataGridViewAdvancedCellBorderStyle.Outset:
743 case DataGridViewAdvancedCellBorderStyle.OutsetPartial:
746 case DataGridViewAdvancedCellBorderStyle.InsetDouble:
747 case DataGridViewAdvancedCellBorderStyle.OutsetDouble:
752 protected virtual bool ClickUnsharesRow (DataGridViewCellEventArgs e)
757 protected virtual bool ContentClickUnsharesRow (DataGridViewCellEventArgs e)
762 protected virtual bool ContentDoubleClickUnsharesRow (DataGridViewCellEventArgs e)
767 protected virtual AccessibleObject CreateAccessibilityInstance () {
768 return new DataGridViewCellAccessibleObject(this);
771 protected virtual void Dispose (bool disposing) {
774 protected virtual bool DoubleClickUnsharesRow (DataGridViewCellEventArgs e)
779 protected virtual bool EnterUnsharesRow (int rowIndex, bool throughMouseClick)
784 protected virtual object GetClipboardContent (int rowIndex, bool firstCell, bool lastCell, bool inFirstRow, bool inLastRow, string format) {
785 if (DataGridView == null)
788 if (rowIndex < 0 || rowIndex >= DataGridView.RowCount)
789 throw new ArgumentOutOfRangeException ("rowIndex", "Specified argument was out of the range of valid values.");
794 DataGridViewCellStyle style = GetInheritedStyle (null, rowIndex, false);
795 value = GetEditedFormattedValue (rowIndex, DataGridViewDataErrorContexts.ClipboardContent | DataGridViewDataErrorContexts.Formatting) as string;
799 value = string.Empty;
801 string table_prefix = string.Empty, cell_prefix = string.Empty, row_prefix = string.Empty;
802 string table_suffix = string.Empty, cell_suffix = string.Empty, row_suffix = string.Empty;
804 if (format == DataFormats.UnicodeText || format == DataFormats.Text) {
805 if (lastCell && !inLastRow)
806 cell_suffix = Environment.NewLine;
809 } else if (format == DataFormats.CommaSeparatedValue) {
810 if (lastCell && !inLastRow)
811 cell_suffix = Environment.NewLine;
814 } else if (format == DataFormats.Html) {
815 if (inFirstRow && firstCell)
816 table_prefix = "<TABLE>";
817 if (inLastRow && lastCell)
818 table_suffix = "</TABLE>";
822 row_suffix = "</TR>";
823 cell_prefix = "<TD>";
824 cell_suffix = "</TD>";
833 value = table_prefix + row_prefix + cell_prefix + value + cell_suffix + row_suffix + table_suffix;
838 internal object GetClipboardContentInternal (int rowIndex, bool firstCell, bool lastCell, bool inFirstRow, bool inLastRow, string format) {
839 return GetClipboardContent (rowIndex, firstCell, lastCell, inFirstRow, inLastRow, format);
842 protected virtual Rectangle GetContentBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex) {
843 return Rectangle.Empty;
846 protected virtual Rectangle GetErrorIconBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)
848 return Rectangle.Empty;
851 protected internal virtual string GetErrorText (int rowIndex)
856 protected virtual object GetFormattedValue (object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
858 if (DataGridView == null)
861 if (rowIndex < 0 || rowIndex >= DataGridView.RowCount)
862 throw new ArgumentOutOfRangeException ("rowIndex");
864 // Give the user a chance to custom format
865 if (!(this is DataGridViewRowHeaderCell)) {
866 DataGridViewCellFormattingEventArgs e = new DataGridViewCellFormattingEventArgs (ColumnIndex, rowIndex, value, FormattedValueType, cellStyle);
867 DataGridView.OnCellFormattingInternal (e);
869 if (e.FormattingApplied)
872 cellStyle = e.CellStyle;
876 if (formattedValueTypeConverter == null)
877 formattedValueTypeConverter = FormattedValueTypeConverter;
878 if (valueTypeConverter == null)
879 valueTypeConverter = ValueTypeConverter;
881 if (valueTypeConverter != null && valueTypeConverter.CanConvertTo (FormattedValueType))
882 return valueTypeConverter.ConvertTo (value, FormattedValueType);
883 if (formattedValueTypeConverter != null && formattedValueTypeConverter.CanConvertFrom (ValueType))
884 return formattedValueTypeConverter.ConvertFrom (value);
886 return Convert.ChangeType (value, FormattedValueType);
889 protected virtual Size GetPreferredSize (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize)
891 return new Size (-1, -1);
894 protected virtual Size GetSize (int rowIndex)
897 throw new InvalidOperationException ("Getting the Size property of a cell in a shared row is not a valid operation.");
899 return new Size (OwningColumn.Width, OwningRow.Height);
902 protected virtual object GetValue (int rowIndex) {
903 if (DataGridView != null && (RowIndex < 0 || RowIndex >= DataGridView.Rows.Count))
904 throw new ArgumentOutOfRangeException ("rowIndex", "Specified argument was out of the range of valid values.");
906 if (DataProperty != null)
907 return DataProperty.GetValue (OwningRow.DataBoundItem);
912 DataGridViewCellValueEventArgs dgvcvea = new DataGridViewCellValueEventArgs (columnIndex, rowIndex);
913 if (DataGridView != null)
914 DataGridView.OnCellValueNeeded (dgvcvea);
915 return dgvcvea.Value;
918 private PropertyDescriptor DataProperty {
920 if (OwningColumn != null && !String.IsNullOrEmpty (OwningColumn.DataPropertyName) &&
921 OwningRow != null && OwningRow.DataBoundItem != null)
922 return TypeDescriptor.GetProperties (OwningRow.DataBoundItem)[OwningColumn.DataPropertyName];
927 private TypeConverter FormattedValueTypeConverter {
929 if (FormattedValueType != null)
930 return TypeDescriptor.GetConverter (FormattedValueType);
935 private TypeConverter ValueTypeConverter {
937 if (DataProperty != null && DataProperty.Converter != null)
938 return DataProperty.Converter;
940 return TypeDescriptor.GetConverter (Value);
941 if (ValueType != null)
942 return TypeDescriptor.GetConverter (ValueType);
947 protected virtual bool KeyDownUnsharesRow (KeyEventArgs e, int rowIndex)
952 protected virtual bool KeyPressUnsharesRow (KeyPressEventArgs e, int rowIndex)
957 protected virtual bool KeyUpUnsharesRow (KeyEventArgs e, int rowIndex)
962 protected virtual bool LeaveUnsharesRow (int rowIndex, bool throughMouseClick)
967 protected virtual bool MouseClickUnsharesRow (DataGridViewCellMouseEventArgs e)
972 protected virtual bool MouseDoubleClickUnsharesRow (DataGridViewCellMouseEventArgs e)
977 protected virtual bool MouseDownUnsharesRow (DataGridViewCellMouseEventArgs e)
982 protected virtual bool MouseEnterUnsharesRow (int rowIndex)
987 protected virtual bool MouseLeaveUnsharesRow (int rowIndex)
992 protected virtual bool MouseMoveUnsharesRow (DataGridViewCellMouseEventArgs e)
997 protected virtual bool MouseUpUnsharesRow (DataGridViewCellMouseEventArgs e)
1002 protected virtual void OnClick (DataGridViewCellEventArgs e) {
1005 internal void OnClickInternal (DataGridViewCellEventArgs e) {
1009 protected virtual void OnContentClick (DataGridViewCellEventArgs e) {
1012 internal void OnContentClickInternal (DataGridViewCellEventArgs e) {
1016 protected virtual void OnContentDoubleClick (DataGridViewCellEventArgs e) {
1019 internal void OnContentDoubleClickInternal (DataGridViewCellEventArgs e) {
1020 OnContentDoubleClick (e);
1023 protected override void OnDataGridViewChanged () {
1026 internal void OnDataGridViewChangedInternal () {
1027 OnDataGridViewChanged ();
1030 protected virtual void OnDoubleClick (DataGridViewCellEventArgs e) {
1033 internal void OnDoubleClickInternal (DataGridViewCellEventArgs e) {
1037 protected virtual void OnEnter (int rowIndex, bool throughMouseClick) {
1040 internal void OnEnterInternal (int rowIndex, bool throughMouseClick) {
1041 OnEnter (rowIndex, throughMouseClick);
1044 protected virtual void OnKeyDown (KeyEventArgs e, int rowIndex) {
1047 internal void OnKeyDownInternal (KeyEventArgs e, int rowIndex) {
1048 OnKeyDown (e, rowIndex);
1051 protected virtual void OnKeyPress (KeyPressEventArgs e, int rowIndex) {
1054 internal void OnKeyPressInternal (KeyPressEventArgs e, int rowIndex) {
1055 OnKeyPress (e, rowIndex);
1058 protected virtual void OnKeyUp (KeyEventArgs e, int rowIndex) {
1061 internal void OnKeyUpInternal (KeyEventArgs e, int rowIndex) {
1062 OnKeyUp (e, rowIndex);
1065 protected virtual void OnLeave (int rowIndex, bool throughMouseClick) {
1068 internal void OnLeaveInternal (int rowIndex, bool throughMouseClick) {
1069 OnLeave (rowIndex, throughMouseClick);
1072 protected virtual void OnMouseClick (DataGridViewCellMouseEventArgs e) {
1075 internal void OnMouseClickInternal (DataGridViewCellMouseEventArgs e) {
1079 protected virtual void OnMouseDoubleClick (DataGridViewCellMouseEventArgs e) {
1082 internal void OnMouseDoubleClickInternal (DataGridViewCellMouseEventArgs e) {
1083 OnMouseDoubleClick (e);
1086 protected virtual void OnMouseDown (DataGridViewCellMouseEventArgs e) {
1089 internal void OnMouseDownInternal (DataGridViewCellMouseEventArgs e) {
1093 protected virtual void OnMouseEnter (int rowIndex) {
1096 internal void OnMouseEnterInternal (int rowIndex) {
1097 OnMouseEnter (rowIndex) ;
1100 protected virtual void OnMouseLeave (int rowIndex) {
1103 internal void OnMouseLeaveInternal (int e) {
1107 protected virtual void OnMouseMove (DataGridViewCellMouseEventArgs e) {
1110 internal void OnMouseMoveInternal (DataGridViewCellMouseEventArgs e) {
1114 protected virtual void OnMouseUp (DataGridViewCellMouseEventArgs e) {
1117 internal void OnMouseUpInternal (DataGridViewCellMouseEventArgs e) {
1121 internal void PaintInternal (Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
1123 Paint (graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
1126 protected virtual void Paint (Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
1128 if ((paintParts & DataGridViewPaintParts.Background) == DataGridViewPaintParts.Background)
1129 PaintPartBackground (graphics, cellBounds, cellStyle);
1130 if ((paintParts & DataGridViewPaintParts.SelectionBackground) == DataGridViewPaintParts.SelectionBackground)
1131 PaintPartSelectionBackground (graphics, cellBounds, cellState, cellStyle);
1132 if ((paintParts & DataGridViewPaintParts.ContentForeground) == DataGridViewPaintParts.ContentForeground)
1133 PaintPartContent (graphics, cellBounds, rowIndex, cellState, cellStyle, formattedValue);
1134 if ((paintParts & DataGridViewPaintParts.Border) == DataGridViewPaintParts.Border)
1135 PaintBorder (graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);
1136 if ((paintParts & DataGridViewPaintParts.Focus) == DataGridViewPaintParts.Focus)
1137 PaintPartFocus (graphics, cellBounds);
1138 if ((paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon)
1139 if (!string.IsNullOrEmpty (ErrorText))
1140 PaintErrorIcon (graphics, clipBounds, cellBounds, ErrorText);
1143 protected virtual void PaintBorder (Graphics graphics, Rectangle clipBounds, Rectangle bounds, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle)
1145 Pen pen = new Pen (DataGridView.GridColor);
1147 // Paint the left border, if any
1148 switch (advancedBorderStyle.Left) {
1149 case DataGridViewAdvancedCellBorderStyle.Single:
1150 if (DataGridView.CellBorderStyle != DataGridViewCellBorderStyle.Single)
1151 graphics.DrawLine (pen, bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height - 1);
1153 case DataGridViewAdvancedCellBorderStyle.Inset:
1154 graphics.DrawLine(pen, bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height - 1);
1156 case DataGridViewAdvancedCellBorderStyle.InsetDouble:
1157 case DataGridViewAdvancedCellBorderStyle.Outset:
1158 case DataGridViewAdvancedCellBorderStyle.OutsetDouble:
1159 graphics.DrawLine(pen, bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height - 1);
1160 graphics.DrawLine(pen, bounds.X + 2, bounds.Y, bounds.X + 2, bounds.Y + bounds.Height - 1);
1164 // Paint the right border, if any
1165 switch (advancedBorderStyle.Right) {
1166 case DataGridViewAdvancedCellBorderStyle.Single:
1167 graphics.DrawLine(pen, bounds.X + bounds.Width - 1, bounds.Y, bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
1169 case DataGridViewAdvancedCellBorderStyle.Inset:
1170 graphics.DrawLine(pen, bounds.X + bounds.Width, bounds.Y, bounds.X + bounds.Width, bounds.Y + bounds.Height - 1);
1174 // Paint the top border, if any
1175 switch (advancedBorderStyle.Top) {
1176 case DataGridViewAdvancedCellBorderStyle.Single:
1177 if (DataGridView.CellBorderStyle != DataGridViewCellBorderStyle.Single)
1178 graphics.DrawLine(pen, bounds.X, bounds.Y, bounds.X + bounds.Width - 1, bounds.Y);
1180 case DataGridViewAdvancedCellBorderStyle.Inset:
1181 graphics.DrawLine(pen, bounds.X, bounds.Y, bounds.X + bounds.Width - 1, bounds.Y);
1185 // Paint the bottom border, if any
1186 switch (advancedBorderStyle.Bottom) {
1187 case DataGridViewAdvancedCellBorderStyle.Single:
1188 graphics.DrawLine(pen, bounds.X, bounds.Y + bounds.Height - 1, bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
1193 protected virtual void PaintErrorIcon (Graphics graphics, Rectangle clipBounds, Rectangle cellValueBounds, string errorText)
1195 Rectangle error_bounds = GetErrorIconBounds (graphics, null, RowIndex);
1197 if (error_bounds.IsEmpty)
1200 Point loc = error_bounds.Location;
1201 loc.X += cellValueBounds.Left;
1202 loc.Y += cellValueBounds.Top;
1204 graphics.FillRectangle (Brushes.Red, new Rectangle (loc.X + 1, loc.Y + 2, 10, 7));
1205 graphics.FillRectangle (Brushes.Red, new Rectangle (loc.X + 2, loc.Y + 1, 8, 9));
1206 graphics.FillRectangle (Brushes.Red, new Rectangle (loc.X + 4, loc.Y, 4, 11));
1207 graphics.FillRectangle (Brushes.Red, new Rectangle (loc.X, loc.Y + 4, 12, 3));
1209 graphics.FillRectangle (Brushes.White, new Rectangle (loc.X + 5, loc.Y + 2, 2, 4));
1210 graphics.FillRectangle (Brushes.White, new Rectangle (loc.X + 5, loc.Y + 7, 2, 2));
1213 internal virtual void PaintPartBackground (Graphics graphics, Rectangle cellBounds, DataGridViewCellStyle style)
1215 Color color = style.BackColor;
1216 graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (color), cellBounds);
1219 internal Pen GetBorderPen ()
1221 return ThemeEngine.Current.ResPool.GetPen (DataGridView.GridColor);
1224 internal virtual void PaintPartContent (Graphics graphics, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, object formattedValue)
1229 Color color = Selected ? cellStyle.SelectionForeColor : cellStyle.ForeColor;
1231 TextFormatFlags flags = TextFormatFlags.EndEllipsis | TextFormatFlags.VerticalCenter | TextFormatFlags.TextBoxControl;
1232 flags |= AlignmentToFlags (style.Alignment);
1234 cellBounds.Height -= 2;
1235 cellBounds.Width -= 2;
1237 if (formattedValue != null)
1238 TextRenderer.DrawText (graphics, formattedValue.ToString (), cellStyle.Font, cellBounds, color, flags);
1241 private void PaintPartFocus (Graphics graphics, Rectangle cellBounds)
1244 cellBounds.Height--;
1246 if (DataGridView.ShowFocusCues && DataGridView.CurrentCell == this && DataGridView.Focused)
1247 ControlPaint.DrawFocusRectangle (graphics, cellBounds);
1250 internal virtual void PaintPartSelectionBackground (Graphics graphics, Rectangle cellBounds, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle)
1252 if ((cellState & DataGridViewElementStates.Selected) != DataGridViewElementStates.Selected)
1255 if (RowIndex >= 0 && IsInEditMode && EditType != null)
1258 Color color = cellStyle.SelectionBackColor;
1259 graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (color), cellBounds);
1262 internal void PaintWork (Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
1265 object formattedvalue;
1267 if (RowIndex == -1 && !(this is DataGridViewColumnHeaderCell)) {
1269 formattedvalue = null;
1270 } else if (RowIndex == -1) {
1272 formattedvalue = Value;
1275 formattedvalue = GetFormattedValue (Value, rowIndex, ref cellStyle, null, null, DataGridViewDataErrorContexts.Formatting);
1278 DataGridViewCellPaintingEventArgs pea = new DataGridViewCellPaintingEventArgs (DataGridView, graphics, clipBounds, cellBounds, rowIndex, columnIndex, cellState, value, formattedvalue, ErrorText, cellStyle, advancedBorderStyle, paintParts);
1279 DataGridView.OnCellPaintingInternal (pea);
1284 pea.Paint (pea.ClipBounds, pea.PaintParts);
1287 protected virtual bool SetValue (int rowIndex, object value)
1289 object oldValue = this.Value;
1291 if (DataProperty != null && !DataProperty.IsReadOnly)
1292 DataProperty.SetValue (OwningRow.DataBoundItem, value);
1296 if (oldValue != value) {
1297 RaiseCellValueChanged (new DataGridViewCellEventArgs (ColumnIndex, RowIndex));
1299 // Set this dirty flag back to false
1300 if (this is IDataGridViewEditingCell)
1301 (this as IDataGridViewEditingCell).EditingCellValueChanged = false;
1303 if (DataGridView != null)
1304 DataGridView.InvalidateCell (this);
1311 private void OnStyleChanged (object sender, EventArgs args) {
1312 if (DataGridView != null) {
1313 DataGridView.RaiseCellStyleChanged(new DataGridViewCellEventArgs(ColumnIndex, RowIndex));
1317 internal virtual Rectangle InternalErrorIconsBounds {
1318 get { return GetErrorIconBounds (null, null, -1); }
1321 internal void InternalPaint (Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) {
1322 Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
1325 internal void SetOwningRow (DataGridViewRow row) {
1329 internal void SetOwningColumn (DataGridViewColumn col) {
1330 columnIndex = col.Index;
1333 internal void SetColumnIndex (int index) {
1334 columnIndex = index;
1337 internal void SetIsInEditMode (bool isInEditMode) {
1338 this.isInEditMode = isInEditMode;
1341 internal void OnErrorTextChanged (DataGridViewCellEventArgs args) {
1342 if (DataGridView != null) {
1343 DataGridView.OnCellErrorTextChanged(args);
1347 internal TextFormatFlags AlignmentToFlags (DataGridViewContentAlignment align)
1349 TextFormatFlags flags = TextFormatFlags.Default;
1352 case DataGridViewContentAlignment.BottomCenter:
1353 flags |= TextFormatFlags.Bottom;
1354 flags |= TextFormatFlags.HorizontalCenter;
1356 case DataGridViewContentAlignment.BottomLeft:
1357 flags |= TextFormatFlags.Bottom;
1359 case DataGridViewContentAlignment.BottomRight:
1360 flags |= TextFormatFlags.Bottom;
1361 flags |= TextFormatFlags.Right;
1363 case DataGridViewContentAlignment.MiddleCenter:
1364 flags |= TextFormatFlags.VerticalCenter;
1365 flags |= TextFormatFlags.HorizontalCenter;
1367 case DataGridViewContentAlignment.MiddleLeft:
1368 flags |= TextFormatFlags.VerticalCenter;
1370 case DataGridViewContentAlignment.MiddleRight:
1371 flags |= TextFormatFlags.VerticalCenter;
1372 flags |= TextFormatFlags.Right;
1374 case DataGridViewContentAlignment.TopLeft:
1375 flags |= TextFormatFlags.Top;
1377 case DataGridViewContentAlignment.TopCenter:
1378 flags |= TextFormatFlags.HorizontalCenter;
1379 flags |= TextFormatFlags.Top;
1381 case DataGridViewContentAlignment.TopRight:
1382 flags |= TextFormatFlags.Right;
1383 flags |= TextFormatFlags.Top;
1390 internal Rectangle AlignInRectangle (Rectangle outer, Size inner, DataGridViewContentAlignment align)
1395 if (align == DataGridViewContentAlignment.BottomLeft || align == DataGridViewContentAlignment.MiddleLeft || align == DataGridViewContentAlignment.TopLeft)
1397 else if (align == DataGridViewContentAlignment.BottomCenter || align == DataGridViewContentAlignment.MiddleCenter || align == DataGridViewContentAlignment.TopCenter)
1398 x = Math.Max (outer.X + ((outer.Width - inner.Width) / 2), outer.Left);
1399 else if (align == DataGridViewContentAlignment.BottomRight || align == DataGridViewContentAlignment.MiddleRight || align == DataGridViewContentAlignment.TopRight)
1400 x = outer.Right - inner.Width;
1401 if (align == DataGridViewContentAlignment.TopCenter || align == DataGridViewContentAlignment.TopLeft || align == DataGridViewContentAlignment.TopRight)
1403 else if (align == DataGridViewContentAlignment.MiddleCenter || align == DataGridViewContentAlignment.MiddleLeft || align == DataGridViewContentAlignment.MiddleRight)
1404 y = outer.Y + (outer.Height - inner.Height) / 2;
1405 else if (align == DataGridViewContentAlignment.BottomCenter || align == DataGridViewContentAlignment.BottomRight || align == DataGridViewContentAlignment.BottomLeft)
1406 y = outer.Bottom - inner.Height;
1408 return new Rectangle (x, y, Math.Min (inner.Width, outer.Width), Math.Min (inner.Height, outer.Height));
1411 [ComVisibleAttribute(true)]
1412 protected class DataGridViewCellAccessibleObject : AccessibleObject {
1414 private DataGridViewCell dataGridViewCell;
1416 public DataGridViewCellAccessibleObject () {
1419 public DataGridViewCellAccessibleObject (DataGridViewCell owner) {
1420 this.dataGridViewCell = owner;
1423 public override Rectangle Bounds {
1424 get { throw new NotImplementedException(); }
1427 public override string DefaultAction {
1428 get { return "Edit"; }
1431 public override string Help {
1432 get { return base.Help; }
1435 public override string Name {
1436 get { return dataGridViewCell.OwningColumn.HeaderText + ": " + dataGridViewCell.RowIndex.ToString(); }
1439 public DataGridViewCell Owner {
1440 get { return dataGridViewCell; }
1441 set { dataGridViewCell = value; }
1444 public override AccessibleObject Parent {
1445 get { return dataGridViewCell.OwningRow.AccessibilityObject; }
1448 public override AccessibleRole Role {
1449 get { return AccessibleRole.Cell; }
1452 public override AccessibleStates State {
1454 if (dataGridViewCell.Selected) {
1455 return AccessibleStates.Selected;
1458 return AccessibleStates.Focused;
1463 public override string Value {
1465 if (dataGridViewCell.FormattedValue == null) {
1468 return dataGridViewCell.FormattedValue.ToString();
1472 throw new InvalidOperationException ("owner is null");
1474 throw new NotImplementedException ();
1478 public override void DoDefaultAction () {
1479 if (dataGridViewCell.DataGridView.EditMode != DataGridViewEditMode.EditProgrammatically) {
1480 if (dataGridViewCell.IsInEditMode) {
1489 public override AccessibleObject GetChild (int index) {
1490 throw new NotImplementedException();
1493 public override int GetChildCount () {
1494 if (dataGridViewCell.IsInEditMode) {
1500 public override AccessibleObject GetFocused () {
1504 public override AccessibleObject GetSelected () {
1508 public override AccessibleObject Navigate (AccessibleNavigation navigationDirection) {
1509 switch (navigationDirection) {
1510 case AccessibleNavigation.Right:
1512 case AccessibleNavigation.Left:
1514 case AccessibleNavigation.Next:
1516 case AccessibleNavigation.Previous:
1518 case AccessibleNavigation.Up:
1520 case AccessibleNavigation.Down:
1528 public override void Select (AccessibleSelection flags) {
1530 case AccessibleSelection.TakeFocus:
1531 dataGridViewCell.dataGridViewOwner.Focus();
1533 case AccessibleSelection.TakeSelection:
1534 //dataGridViewCell.Focus();
1536 case AccessibleSelection.AddSelection:
1537 dataGridViewCell.dataGridViewOwner.SelectedCells.InternalAdd(dataGridViewCell);
1539 case AccessibleSelection.RemoveSelection:
1540 dataGridViewCell.dataGridViewOwner.SelectedCells.InternalRemove(dataGridViewCell);
1548 internal class DataGridViewCellConverter : TypeConverter