Fix bug #395
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridViewCell.cs
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:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
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.
19 //
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Author:
23 //      Pedro Martínez Juliá <pedromj@gmail.com>
24 //      Ivan N. Zlatev  <contact@i-nz.net>
25 //
26
27
28
29 using System;
30 using System.Drawing;
31 using System.ComponentModel;
32 using System.Runtime.InteropServices;
33
34 namespace System.Windows.Forms {
35
36         [TypeConverter (typeof (DataGridViewCellConverter))]
37         public abstract class DataGridViewCell : DataGridViewElement, ICloneable, IDisposable
38         {
39                 private DataGridView dataGridViewOwner;
40
41                 private AccessibleObject accessibilityObject;
42                 private int columnIndex;
43                 private ContextMenuStrip contextMenuStrip;
44                 private bool displayed;
45                 private string errorText;
46                 private bool isInEditMode;
47                 private DataGridViewRow owningRow;
48                 private DataGridViewTriState readOnly;
49                 private bool selected;
50                 private DataGridViewCellStyle style;
51                 private object tag;
52                 private string toolTipText;
53                 private object valuex;
54                 private Type valueType;
55
56                 protected DataGridViewCell ()
57                 {
58                         columnIndex = -1;
59                         dataGridViewOwner = null;
60                         errorText = string.Empty;
61                 }
62
63                 ~DataGridViewCell ()
64                 {
65                         Dispose(false);
66                 }
67
68                 [Browsable (false)]
69                 public AccessibleObject AccessibilityObject {
70                         get {
71                                 if (accessibilityObject == null) {
72                                         accessibilityObject = CreateAccessibilityInstance();
73                                 }
74                                 return accessibilityObject;
75                         }
76                 }
77
78                 public int ColumnIndex {
79                         get { 
80                                 if (DataGridView == null)
81                                         return -1;
82                                 return columnIndex; 
83                         }
84                 }
85
86                 [Browsable (false)]
87                 public Rectangle ContentBounds {
88                         get { 
89                                 return GetContentBounds (RowIndex);
90                         }
91                 }
92
93                 [DefaultValue (null)]
94                 public virtual ContextMenuStrip ContextMenuStrip {
95                         get { return contextMenuStrip; }
96                         set { contextMenuStrip = value; }
97                 }
98
99                 [Browsable (false)]
100                 public virtual object DefaultNewRowValue {
101                         get { return null; }
102                 }
103
104                 [Browsable (false)]
105                 public virtual bool Displayed {
106                         get { return displayed; }
107                 }
108
109                 [Browsable (false)]
110                 [EditorBrowsable (EditorBrowsableState.Advanced)]
111                 public object EditedFormattedValue {
112                         get { 
113                                 return GetEditedFormattedValue (RowIndex, DataGridViewDataErrorContexts.Formatting);
114                         }
115                 }
116
117                 [Browsable (false)]
118                 [EditorBrowsable (EditorBrowsableState.Advanced)]
119                 public virtual Type EditType {
120                         get {
121                                 return typeof (DataGridViewTextBoxEditingControl);
122                         }
123                 }
124
125                 [Browsable (false)]
126                 [EditorBrowsable (EditorBrowsableState.Advanced)]
127                 public Rectangle ErrorIconBounds {
128                         get {
129                                 if (this is DataGridViewTopLeftHeaderCell)
130                                         return GetErrorIconBounds (null, null, RowIndex);
131
132                                 if (DataGridView == null || columnIndex < 0)
133                                         throw new InvalidOperationException ();
134                                 if (RowIndex < 0 || RowIndex >= DataGridView.Rows.Count)
135                                         throw new ArgumentOutOfRangeException ("rowIndex", "Specified argument was out of the range of valid values.");
136
137                                 return GetErrorIconBounds (null, null, RowIndex);
138                         }
139                 }
140
141                 [Browsable (false)]
142                 public string ErrorText {
143                         get { 
144                                 if (this is DataGridViewTopLeftHeaderCell)
145                                         return GetErrorText (-1);
146                                         
147                                 if (OwningRow == null)
148                                         return string.Empty;
149                                         
150                                 return GetErrorText (OwningRow.Index); 
151                         }
152                         set {
153                                 if (errorText != value) {
154                                         errorText = value;
155                                         OnErrorTextChanged(new DataGridViewCellEventArgs(ColumnIndex, RowIndex));
156                                 }
157                         }
158                 }
159
160                 [Browsable (false)]
161                 public object FormattedValue {
162                         get {
163                                 if (DataGridView == null)
164                                         return null;
165                                 
166                                 DataGridViewCellStyle style = InheritedStyle;
167                                 return GetFormattedValue (Value, RowIndex, ref style, null, null, DataGridViewDataErrorContexts.Formatting);
168                         }
169                 }
170
171                 [Browsable (false)]
172                 public virtual Type FormattedValueType {
173                         get { return null; }
174                 }
175
176                 [Browsable (false)]
177                 public virtual bool Frozen {
178                         get {
179                                 if (DataGridView == null)
180                                         return false;
181                                 
182                                 if (RowIndex >= 0)
183                                         return OwningRow.Frozen && OwningColumn.Frozen;
184                                         
185                                 return false;
186                         }
187                 }
188
189                 [Browsable (false)]
190                 public bool HasStyle {
191                         get { return style != null; }
192                 }
193
194                 [Browsable (false)]
195                 public DataGridViewElementStates InheritedState {
196                         get { 
197                                 return GetInheritedState (RowIndex);
198                         }
199                 }
200
201                 [Browsable (false)]
202                 public DataGridViewCellStyle InheritedStyle {
203                         get {
204                                 return GetInheritedStyle (null, RowIndex, true);
205                         }
206                 }
207
208                 [Browsable (false)]
209                 public bool IsInEditMode {
210                         get {
211                                 if (DataGridView == null)
212                                         return false;
213                                         
214                                 if (RowIndex == -1)
215                                         throw new InvalidOperationException ("Operation cannot be performed on a cell of a shared row.");
216                                         
217                                 return isInEditMode;
218                         }
219                 }
220
221                 [Browsable (false)]
222                 [EditorBrowsable (EditorBrowsableState.Advanced)]
223                 public DataGridViewColumn OwningColumn {
224                         get {
225                                 if (DataGridView == null || columnIndex < 0 || columnIndex >= DataGridView.Columns.Count)
226                                         return null;
227                                         
228                                 return DataGridView.Columns[columnIndex];
229                         }
230                 }
231
232                 [Browsable (false)]
233                 [EditorBrowsable (EditorBrowsableState.Advanced)]
234                 public DataGridViewRow OwningRow {
235                         get { return owningRow; }
236                 }
237
238                 [Browsable (false)]
239                 public Size PreferredSize {
240                         get { 
241                                 if (DataGridView == null)
242                                         return new Size (-1, -1);
243                                         
244                                 return GetPreferredSize (Hwnd.GraphicsContext, InheritedStyle, RowIndex, Size.Empty); 
245                         }
246                 }
247
248                 [Browsable (false)]
249                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
250                 public virtual bool ReadOnly {
251                         get {
252                                 if (DataGridView != null && DataGridView.ReadOnly)
253                                         return true;
254                                 
255                                 if (readOnly != DataGridViewTriState.NotSet)
256                                         return readOnly == DataGridViewTriState.True;
257                                         
258                                 if (OwningRow != null && !OwningRow.IsShared && OwningRow.ReadOnly)
259                                         return true;
260                                 
261                                 if (OwningColumn != null && OwningColumn.ReadOnly)
262                                         return true;
263                                         
264                                 return false;
265                         }
266                         set {
267                                 readOnly = value ? DataGridViewTriState.True : DataGridViewTriState.False;
268                                 if (value) {
269                                         SetState (DataGridViewElementStates.ReadOnly | State);
270                                 } else {
271                                         SetState (~DataGridViewElementStates.ReadOnly & State);
272                                 }
273                         }
274                 }
275
276                 [Browsable (false)]
277                 public virtual bool Resizable {
278                         get {
279                                 if (DataGridView == null)
280                                         return false;
281
282                                 // Shared cells aren't resizable
283                                 if (RowIndex == -1 || columnIndex == -1)
284                                         return false;
285                                         
286                                 return OwningRow.Resizable == DataGridViewTriState.True || OwningColumn.Resizable == DataGridViewTriState.True; 
287                         }
288                 }
289
290                 [Browsable (false)]
291                 public int RowIndex {
292                         get {
293                                 if (owningRow == null) {
294                                         return -1;
295                                 }
296                                 return owningRow.Index;
297                         }
298                 }
299
300                 [Browsable (false)]
301                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
302                 public virtual bool Selected {
303                         get {
304                                 if (selected)
305                                         return true;
306                                 
307                                 if (DataGridView != null) {
308                                         if (RowIndex >= 0 && RowIndex < DataGridView.Rows.Count && DataGridView.Rows [RowIndex].Selected)
309                                                 return true;
310                                                 
311                                         if (ColumnIndex >= 0 && ColumnIndex < DataGridView.Columns.Count && DataGridView.Columns [ColumnIndex].Selected)
312                                                 return true;
313                                 }
314                                 
315                                 return false;
316                         }
317                         set {
318                                 bool changed = selected != value;
319                                 selected = value;
320
321                                 if (value != ((State & DataGridViewElementStates.Selected) != 0))
322                                         SetState(State ^ DataGridViewElementStates.Selected);
323                                 
324                                 // If our row is selected, unselect it and select
325                                 // the first cell in it that isn't us
326                                 if (!selected && OwningRow != null && OwningRow.Selected) {
327                                         OwningRow.Selected = false;
328                                         
329                                         if (columnIndex != 0 && OwningRow.Cells.Count > 0)
330                                                 OwningRow.Cells[0].Selected = true;
331                                         else if (OwningRow.Cells.Count > 1)
332                                                 OwningRow.Cells[1].Selected = true;
333                                 }
334
335                                 if (changed && DataGridView != null && DataGridView.IsHandleCreated)
336                                         DataGridView.Invalidate ();
337                         }
338                 }
339
340                 [Browsable (false)]
341                 public Size Size {
342                         get {
343                                 if (DataGridView == null)
344                                         return new Size (-1, -1);
345                                         
346                                 return GetSize (RowIndex);
347                         }
348                 }
349
350                 [Browsable (true)]
351                 public DataGridViewCellStyle Style {
352                         get {
353                                 if (style == null) {
354                                         style = new DataGridViewCellStyle();
355                                         style.StyleChanged += OnStyleChanged;
356                                 }
357                                 return style;
358                         }
359                         set { style = value; }
360                 }
361
362                 [Bindable (true, BindingDirection.OneWay)]
363                 [DefaultValue (null)]
364                 [Localizable (false)]
365                 [TypeConverter ("System.ComponentModel.StringConverter, " + Consts.AssemblySystem)]
366                 public object Tag {
367                         get { return tag; }
368                         set { tag = value; }
369                 }
370
371                 [Browsable (false)]
372                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
373                 public string ToolTipText {
374                         get { return toolTipText == null ? string.Empty : toolTipText; }
375                         set { toolTipText = value; }
376                 }
377
378                 [Browsable (false)]
379                 public object Value {
380                         get {
381                                 return GetValue (RowIndex);
382                         }
383                         set {
384                                 SetValue (RowIndex, value);
385                         }
386                 }
387
388                 [Browsable (false)]
389                 public virtual Type ValueType {
390                         get { 
391                                 if (valueType == null) {
392                                         if (DataProperty != null)
393                                                 valueType = DataProperty.PropertyType;
394                                         else if (OwningColumn != null)
395                                                 valueType = OwningColumn.ValueType;
396                                 }
397
398                                 return valueType;
399                         }
400                         set { valueType = value; }
401                 }
402
403                 [Browsable (false)]
404                 public virtual bool Visible {
405                         get {
406                                 // This is independent from State...
407                                 DataGridViewColumn col = OwningColumn;
408                                 DataGridViewRow row = OwningRow;
409                                 
410                                 bool rowVisible = true, colVisible = true;
411                                 
412                                 if (row == null && col == null)
413                                         return false;
414                                 
415                                 if (row != null) {
416                                         rowVisible = !row.IsShared && row.Visible;
417                                 }
418                                 
419                                 if (col != null) {
420                                         colVisible = col.Index >= 0 && col.Visible;
421                                 }
422                                 
423                                 return rowVisible && colVisible;
424                         }
425                 }
426
427                 internal override void SetState (DataGridViewElementStates state) {
428                         base.SetState (state);
429                         if (DataGridView != null)
430                                 DataGridView.OnCellStateChangedInternal (new DataGridViewCellStateChangedEventArgs (this, state));
431                 }
432
433                 [EditorBrowsable (EditorBrowsableState.Advanced)]
434                 public virtual DataGridViewAdvancedBorderStyle AdjustCellBorderStyle (DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStyleInput,     DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) {
435                         return dataGridViewAdvancedBorderStyleInput;
436                 }
437
438                 public virtual object Clone ()
439                 {
440                         DataGridViewCell result = (DataGridViewCell) Activator.CreateInstance (GetType ());
441                         result.accessibilityObject = this.accessibilityObject;
442                         result.columnIndex = this.columnIndex;
443                         result.displayed = this.displayed;
444                         result.errorText = this.errorText;
445                         result.isInEditMode = this.isInEditMode;
446                         result.owningRow = this.owningRow;
447                         result.readOnly = this.readOnly;
448                         result.selected = this.selected;
449                         result.style = this.style;
450                         result.tag = this.tag;
451                         result.toolTipText = this.toolTipText;
452                         result.valuex = this.valuex;
453                         result.valueType = this.valueType;
454                         return result;
455                 }
456
457                 [EditorBrowsable (EditorBrowsableState.Advanced)]
458                 public virtual void DetachEditingControl ()
459                 {
460                 }
461
462                 public void Dispose ()
463                 {
464                 }
465
466                 public Rectangle GetContentBounds (int rowIndex)
467                 {
468                         if (DataGridView == null)
469                                 return Rectangle.Empty;
470                         
471                         return GetContentBounds (Hwnd.GraphicsContext, InheritedStyle, rowIndex);
472                 }
473
474                 public object GetEditedFormattedValue (int rowIndex, DataGridViewDataErrorContexts context)
475                 {
476                         if (DataGridView == null)
477                                 return null;
478                         
479                         if (rowIndex < 0 || rowIndex >= DataGridView.RowCount)
480                                 throw new ArgumentOutOfRangeException ("rowIndex", "Specified argument was out of the range of valid values.");
481                         
482                         // If we are in edit mode, this returns the value of the editing control
483                         // If we aren't in edit mode, return the cell's value
484                         // Basically, return what the user is currently seeing
485                         if (IsInEditMode) {
486                                 if (DataGridView.EditingControl != null)
487                                         return (DataGridView.EditingControl as IDataGridViewEditingControl).GetEditingControlFormattedValue (context);
488                                 else
489                                         return (this as IDataGridViewEditingCell).GetEditingCellFormattedValue (context);
490                         }
491                                 
492                         DataGridViewCellStyle style = InheritedStyle;
493                         
494                         return GetFormattedValue (GetValue (rowIndex), rowIndex, ref style, null, null, context);
495                 }
496
497                 public virtual ContextMenuStrip GetInheritedContextMenuStrip (int rowIndex)
498                 {
499                         if (DataGridView == null)
500                                 return null;
501                                 
502                         if (rowIndex < 0 || rowIndex >= DataGridView.Rows.Count)
503                                 throw new ArgumentOutOfRangeException ("rowIndex");
504                         if (columnIndex < 0)
505                                 throw new InvalidOperationException ("cannot perform this on a column header cell");
506                                 
507                         if (contextMenuStrip != null)
508                                 return contextMenuStrip;
509                         if (OwningRow.ContextMenuStrip != null)
510                                 return OwningRow.ContextMenuStrip;
511                         if (OwningColumn.ContextMenuStrip != null)
512                                 return OwningColumn.ContextMenuStrip;
513                                 
514                         return DataGridView.ContextMenuStrip;
515                 }
516
517                 public virtual DataGridViewElementStates GetInheritedState (int rowIndex)
518                 {
519                 
520                         if (DataGridView == null && rowIndex != -1)
521                                 throw new ArgumentException ("msg?");
522                         
523                         if (DataGridView != null && (rowIndex < 0 || rowIndex >= DataGridView.Rows.Count))
524                                 throw new ArgumentOutOfRangeException ("rowIndex", "Specified argument was out of the range of valid values.");
525                 
526                         DataGridViewElementStates result;
527                         
528                         result = DataGridViewElementStates.ResizableSet | State;
529                         
530                         DataGridViewColumn col = OwningColumn;
531                         DataGridViewRow row = OwningRow;
532
533                         if (DataGridView == null) {
534                                 if (row != null) {
535                                         if (row.Resizable == DataGridViewTriState.True)
536                                                 result |= DataGridViewElementStates.Resizable;
537                                                 
538                                         if (row.Visible)
539                                                 result |= DataGridViewElementStates.Visible;
540                                                 
541                                         if (row.ReadOnly)
542                                                 result |= DataGridViewElementStates.ReadOnly;
543                                                 
544                                         if (row.Frozen)
545                                                 result |= DataGridViewElementStates.Frozen;
546                                                 
547                                         if (row.Displayed)
548                                                 result |= DataGridViewElementStates.Displayed;
549                                                 
550                                         if (row.Selected)
551                                                 result |= DataGridViewElementStates.Selected;
552                                 }
553                                 
554                                 return result;
555                         }
556                         
557                         if (col != null) {
558                                 if (col.Resizable == DataGridViewTriState.True && row.Resizable == DataGridViewTriState.True)
559                                         result |= DataGridViewElementStates.Resizable;
560                                 
561                                 if (col.Visible && row.Visible)
562                                         result |= DataGridViewElementStates.Visible;
563
564                                 if (col.ReadOnly || row.ReadOnly)
565                                         result |= DataGridViewElementStates.ReadOnly;
566
567                                 if (col.Frozen || row.Frozen)
568                                         result |= DataGridViewElementStates.Frozen;
569
570                                 if (col.Displayed && row.Displayed)
571                                         result |= DataGridViewElementStates.Displayed;
572
573                                 if (col.Selected || row.Selected)
574                                         result |= DataGridViewElementStates.Selected;
575                         }
576                         
577                         return result;
578                 }
579
580                 public virtual DataGridViewCellStyle GetInheritedStyle (DataGridViewCellStyle inheritedCellStyle, int rowIndex, bool includeColors) {
581                         /*
582                          * System.InvalidOperationException :: The cell has no associated System.Windows.Forms.DataGridView, or the cell's System.Windows.Forms.DataGridViewCell.ColumnIndex is less than 0.
583                          * System.ArgumentOutOfRangeException :: rowIndex is less than 0, or greater than or equal to the number of rows in the parent System.Windows.Forms.DataGridView.
584                          * */
585         
586                         if (DataGridView == null)
587                                 throw new InvalidOperationException ("Cell is not in a DataGridView. The cell cannot retrieve the inherited cell style.");
588
589                         if (rowIndex < 0 || rowIndex >= DataGridView.Rows.Count)
590                                 throw new ArgumentOutOfRangeException ("rowIndex");
591
592                         // Start with DataGridView.DefaultCellStyle
593                         DataGridViewCellStyle result = new DataGridViewCellStyle (DataGridView.DefaultCellStyle);
594
595                         // If we have a column, add OwningColumn.DefaultCellStyle
596                         if (OwningColumn != null)
597                                 result.ApplyStyle (OwningColumn.DefaultCellStyle);
598
599                         // Add DataGridView.RowsDefaultCellStyle
600                         result.ApplyStyle (DataGridView.RowsDefaultCellStyle);
601
602                         // If we are an odd row, add DataGridView.AlternatingRowsDefaultCellStyle
603                         if (rowIndex % 2 == 1)
604                                 result.ApplyStyle (DataGridView.AlternatingRowsDefaultCellStyle);
605
606                         // Add Row.DefaultCellStyle
607                         result.ApplyStyle (DataGridView.Rows.SharedRow (rowIndex).DefaultCellStyle);
608                         
609                         // Add cell's style
610                         if (HasStyle)
611                                 result.ApplyStyle (Style);
612                         
613                         return result;
614                 }
615
616                 [EditorBrowsable (EditorBrowsableState.Advanced)]
617                 public virtual void InitializeEditingControl (int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) {
618                         if (DataGridView == null || DataGridView.EditingControl == null) {
619                                 throw new InvalidOperationException("No editing control defined");
620                         }
621                 }
622
623                 public virtual bool KeyEntersEditMode (KeyEventArgs e)
624                 {
625                         return false;
626                 }
627
628                 [EditorBrowsable (EditorBrowsableState.Advanced)]
629                 public static int MeasureTextHeight (Graphics graphics, string text, Font font, int maxWidth, TextFormatFlags flags)
630                 {
631                         if (graphics == null)
632                                 throw new ArgumentNullException ("Graphics argument null");
633                         if (font == null)
634                                 throw new ArgumentNullException ("Font argument null");
635                         if (maxWidth < 1)
636                                 throw new ArgumentOutOfRangeException ("maxWidth is less than 1.");
637
638                         return TextRenderer.MeasureText (graphics, text, font, new Size (maxWidth, 0), flags).Height;
639                 }
640
641                 [MonoTODO ("does not use widthTruncated parameter")]
642                 [EditorBrowsable (EditorBrowsableState.Advanced)]
643                 public static int MeasureTextHeight (Graphics graphics, string text, Font font, int maxWidth, TextFormatFlags flags, out bool widthTruncated)
644                 {
645                         widthTruncated = false;
646                         return TextRenderer.MeasureText (graphics, text, font, new Size (maxWidth, 0), flags).Height;
647                 }
648
649                 [EditorBrowsable (EditorBrowsableState.Advanced)]
650                 public static Size MeasureTextPreferredSize (Graphics graphics, string text, Font font, float maxRatio, TextFormatFlags flags)
651                 {
652                         if (graphics == null)
653                                 throw new ArgumentNullException ("Graphics argument null");
654                         if (font == null)
655                                 throw new ArgumentNullException ("Font argument null");
656                         if (maxRatio <= 0)
657                                 throw new ArgumentOutOfRangeException ("maxRatio is less than or equals to 0.");
658
659                         // I couldn't find a case where maxRatio
660                         // affected anything on MS
661                         return MeasureTextSize (graphics, text, font, flags);
662                 }
663
664                 [EditorBrowsable (EditorBrowsableState.Advanced)]
665                 public static Size MeasureTextSize (Graphics graphics, string text, Font font, TextFormatFlags flags)
666                 {
667                         return TextRenderer.MeasureText (graphics, text, font, Size.Empty, flags);
668                 }
669
670                 [EditorBrowsable (EditorBrowsableState.Advanced)]
671                 public static int MeasureTextWidth (Graphics graphics, string text, Font font, int maxHeight, TextFormatFlags flags)
672                 {
673                         if (graphics == null)
674                                 throw new ArgumentNullException ("Graphics argument null");
675                         if (font == null)
676                                 throw new ArgumentNullException ("Font argument null");
677                         if (maxHeight < 1)
678                                 throw new ArgumentOutOfRangeException ("maxHeight is less than 1.");
679
680                         return TextRenderer.MeasureText (graphics, text, font, new Size (0, maxHeight), flags).Width;
681                 }
682
683                 public virtual object ParseFormattedValue (object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
684                 {
685                         if (cellStyle == null)
686                                 throw new ArgumentNullException ("cellStyle is null.");
687                         if (FormattedValueType == null)
688                                 throw new FormatException ("The System.Windows.Forms.DataGridViewCell.FormattedValueType property value is null.");
689                         if (formattedValue == null)
690                                 throw new ArgumentException ("formattedValue is null.");
691                         if (ValueType == null)
692                                 throw new FormatException ("valuetype is null");
693                         if (!FormattedValueType.IsAssignableFrom (formattedValue.GetType ()))
694                                 throw new ArgumentException ("formattedValue is not of formattedValueType.");
695                         
696                         if (formattedValueTypeConverter == null)
697                                 formattedValueTypeConverter = FormattedValueTypeConverter;
698                         if (valueTypeConverter == null)
699                                 valueTypeConverter = ValueTypeConverter;
700
701                         if (valueTypeConverter != null && valueTypeConverter.CanConvertFrom (FormattedValueType))
702                                 return valueTypeConverter.ConvertFrom (formattedValue);
703                         if (formattedValueTypeConverter != null && formattedValueTypeConverter.CanConvertTo (ValueType))
704                                 return formattedValueTypeConverter.ConvertTo (formattedValue, ValueType);
705                         return Convert.ChangeType (formattedValue, ValueType);
706                 }
707
708                 [EditorBrowsable (EditorBrowsableState.Advanced)]
709                 public virtual void PositionEditingControl (bool setLocation, bool setSize, Rectangle cellBounds, Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow)
710                 {
711                         if (DataGridView.EditingControl != null) {
712                                 if (setLocation && setSize)
713                                         DataGridView.EditingControl.Bounds = cellBounds;
714                                 else if (setLocation)
715                                         DataGridView.EditingControl.Location = cellBounds.Location;     
716                                 else if (setSize)
717                                         DataGridView.EditingControl.Size = cellBounds.Size;
718                         }
719                 }
720
721                 [EditorBrowsable (EditorBrowsableState.Advanced)]
722                 public virtual Rectangle PositionEditingPanel (Rectangle cellBounds, Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) {
723                         throw new NotImplementedException();
724                 }
725
726                 public override string ToString () {
727                         return String.Format("{0} {{ ColumnIndex={1}, RowIndex={2} }}", this.GetType().Name, ColumnIndex, RowIndex);
728                 }
729
730                 protected virtual Rectangle BorderWidths (DataGridViewAdvancedBorderStyle advancedBorderStyle)
731                 {
732                         Rectangle r = Rectangle.Empty;
733
734                         r.X = BorderToWidth (advancedBorderStyle.Left);
735                         r.Y = BorderToWidth (advancedBorderStyle.Top);
736                         r.Width = BorderToWidth (advancedBorderStyle.Right);
737                         r.Height = BorderToWidth (advancedBorderStyle.Bottom);
738                         
739                         if (OwningColumn != null)
740                                 r.Width += OwningColumn.DividerWidth;
741                         if (OwningRow != null)
742                                 r.Height += OwningRow.DividerHeight;
743                                 
744                         return r;
745                 }
746
747                 private int BorderToWidth (DataGridViewAdvancedCellBorderStyle style)
748                 {
749                         switch (style) {
750                                 case DataGridViewAdvancedCellBorderStyle.None:
751                                         return 0;
752                                 case DataGridViewAdvancedCellBorderStyle.NotSet:
753                                 case DataGridViewAdvancedCellBorderStyle.Single:
754                                 case DataGridViewAdvancedCellBorderStyle.Inset:
755                                 case DataGridViewAdvancedCellBorderStyle.Outset:
756                                 case DataGridViewAdvancedCellBorderStyle.OutsetPartial:
757                                 default:
758                                         return 1;
759                                 case DataGridViewAdvancedCellBorderStyle.InsetDouble:
760                                 case DataGridViewAdvancedCellBorderStyle.OutsetDouble:
761                                         return 2;
762                         }
763                 }
764                 
765                 protected virtual bool ClickUnsharesRow (DataGridViewCellEventArgs e)
766                 {
767                         return false;
768                 }
769
770                 protected virtual bool ContentClickUnsharesRow (DataGridViewCellEventArgs e)
771                 {
772                         return false;
773                 }
774
775                 protected virtual bool ContentDoubleClickUnsharesRow (DataGridViewCellEventArgs e)
776                 {
777                         return false;
778                 }
779
780                 protected virtual AccessibleObject CreateAccessibilityInstance () {
781                         return new DataGridViewCellAccessibleObject(this);
782                 }
783
784                 protected virtual void Dispose (bool disposing) {
785                 }
786
787                 protected virtual bool DoubleClickUnsharesRow (DataGridViewCellEventArgs e)
788                 {
789                         return false;
790                 }
791
792                 protected virtual bool EnterUnsharesRow (int rowIndex, bool throughMouseClick)
793                 {
794                         return false;
795                 }
796
797                 protected virtual object GetClipboardContent (int rowIndex, bool firstCell, bool lastCell, bool inFirstRow, bool inLastRow, string format) {
798                         if (DataGridView == null)
799                                 return null;
800                                 
801                         if (rowIndex < 0 || rowIndex >= DataGridView.RowCount)
802                                 throw new ArgumentOutOfRangeException ("rowIndex", "Specified argument was out of the range of valid values.");
803                         
804                         string value = null;
805                         
806                         if (Selected) {
807 //                              DataGridViewCellStyle style = GetInheritedStyle (null, rowIndex, false);
808                                 value = GetEditedFormattedValue (rowIndex, DataGridViewDataErrorContexts.ClipboardContent | DataGridViewDataErrorContexts.Formatting) as string;
809                         }
810
811                         if (value == null)
812                                 value = string.Empty;
813                                 
814                         string table_prefix = string.Empty, cell_prefix = string.Empty, row_prefix = string.Empty;
815                         string table_suffix = string.Empty, cell_suffix = string.Empty, row_suffix = string.Empty;
816                         
817                         if (format == DataFormats.UnicodeText || format == DataFormats.Text) {
818                                 if (lastCell && !inLastRow)
819                                         cell_suffix = Environment.NewLine;
820                                 else if (!lastCell)
821                                         cell_suffix = "\t";
822                         } else if (format == DataFormats.CommaSeparatedValue) {
823                                 if (lastCell && !inLastRow)
824                                         cell_suffix = Environment.NewLine;
825                                 else if (!lastCell)
826                                         cell_suffix = ",";
827                         } else if (format == DataFormats.Html) {
828                                 if (inFirstRow && firstCell)
829                                         table_prefix = "<TABLE>";
830                                 if (inLastRow && lastCell)
831                                         table_suffix = "</TABLE>";
832                                 if (firstCell)
833                                         row_prefix = "<TR>";
834                                 if (lastCell)
835                                         row_suffix = "</TR>";
836                                 cell_prefix = "<TD>";
837                                 cell_suffix = "</TD>";
838                                 
839                                 if (!Selected) {
840                                         value = "&nbsp;";
841                                 }
842                         } else {
843                                 return value;
844                         }
845                                                 
846                         value = table_prefix + row_prefix + cell_prefix + value + cell_suffix + row_suffix + table_suffix;
847                         
848                         return value;
849                 }
850                 
851                 internal object GetClipboardContentInternal (int rowIndex, bool firstCell, bool lastCell, bool inFirstRow, bool inLastRow, string format) {
852                         return GetClipboardContent (rowIndex, firstCell, lastCell, inFirstRow, inLastRow, format);
853                 }
854
855                 protected virtual Rectangle GetContentBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex) {
856                         return Rectangle.Empty;
857                 }
858
859                 protected virtual Rectangle GetErrorIconBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)
860                 {
861                         return Rectangle.Empty;
862                 }
863
864                 protected internal virtual string GetErrorText (int rowIndex)
865                 {
866                         return errorText;
867                 }
868
869                 protected virtual object GetFormattedValue (object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
870                 {
871                         if (DataGridView == null)
872                                 return null;
873                                 
874                         if (rowIndex < 0 || rowIndex >= DataGridView.RowCount)
875                                 throw new ArgumentOutOfRangeException ("rowIndex");
876
877                         // Give the user a chance to custom format
878                         if (!(this is DataGridViewRowHeaderCell)) {
879                                 DataGridViewCellFormattingEventArgs e = new DataGridViewCellFormattingEventArgs (ColumnIndex, rowIndex, value, FormattedValueType, cellStyle);
880                                 DataGridView.OnCellFormattingInternal (e);
881                         
882                                 if (e.FormattingApplied)
883                                         return e.Value;
884                         
885                                 cellStyle = e.CellStyle;
886                                 value = e.Value;
887                         }
888                         
889                         if (value == null || (cellStyle != null && value == cellStyle.DataSourceNullValue)) {
890                                 if (FormattedValueType == typeof (string))
891                                         return String.Empty;
892                         }
893
894                         if (FormattedValueType == typeof(string) && value is IFormattable && !String.IsNullOrEmpty (cellStyle.Format))
895                                 return ((IFormattable) value).ToString (cellStyle.Format, cellStyle.FormatProvider);
896                         if (value != null && FormattedValueType.IsAssignableFrom (value.GetType()))
897                                 return value;
898
899                         if (formattedValueTypeConverter == null)
900                                 formattedValueTypeConverter = FormattedValueTypeConverter;
901                         if (valueTypeConverter == null)
902                                 valueTypeConverter = ValueTypeConverter;
903
904                         if (valueTypeConverter != null && valueTypeConverter.CanConvertTo (FormattedValueType))
905                                 return valueTypeConverter.ConvertTo (value, FormattedValueType);
906                         if (formattedValueTypeConverter != null && formattedValueTypeConverter.CanConvertFrom (ValueType))
907                                 return formattedValueTypeConverter.ConvertFrom (value);
908
909                         return Convert.ChangeType (value, FormattedValueType);
910                 }
911
912                 protected virtual Size GetPreferredSize (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize)
913                 {
914                         return new Size (-1, -1);
915                 }
916
917                 protected virtual Size GetSize (int rowIndex)
918                 {
919                         if (RowIndex == -1)
920                                 throw new InvalidOperationException ("Getting the Size property of a cell in a shared row is not a valid operation.");
921
922                         return new Size (OwningColumn.Width, OwningRow.Height);
923                 }
924
925                 protected virtual object GetValue (int rowIndex) {
926                         if (DataGridView != null && (RowIndex < 0 || RowIndex >= DataGridView.Rows.Count))
927                                 throw new ArgumentOutOfRangeException ("rowIndex", "Specified argument was out of the range of valid values.");
928                 
929                         if (OwningRow != null && DataGridView != null && OwningRow.Index == DataGridView.NewRowIndex)
930                                 return DefaultNewRowValue;
931
932                         if (DataProperty != null && OwningRow.DataBoundItem != null)
933                                 return DataProperty.GetValue (OwningRow.DataBoundItem);
934                         
935                         if (valuex != null)
936                                 return valuex;
937
938                         DataGridViewCellValueEventArgs dgvcvea = new DataGridViewCellValueEventArgs (columnIndex, rowIndex);
939                         if (DataGridView != null)
940                                 DataGridView.OnCellValueNeeded (dgvcvea);
941                         return dgvcvea.Value;
942                 }
943                 
944                 private PropertyDescriptor DataProperty {
945                         get {
946                                 if (OwningColumn != null && OwningColumn.DataColumnIndex != -1 && 
947                                     DataGridView != null && DataGridView.DataManager != null)
948                                         return DataGridView.DataManager.GetItemProperties()[OwningColumn.DataColumnIndex];
949                                 return null;
950                         }
951                 }
952
953                 private TypeConverter FormattedValueTypeConverter {
954                         get {
955                                 if (FormattedValueType != null)
956                                         return TypeDescriptor.GetConverter (FormattedValueType);
957                                 return null;
958                         }
959                 }
960
961                 private TypeConverter ValueTypeConverter {
962                         get {
963                                 if (DataProperty != null && DataProperty.Converter != null)
964                                         return DataProperty.Converter;
965                                 if (Value != null)
966                                         return TypeDescriptor.GetConverter (Value);
967                                 if (ValueType != null)
968                                         return TypeDescriptor.GetConverter (ValueType);
969                                 return null;
970                         }
971                 }
972
973                 protected virtual bool KeyDownUnsharesRow (KeyEventArgs e, int rowIndex)
974                 {
975                         return false;
976                 }
977
978                 protected virtual bool KeyPressUnsharesRow (KeyPressEventArgs e, int rowIndex)
979                 {
980                         return false;
981                 }
982
983                 protected virtual bool KeyUpUnsharesRow (KeyEventArgs e, int rowIndex)
984                 {
985                         return false;
986                 }
987
988                 protected virtual bool LeaveUnsharesRow (int rowIndex, bool throughMouseClick)
989                 {
990                         return false;
991                 }
992
993                 protected virtual bool MouseClickUnsharesRow (DataGridViewCellMouseEventArgs e)
994                 {
995                         return false;
996                 }
997
998                 protected virtual bool MouseDoubleClickUnsharesRow (DataGridViewCellMouseEventArgs e)
999                 {
1000                         return false;
1001                 }
1002
1003                 protected virtual bool MouseDownUnsharesRow (DataGridViewCellMouseEventArgs e)
1004                 {
1005                         return false;
1006                 }
1007
1008                 protected virtual bool MouseEnterUnsharesRow (int rowIndex)
1009                 {
1010                         return false;
1011                 }
1012
1013                 protected virtual bool MouseLeaveUnsharesRow (int rowIndex)
1014                 {
1015                         return false;
1016                 }
1017
1018                 protected virtual bool MouseMoveUnsharesRow (DataGridViewCellMouseEventArgs e)
1019                 {
1020                         return false;
1021                 }
1022
1023                 protected virtual bool MouseUpUnsharesRow (DataGridViewCellMouseEventArgs e)
1024                 {
1025                         return false;
1026                 }
1027
1028                 protected virtual void OnClick (DataGridViewCellEventArgs e) {
1029                 }
1030
1031                 internal void OnClickInternal (DataGridViewCellEventArgs e) {
1032                         OnClick (e);
1033                 }
1034
1035                 protected virtual void OnContentClick (DataGridViewCellEventArgs e) {
1036                 }
1037                 
1038                 internal void OnContentClickInternal (DataGridViewCellEventArgs e) {
1039                         OnContentClick (e);
1040                 }
1041
1042                 protected virtual void OnContentDoubleClick (DataGridViewCellEventArgs e) {
1043                 }
1044                 
1045                 internal void OnContentDoubleClickInternal (DataGridViewCellEventArgs e) {
1046                         OnContentDoubleClick (e);
1047                 }
1048
1049                 protected override void OnDataGridViewChanged () {
1050                 }
1051                 
1052                 internal void OnDataGridViewChangedInternal () {
1053                         OnDataGridViewChanged ();
1054                 }
1055
1056                 protected virtual void OnDoubleClick (DataGridViewCellEventArgs e) {
1057                 }
1058
1059                 internal void OnDoubleClickInternal (DataGridViewCellEventArgs e) {
1060                         OnDoubleClick (e);
1061                 }
1062                 
1063                 protected virtual void OnEnter (int rowIndex, bool throughMouseClick) {
1064                 }
1065
1066                 internal void OnEnterInternal (int rowIndex, bool throughMouseClick) {
1067                         OnEnter (rowIndex, throughMouseClick);
1068                 }
1069
1070                 protected virtual void OnKeyDown (KeyEventArgs e, int rowIndex) {
1071                 }
1072
1073                 internal void OnKeyDownInternal (KeyEventArgs e, int rowIndex) {
1074                         OnKeyDown (e, rowIndex);
1075                 }
1076
1077                 protected virtual void OnKeyPress (KeyPressEventArgs e, int rowIndex) {
1078                 }
1079
1080                 internal void OnKeyPressInternal (KeyPressEventArgs e, int rowIndex) {
1081                         OnKeyPress (e, rowIndex);
1082                 }
1083
1084                 protected virtual void OnKeyUp (KeyEventArgs e, int rowIndex) {
1085                 }
1086                 
1087                 internal void OnKeyUpInternal (KeyEventArgs e, int rowIndex) {
1088                         OnKeyUp (e, rowIndex);
1089                 }
1090
1091                 protected virtual void OnLeave (int rowIndex, bool throughMouseClick) {
1092                 }
1093                 
1094                 internal void OnLeaveInternal (int rowIndex, bool throughMouseClick) {
1095                         OnLeave (rowIndex, throughMouseClick);
1096                 }
1097
1098                 protected virtual void OnMouseClick (DataGridViewCellMouseEventArgs e) {
1099                 }
1100
1101                 internal void OnMouseClickInternal (DataGridViewCellMouseEventArgs e) {
1102                         OnMouseClick (e);
1103                 }
1104
1105                 protected virtual void OnMouseDoubleClick (DataGridViewCellMouseEventArgs e) {
1106                 }
1107                 
1108                 internal void OnMouseDoubleClickInternal (DataGridViewCellMouseEventArgs e) {
1109                         OnMouseDoubleClick (e);
1110                 }
1111
1112                 protected virtual void OnMouseDown (DataGridViewCellMouseEventArgs e) {
1113                 }
1114
1115                 internal void OnMouseDownInternal (DataGridViewCellMouseEventArgs e) {
1116                         OnMouseDown (e);
1117                 }
1118
1119                 protected virtual void OnMouseEnter (int rowIndex) {
1120                 }
1121                 
1122                 internal void OnMouseEnterInternal (int rowIndex) {
1123                         OnMouseEnter (rowIndex) ;
1124                 }
1125
1126                 protected virtual void OnMouseLeave (int rowIndex) {
1127                 }
1128
1129                 internal void OnMouseLeaveInternal (int e) {
1130                         OnMouseLeave (e);
1131                 }
1132                 
1133                 protected virtual void OnMouseMove (DataGridViewCellMouseEventArgs e) {
1134                 }
1135                 
1136                 internal void OnMouseMoveInternal (DataGridViewCellMouseEventArgs e) {
1137                         OnMouseMove (e);
1138                 }
1139
1140                 protected virtual void OnMouseUp (DataGridViewCellMouseEventArgs e) {
1141                 }
1142
1143                 internal void OnMouseUpInternal (DataGridViewCellMouseEventArgs e) {
1144                         OnMouseUp (e);
1145                 }
1146
1147                 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)
1148                 {
1149                         Paint (graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
1150                 }
1151                         
1152                 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)
1153                 {
1154                         if ((paintParts & DataGridViewPaintParts.Background) == DataGridViewPaintParts.Background)
1155                                 PaintPartBackground (graphics, cellBounds, cellStyle);
1156                         if ((paintParts & DataGridViewPaintParts.SelectionBackground) == DataGridViewPaintParts.SelectionBackground)
1157                                 PaintPartSelectionBackground (graphics, cellBounds, cellState, cellStyle);
1158                         if ((paintParts & DataGridViewPaintParts.ContentForeground) == DataGridViewPaintParts.ContentForeground)
1159                                 PaintPartContent (graphics, cellBounds, rowIndex, cellState, cellStyle, formattedValue);
1160                         if ((paintParts & DataGridViewPaintParts.Border) == DataGridViewPaintParts.Border)
1161                                 PaintBorder (graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);
1162                         if ((paintParts & DataGridViewPaintParts.Focus) == DataGridViewPaintParts.Focus)
1163                                 PaintPartFocus (graphics, cellBounds);
1164                         if ((paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon)
1165                                 if (!string.IsNullOrEmpty (ErrorText))
1166                                         PaintErrorIcon (graphics, clipBounds, cellBounds, ErrorText);
1167                 }
1168
1169                 protected virtual void PaintBorder (Graphics graphics, Rectangle clipBounds, Rectangle bounds, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle)
1170                 {
1171                         Pen pen = new Pen (DataGridView.GridColor);
1172
1173                         // Paint the left border, if any
1174                         switch (advancedBorderStyle.Left) {
1175                                 case DataGridViewAdvancedCellBorderStyle.Single:
1176                                         if (DataGridView.CellBorderStyle != DataGridViewCellBorderStyle.Single)
1177                                                 graphics.DrawLine (pen, bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height - 1);
1178                                         break;
1179                                 case DataGridViewAdvancedCellBorderStyle.Outset:
1180                                 case DataGridViewAdvancedCellBorderStyle.Inset:
1181                                         graphics.DrawLine(pen, bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height - 1);
1182                                         break;
1183                                 case DataGridViewAdvancedCellBorderStyle.InsetDouble:
1184                                 case DataGridViewAdvancedCellBorderStyle.OutsetDouble:
1185                                         graphics.DrawLine(pen, bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height - 1);
1186                                         graphics.DrawLine(pen, bounds.X + 2, bounds.Y, bounds.X + 2, bounds.Y + bounds.Height - 1);
1187                                         break;
1188                         }
1189                         
1190                         // Paint the right border, if any
1191                         switch (advancedBorderStyle.Right) {
1192                                 case DataGridViewAdvancedCellBorderStyle.Single:
1193                                         graphics.DrawLine(pen, bounds.X + bounds.Width - 1, bounds.Y, bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
1194                                         break;
1195                                 case DataGridViewAdvancedCellBorderStyle.Outset:
1196                                 case DataGridViewAdvancedCellBorderStyle.Inset:
1197                                 case DataGridViewAdvancedCellBorderStyle.InsetDouble:
1198                                 case DataGridViewAdvancedCellBorderStyle.OutsetDouble:
1199                                         graphics.DrawLine(pen, bounds.X + bounds.Width, bounds.Y, bounds.X + bounds.Width, bounds.Y + bounds.Height - 1);
1200                                         break;
1201                         }
1202                         
1203                         // Paint the top border, if any
1204                         switch (advancedBorderStyle.Top) {
1205                                 case DataGridViewAdvancedCellBorderStyle.Single:
1206                                         if (DataGridView.CellBorderStyle != DataGridViewCellBorderStyle.Single)
1207                                                 graphics.DrawLine(pen, bounds.X, bounds.Y, bounds.X + bounds.Width - 1, bounds.Y);
1208                                         break;
1209                                 case DataGridViewAdvancedCellBorderStyle.Outset:
1210                                 case DataGridViewAdvancedCellBorderStyle.Inset:
1211                                 case DataGridViewAdvancedCellBorderStyle.InsetDouble:
1212                                 case DataGridViewAdvancedCellBorderStyle.OutsetDouble:
1213                                         graphics.DrawLine(pen, bounds.X, bounds.Y, bounds.X + bounds.Width - 1, bounds.Y);
1214                                         break;
1215                         }
1216                         
1217                         // Paint the bottom border, if any
1218                         switch (advancedBorderStyle.Bottom) {
1219                                 case DataGridViewAdvancedCellBorderStyle.Outset:
1220                                 case DataGridViewAdvancedCellBorderStyle.Inset:
1221                                 case DataGridViewAdvancedCellBorderStyle.Single:
1222                                 case DataGridViewAdvancedCellBorderStyle.InsetDouble:
1223                                 case DataGridViewAdvancedCellBorderStyle.OutsetDouble:
1224                                         graphics.DrawLine(pen, bounds.X, bounds.Y + bounds.Height - 1, bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
1225                                         break;
1226                         }
1227                 }
1228
1229                 protected virtual void PaintErrorIcon (Graphics graphics, Rectangle clipBounds, Rectangle cellValueBounds, string errorText)
1230                 {
1231                         Rectangle error_bounds = GetErrorIconBounds (graphics, null, RowIndex);
1232                         
1233                         if (error_bounds.IsEmpty)
1234                                 return;
1235
1236                         Point loc = error_bounds.Location;
1237                         loc.X += cellValueBounds.Left;
1238                         loc.Y += cellValueBounds.Top;
1239
1240                         graphics.FillRectangle (Brushes.Red, new Rectangle (loc.X + 1, loc.Y + 2, 10, 7));
1241                         graphics.FillRectangle (Brushes.Red, new Rectangle (loc.X + 2, loc.Y + 1, 8, 9));
1242                         graphics.FillRectangle (Brushes.Red, new Rectangle (loc.X + 4, loc.Y, 4, 11));
1243                         graphics.FillRectangle (Brushes.Red, new Rectangle (loc.X, loc.Y + 4, 12, 3));
1244
1245                         graphics.FillRectangle (Brushes.White, new Rectangle (loc.X + 5, loc.Y + 2, 2, 4));
1246                         graphics.FillRectangle (Brushes.White, new Rectangle (loc.X + 5, loc.Y + 7, 2, 2));
1247                 }
1248
1249                 internal virtual void PaintPartBackground (Graphics graphics, Rectangle cellBounds, DataGridViewCellStyle style)
1250                 {
1251                         Color color = style.BackColor;
1252                         graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (color), cellBounds);
1253                 }
1254
1255                 internal Pen GetBorderPen ()
1256                 {
1257                         return ThemeEngine.Current.ResPool.GetPen (DataGridView.GridColor);
1258                 }
1259
1260                 internal virtual void PaintPartContent (Graphics graphics, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, object formattedValue)
1261                 {
1262                         if (IsInEditMode)
1263                                 return;
1264                                 
1265                         Color color = Selected ? cellStyle.SelectionForeColor : cellStyle.ForeColor;
1266
1267                         TextFormatFlags flags = TextFormatFlags.EndEllipsis | TextFormatFlags.VerticalCenter | TextFormatFlags.TextBoxControl;
1268                         flags |= AlignmentToFlags (style.Alignment);
1269                         
1270                         cellBounds.Height -= 2;
1271                         cellBounds.Width -= 2;
1272
1273                         if (formattedValue != null)
1274                                 TextRenderer.DrawText (graphics, formattedValue.ToString (), cellStyle.Font, cellBounds, color, flags);
1275                 }
1276                 
1277                 private void PaintPartFocus (Graphics graphics, Rectangle cellBounds)
1278                 {
1279                         cellBounds.Width--;
1280                         cellBounds.Height--;
1281                         
1282                         if (DataGridView.ShowFocusCues && DataGridView.CurrentCell == this && DataGridView.Focused)
1283                                 ControlPaint.DrawFocusRectangle (graphics, cellBounds);
1284                 }
1285
1286                 internal virtual void PaintPartSelectionBackground (Graphics graphics, Rectangle cellBounds, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle)
1287                 {
1288                         if ((cellState & DataGridViewElementStates.Selected) != DataGridViewElementStates.Selected)
1289                                 return;
1290
1291                         if (RowIndex >= 0 && IsInEditMode && EditType != null)
1292                                 return;
1293                                 
1294                         Color color = cellStyle.SelectionBackColor;
1295                         graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (color), cellBounds);
1296                 }
1297
1298                 internal void PaintWork (Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
1299                 {
1300                         object value;
1301                         object formattedvalue;
1302                         
1303                         if (RowIndex == -1 && !(this is DataGridViewColumnHeaderCell)) {
1304                                 value = null;
1305                                 formattedvalue = null;
1306                         } else if (RowIndex == -1) {
1307                                 value = Value;
1308                                 formattedvalue = Value;
1309                         } else {
1310                                 value = Value;
1311                                 formattedvalue = GetFormattedValue (Value, rowIndex, ref cellStyle, null, null, DataGridViewDataErrorContexts.Formatting);
1312                         }
1313
1314                         DataGridViewCellPaintingEventArgs pea = new DataGridViewCellPaintingEventArgs (DataGridView, graphics, clipBounds, cellBounds, rowIndex, columnIndex, cellState, value, formattedvalue, ErrorText, cellStyle, advancedBorderStyle, paintParts);
1315                         DataGridView.OnCellPaintingInternal (pea);
1316                         
1317                         if (pea.Handled)
1318                                 return;
1319                                 
1320                         pea.Paint (pea.ClipBounds, pea.PaintParts);
1321                 }
1322                 
1323                 protected virtual bool SetValue (int rowIndex, object value)
1324                 {
1325                         object oldValue = this.Value;
1326
1327                         if (DataProperty != null && !DataProperty.IsReadOnly) {
1328                                 DataProperty.SetValue (OwningRow.DataBoundItem, value);
1329                         } else if (DataGridView != null && DataGridView.VirtualMode) {
1330                                 DataGridViewCellValueEventArgs ea = new DataGridViewCellValueEventArgs(ColumnIndex, RowIndex);
1331                                 ea.Value = value;
1332                                 DataGridView.OnCellValuePushed(ea);
1333                         } else {
1334                                 valuex = value;
1335                         }
1336
1337                         if (!Object.ReferenceEquals (oldValue, value) || !Object.Equals (oldValue, value)) {
1338                                 RaiseCellValueChanged (new DataGridViewCellEventArgs (ColumnIndex, RowIndex));
1339                                 
1340                                 // Set this dirty flag back to false
1341                                 if (this is IDataGridViewEditingCell)
1342                                         (this as IDataGridViewEditingCell).EditingCellValueChanged = false;
1343                                 
1344                                 if (DataGridView != null)
1345                                         DataGridView.InvalidateCell (this);
1346                                         
1347                                 return true;
1348                         }
1349                         return false;
1350                 }
1351
1352                 private void OnStyleChanged (object sender, EventArgs args) {
1353                         if (DataGridView != null) {
1354                                 DataGridView.RaiseCellStyleChanged(new DataGridViewCellEventArgs(ColumnIndex, RowIndex));
1355                         }
1356                 }
1357
1358                 internal virtual Rectangle InternalErrorIconsBounds {
1359                         get { return GetErrorIconBounds (null, null, -1); }
1360                 }
1361
1362                 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) {
1363                         Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
1364                 }
1365
1366                 internal void SetOwningRow (DataGridViewRow row) {
1367                         owningRow = row;
1368                 }
1369                 
1370                 internal void SetOwningColumn (DataGridViewColumn col) {
1371                         columnIndex = col.Index;
1372                 }
1373
1374                 internal void SetColumnIndex (int index) {
1375                         columnIndex = index;
1376                 }
1377
1378                 internal void SetIsInEditMode (bool isInEditMode) {
1379                         this.isInEditMode = isInEditMode;
1380                 }
1381
1382                 internal void OnErrorTextChanged (DataGridViewCellEventArgs args) {
1383                         if (DataGridView != null) {
1384                                 DataGridView.OnCellErrorTextChanged(args);
1385                         }
1386                 }
1387
1388                 internal TextFormatFlags AlignmentToFlags (DataGridViewContentAlignment align)
1389                 {
1390                         TextFormatFlags flags = TextFormatFlags.Default;
1391
1392                         switch (align) {
1393                                 case DataGridViewContentAlignment.BottomCenter:
1394                                         flags |= TextFormatFlags.Bottom;
1395                                         flags |= TextFormatFlags.HorizontalCenter;
1396                                         break;
1397                                 case DataGridViewContentAlignment.BottomLeft:
1398                                         flags |= TextFormatFlags.Bottom;
1399                                         break;
1400                                 case DataGridViewContentAlignment.BottomRight:
1401                                         flags |= TextFormatFlags.Bottom;
1402                                         flags |= TextFormatFlags.Right;
1403                                         break;
1404                                 case DataGridViewContentAlignment.MiddleCenter:
1405                                         flags |= TextFormatFlags.VerticalCenter;
1406                                         flags |= TextFormatFlags.HorizontalCenter;
1407                                         break;
1408                                 case DataGridViewContentAlignment.MiddleLeft:
1409                                         flags |= TextFormatFlags.VerticalCenter;
1410                                         break;
1411                                 case DataGridViewContentAlignment.MiddleRight:
1412                                         flags |= TextFormatFlags.VerticalCenter;
1413                                         flags |= TextFormatFlags.Right;
1414                                         break;
1415                                 case DataGridViewContentAlignment.TopLeft:
1416                                         flags |= TextFormatFlags.Top;
1417                                         break;
1418                                 case DataGridViewContentAlignment.TopCenter:
1419                                         flags |= TextFormatFlags.HorizontalCenter;
1420                                         flags |= TextFormatFlags.Top;
1421                                         break;
1422                                 case DataGridViewContentAlignment.TopRight:
1423                                         flags |= TextFormatFlags.Right;
1424                                         flags |= TextFormatFlags.Top;
1425                                         break;
1426                         }
1427
1428                         return flags;
1429                 }
1430
1431                 internal Rectangle AlignInRectangle (Rectangle outer, Size inner, DataGridViewContentAlignment align)
1432                 {
1433                         int x = 0;
1434                         int y = 0;
1435
1436                         if (align == DataGridViewContentAlignment.BottomLeft || align == DataGridViewContentAlignment.MiddleLeft || align == DataGridViewContentAlignment.TopLeft)
1437                                 x = outer.X;
1438                         else if (align == DataGridViewContentAlignment.BottomCenter || align == DataGridViewContentAlignment.MiddleCenter || align == DataGridViewContentAlignment.TopCenter)
1439                                 x = Math.Max (outer.X + ((outer.Width - inner.Width) / 2), outer.Left);
1440                         else if (align == DataGridViewContentAlignment.BottomRight || align == DataGridViewContentAlignment.MiddleRight || align == DataGridViewContentAlignment.TopRight)
1441                                 x = Math.Max (outer.Right - inner.Width, outer.X);
1442                         if (align == DataGridViewContentAlignment.TopCenter || align == DataGridViewContentAlignment.TopLeft || align == DataGridViewContentAlignment.TopRight)
1443                                 y = outer.Y;
1444                         else if (align == DataGridViewContentAlignment.MiddleCenter || align == DataGridViewContentAlignment.MiddleLeft || align == DataGridViewContentAlignment.MiddleRight)
1445                                 y = Math.Max (outer.Y + (outer.Height - inner.Height) / 2, outer.Y);
1446                         else if (align == DataGridViewContentAlignment.BottomCenter || align == DataGridViewContentAlignment.BottomRight || align == DataGridViewContentAlignment.BottomLeft)
1447                                 y = Math.Max (outer.Bottom - inner.Height, outer.Y);
1448
1449                         return new Rectangle (x, y, Math.Min (inner.Width, outer.Width), Math.Min (inner.Height, outer.Height));
1450                 }
1451
1452                 [ComVisibleAttribute(true)]
1453                 protected class DataGridViewCellAccessibleObject : AccessibleObject {
1454
1455                         private DataGridViewCell dataGridViewCell;
1456
1457                         public DataGridViewCellAccessibleObject () {
1458                         }
1459
1460                         public DataGridViewCellAccessibleObject (DataGridViewCell owner) {
1461                                 this.dataGridViewCell = owner;
1462                         }
1463
1464                         public override Rectangle Bounds {
1465                                 get { throw new NotImplementedException(); }
1466                         }
1467
1468                         public override string DefaultAction {
1469                                 get { return "Edit"; }
1470                         }
1471
1472                         public override string Help {
1473                                 get { return base.Help; }
1474                         }
1475                         
1476                         public override string Name {
1477                                 get { return dataGridViewCell.OwningColumn.HeaderText + ": " + dataGridViewCell.RowIndex.ToString(); }
1478                         }
1479
1480                         public DataGridViewCell Owner {
1481                                 get { return dataGridViewCell; }
1482                                 set { dataGridViewCell = value; }
1483                         }
1484
1485                         public override AccessibleObject Parent {
1486                                 get { return dataGridViewCell.OwningRow.AccessibilityObject; }
1487                         }
1488
1489                         public override AccessibleRole Role {
1490                                 get { return AccessibleRole.Cell; }
1491                         }
1492
1493                         public override AccessibleStates State {
1494                                 get {
1495                                         if (dataGridViewCell.Selected) {
1496                                                 return AccessibleStates.Selected;
1497                                         }
1498                                         else {
1499                                                 return AccessibleStates.Focused;
1500                                         }
1501                                 }
1502                         }
1503
1504                         public override string Value {
1505                                 get {
1506                                         if (dataGridViewCell.FormattedValue == null) {
1507                                                 return "(null)";
1508                                         }
1509                                         return dataGridViewCell.FormattedValue.ToString();
1510                                 }
1511                                 set {
1512                                         if (owner == null)
1513                                                 throw new InvalidOperationException ("owner is null");
1514                                                 
1515                                         throw new NotImplementedException ();
1516                                 }
1517                         }
1518
1519                         public override void DoDefaultAction () {
1520                                 if (dataGridViewCell.DataGridView.EditMode != DataGridViewEditMode.EditProgrammatically) {
1521                                         if (dataGridViewCell.IsInEditMode) {
1522                                                 // commit edit
1523                                         }
1524                                         else {
1525                                                 // begin edit
1526                                         }
1527                                 }
1528                         }
1529
1530                         public override AccessibleObject GetChild (int index) {
1531                                 throw new NotImplementedException();
1532                         }
1533
1534                         public override int GetChildCount () {
1535                                 if (dataGridViewCell.IsInEditMode) {
1536                                         return 1;
1537                                 }
1538                                 return -1;
1539                         }
1540
1541                         public override AccessibleObject GetFocused () {
1542                                 return null;
1543                         }
1544
1545                         public override AccessibleObject GetSelected () {
1546                                 return null;
1547                         }
1548
1549                         public override AccessibleObject Navigate (AccessibleNavigation navigationDirection) {
1550                                 switch (navigationDirection) {
1551                                         case AccessibleNavigation.Right:
1552                                                 break;
1553                                         case AccessibleNavigation.Left:
1554                                                 break;
1555                                         case AccessibleNavigation.Next:
1556                                                 break;
1557                                         case AccessibleNavigation.Previous:
1558                                                 break;
1559                                         case AccessibleNavigation.Up:
1560                                                 break;
1561                                         case AccessibleNavigation.Down:
1562                                                 break;
1563                                         default:
1564                                                 return null;
1565                                 }
1566                                 return null;
1567                         }
1568
1569                         public override void Select (AccessibleSelection flags) {
1570                                 switch (flags) {
1571                                         case AccessibleSelection.TakeFocus:
1572                                                 dataGridViewCell.dataGridViewOwner.Focus();
1573                                                 break;
1574                                         case AccessibleSelection.TakeSelection:
1575                                                 //dataGridViewCell.Focus();
1576                                                 break;
1577                                         case AccessibleSelection.AddSelection:
1578                                                 dataGridViewCell.dataGridViewOwner.SelectedCells.InternalAdd(dataGridViewCell);
1579                                                 break;
1580                                         case AccessibleSelection.RemoveSelection:
1581                                                 dataGridViewCell.dataGridViewOwner.SelectedCells.InternalRemove(dataGridViewCell);
1582                                                 break;
1583                                 }
1584                         }
1585
1586                 }
1587         }
1588
1589         internal class DataGridViewCellConverter : TypeConverter
1590         {
1591         }
1592
1593 }