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