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