2005-09-19 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGrid.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 //      Jordi Mas i Hernandez <jordi@ximian.com>
24 //
25 //
26
27 // NOT COMPLETE
28
29
30 using System;
31 using System.ComponentModel;
32 using System.Drawing;
33 using System.Runtime.InteropServices;
34 using System.Collections;
35
36 namespace System.Windows.Forms
37 {
38         [DefaultEvent("Navigate")]
39         [DefaultProperty("DataSource")]
40         [Designer("System.Windows.Forms.Design.DataGridDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
41         public class DataGrid : Control, ISupportInitialize, IDataGridEditingService
42         {
43                 [Flags]
44                 [Serializable]
45                 public enum HitTestType
46                 {
47                         None            = 0,
48                         Cell            = 1,
49                         ColumnHeader    = 2,
50                         RowHeader       = 4,
51                         ColumnResize    = 8,
52                         RowResize       = 16,
53                         Caption         = 32,
54                         ParentRows      = 64
55                 }
56
57                 public sealed class HitTestInfo
58                 {
59                         public static readonly HitTestInfo Nowhere = null;
60
61                         #region Local Variables
62                         internal int column;
63                         internal int row;
64                         internal HitTestType type;
65                         #endregion // Local Variables
66
67                         #region Private Constructors
68                         internal HitTestInfo ()
69                         {
70                                 column = 0;
71                                 row = 0;
72                                 type =  HitTestType.None;
73                         }
74                         #endregion
75
76
77                         #region Public Instance Properties
78                         public int Column {
79                                 get { return column; }
80                         }
81
82                         public int Row {
83                                 get { return row; }
84                         }
85                         public DataGrid.HitTestType Type {
86                                 get { return type; }
87                         }
88                         #endregion //Public Instance Properties
89
90                         public override bool Equals (object o)
91                         {
92                                 if (!(o is HitTestInfo))
93                                         return false;
94
95                                 HitTestInfo obj = (HitTestInfo) o;
96                                 return (obj.Column == column && obj.Row == row && obj.Type ==type);
97                         }
98
99                         public override int GetHashCode ()
100                         {
101                                 return row ^ column;
102                         }
103
104                         public override string ToString ()
105                         {
106                                 return base.ToString ();
107                         }
108
109                 }
110
111                 #region Local Variables
112                 private static readonly Color   def_alternating_backcolor = ThemeEngine.Current.DataGridAlternatingBackColor;
113                 private static readonly Color   def_background_color = ThemeEngine.Current.DataGridBackgroundColor;
114                 private static readonly Color   def_caption_backcolor = ThemeEngine.Current.DataGridCaptionBackColor;
115                 private static readonly Color   def_caption_forecolor = ThemeEngine.Current.DataGridCaptionForeColor;
116                 private static readonly Color   def_gridline_color = ThemeEngine.Current.DataGridGridLineColor;
117                 private static readonly Color   def_header_backcolor = ThemeEngine.Current.DataGridHeaderBackColor;
118                 private static readonly Font    def_header_font = ThemeEngine.Current.DefaultFont;
119                 private static readonly Color   def_header_forecolor = ThemeEngine.Current.DataGridHeaderForeColor;
120                 private static readonly Color   def_link_hovercolor = ThemeEngine.Current.DataGridLinkHoverColor;
121                 private static readonly Color   def_parentrowsback_color = ThemeEngine.Current.DataGridParentRowsBackColor;
122                 private static readonly Color   def_parentrowsfore_color = ThemeEngine.Current.DataGridParentRowsForeColor;
123                 private static readonly Color   def_selection_backcolor = ThemeEngine.Current.DataGridSelectionBackColor;
124                 private static readonly Color   def_selection_forecolor = ThemeEngine.Current.DataGridSelectionForeColor;
125                 private static readonly Color   def_link_color = ThemeEngine.Current.DataGridLinkColor;
126                 internal readonly int def_preferredrow_height;
127
128                 private bool allow_navigation;
129                 private bool allow_sorting;
130                 private Color alternating_backcolor;
131                 private Color backColor;
132                 private Color background_color;
133                 internal BorderStyle border_style;
134                 private Color caption_backcolor;
135                 private Font caption_font;
136                 private Color caption_forecolor;
137                 private string caption_text;
138                 internal bool caption_visible;
139                 internal bool columnheaders_visible;
140                 private object datasource;
141                 private object real_datasource;
142                 private string datamember;
143                 private int firstvisible_column;
144                 private bool flatmode;
145                 private Color gridline_color;
146                 private DataGridLineStyle gridline_style;
147                 private Color header_backcolor;
148                 private Color header_forecolor;
149                 private Font header_font;
150                 private Color link_color;
151                 private Color link_hovercolor;
152                 private Color parentrowsback_color;
153                 private Color parentrowsfore_color;
154                 private bool parentrows_visible;
155                 private int preferredcolumn_width;
156                 private int preferredrow_height;
157                 private bool _readonly;
158                 internal bool rowheaders_visible;
159                 private Color selection_backcolor;
160                 private Color selection_forecolor;
161                 private int rowheaders_width;
162                 internal int visiblecolumn_count;
163                 internal int visiblerow_count;
164                 internal int first_visiblecolumn;
165                 private GridTableStylesCollection styles_collection;
166                 private DataGridParentRowsLabelStyle parentrowslabel_style;
167                 internal DataGridCell current_cell;
168                 private DataGridTableStyle default_style;
169                 private DataGridTableStyle current_style;
170                 internal HScrollBar horiz_scrollbar;
171                 internal VScrollBar vert_scrollbar;
172                 internal DataGridDrawing grid_drawing;
173                 internal int first_visiblerow;
174                 internal int horz_pixeloffset;
175                 internal bool is_editing;       // Current cell is edit mode
176                 internal bool is_changing;      // Indicates if current cell is been changed (in edit mode)
177                 internal bool is_adding;        // Indicates when we are adding a row
178                 private Hashtable selected_rows;
179                 private bool ctrl_pressed;
180                 private bool shift_pressed;
181                 private bool begininit;
182                 private CurrencyManager cached_currencymgr;
183                 private CurrencyManager cached_currencymgr_events;
184                 private bool accept_listmgrevents;
185                 #endregion // Local Variables
186
187                 #region Public Constructors
188                 public DataGrid ()
189                 {
190                         grid_drawing = new DataGridDrawing (this);
191                         allow_navigation = true;
192                         allow_sorting = true;
193                         begininit = false;
194                         backColor = ThemeEngine.Current.DataGridBackColor;
195                         alternating_backcolor = def_alternating_backcolor;
196                         background_color = def_background_color;
197                         border_style = BorderStyle.Fixed3D;
198                         caption_backcolor = def_caption_backcolor;
199                         caption_font = null;
200                         caption_forecolor = def_caption_forecolor;
201                         caption_text = string.Empty;
202                         caption_visible = true;
203                         columnheaders_visible = true;
204                         datasource = null;
205                         real_datasource = null;
206                         datamember = string.Empty;
207                         firstvisible_column = 0;
208                         flatmode = false;
209                         gridline_color = def_gridline_color;
210                         gridline_style = DataGridLineStyle.Solid;
211                         header_backcolor = def_header_backcolor;
212                         header_forecolor = def_header_forecolor;
213                         header_font = def_header_font;
214                         link_color = def_link_color;
215                         link_hovercolor = def_link_hovercolor;
216                         parentrowsback_color = def_parentrowsback_color;
217                         parentrowsfore_color = def_parentrowsfore_color;
218                         parentrows_visible = true;
219                         preferredcolumn_width = ThemeEngine.Current.DataGridPreferredColumnWidth;
220                         _readonly = false;
221                         rowheaders_visible = true;
222                         selection_backcolor = def_selection_backcolor;
223                         selection_forecolor = def_selection_forecolor;
224                         rowheaders_width = 35;
225                         visiblecolumn_count = 0;
226                         visiblerow_count = 0;
227                         current_cell = new DataGridCell ();
228                         first_visiblerow = 0;
229                         first_visiblecolumn = 0;
230                         horz_pixeloffset = 0;
231                         is_editing = false;
232                         is_changing = false;
233                         is_adding = false;
234                         parentrowslabel_style = DataGridParentRowsLabelStyle.Both;
235                         selected_rows = new Hashtable ();
236                         ctrl_pressed = false;
237                         shift_pressed = false;
238                         preferredrow_height = def_preferredrow_height = FontHeight + 3;
239                         cached_currencymgr_events = cached_currencymgr = null;
240                         accept_listmgrevents = true;
241
242                         default_style = new DataGridTableStyle (true);
243                         styles_collection = new GridTableStylesCollection (this);
244                         styles_collection.CollectionChanged += new CollectionChangeEventHandler (OnTableStylesCollectionChanged);
245
246                         CurrentTableStyle = default_style;
247
248                         horiz_scrollbar = new HScrollBar ();
249                         horiz_scrollbar.Scroll += new ScrollEventHandler  (GridHScrolled);
250                         vert_scrollbar = new VScrollBar ();
251                         vert_scrollbar.Scroll += new ScrollEventHandler (GridVScrolled);                        
252                         KeyUp += new KeyEventHandler (OnKeyUpDG);                       
253
254                         SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
255
256                 }
257
258                 #endregion      // Public Constructor
259
260                 #region Public Instance Properties
261
262                 [DefaultValue(true)]
263                 public bool AllowNavigation {
264                         get {
265                                 return allow_navigation;
266                         }
267
268                         set {
269                                 if (allow_navigation != value) {
270                                         allow_navigation = value;
271                                         OnAllowNavigationChanged (EventArgs.Empty);
272                                 }
273                         }
274                 }
275
276                 [DefaultValue(true)]
277                 public bool AllowSorting {
278                         get {
279                                 return allow_sorting;
280                         }
281
282                         set {
283                                 if (allow_sorting != value) {
284                                         allow_sorting = value;
285                                 }
286                         }
287                 }
288
289                 public Color AlternatingBackColor  {
290                         get {
291                                 return alternating_backcolor;
292                         }
293
294                         set {
295                                 if (alternating_backcolor != value) {
296                                         alternating_backcolor = value;
297                                         Refresh ();
298                                 }
299                         }
300                 }
301
302                 public Color BackColor {
303                         get {
304                                 return backColor;
305                         }
306                         set {
307                                 backColor = value;
308                         }
309                 }
310
311                 public Color BackgroundColor {
312                         get {
313                                 return background_color;
314                         }
315                         set {
316                                  if (background_color != value) {
317                                         background_color = value;
318                                         OnBackgroundColorChanged (EventArgs.Empty);
319                                         Refresh ();
320                                 }
321                         }
322                 }
323
324                 [Browsable(false)]
325                 [EditorBrowsable(EditorBrowsableState.Never)]
326                 public Image BackgroundImage {
327                         get {
328                                 return base.BackgroundImage;
329                         }
330
331                         set {
332                                 base.BackgroundImage = value;
333                         }
334                 }
335
336                 [DispId(-504)]
337                 [DefaultValue(BorderStyle.Fixed3D)]
338                 public BorderStyle BorderStyle {
339                         get {
340                                 return border_style;
341                         }
342
343                         set {
344                                  if (border_style != value) {
345                                         border_style = value;
346                                         CalcAreasAndInvalidate ();
347                                         OnBorderStyleChanged (EventArgs.Empty);                                 
348                                 }
349                         }
350                 }
351
352                 public Color CaptionBackColor {
353                         get {
354                                 return caption_backcolor;
355                         }
356
357                         set {
358                                 if (caption_backcolor != value) {
359                                         caption_backcolor = value;
360                                         grid_drawing.InvalidateCaption ();
361                                 }
362                         }
363                 }
364
365                 [Localizable(true)]
366                 [AmbientValue(null)]
367                 public Font CaptionFont {
368                         get {
369                                 if (caption_font == null) {
370                                         return Font;
371                                 }
372
373                                 return caption_font;
374                         }
375
376                         set {
377                                 if (caption_font != null && caption_font.Equals (value)) {
378                                         return;
379                                 }
380
381                                 caption_font = value;
382                                 CalcAreasAndInvalidate ();
383                         }
384                 }
385
386                 public Color CaptionForeColor {
387                         get {
388                                 return caption_forecolor;
389                         }
390
391                         set {
392                                 if (caption_forecolor != value) {
393                                         caption_forecolor = value;
394                                         grid_drawing.InvalidateCaption ();
395                                 }
396                         }
397                 }
398
399                 [Localizable(true)]
400                 [DefaultValue("")]
401                 public string CaptionText {
402                         get {
403                                 return caption_text;
404                         }
405
406                         set {
407                                 if (caption_text != value) {
408                                         caption_text = value;
409                                         grid_drawing.InvalidateCaption ();
410                                 }
411                         }
412                 }
413
414                 [DefaultValue(true)]
415                 public bool CaptionVisible {
416                         get {
417                                 return caption_visible;
418                         }
419
420                         set {
421                                 if (caption_visible != value) {
422                                         caption_visible = value;
423                                         CalcAreasAndInvalidate ();
424                                         OnCaptionVisibleChanged (EventArgs.Empty);
425                                 }
426                         }
427                 }
428
429                 [DefaultValue(true)]
430                 public bool ColumnHeadersVisible {
431                         get {
432                                 return columnheaders_visible;
433                         }
434
435                         set {
436                                 if (columnheaders_visible != value) {
437                                         columnheaders_visible = value;
438                                         CalcAreasAndInvalidate ();
439                                 }
440                         }
441                 }
442
443                 [Browsable(false)]
444                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
445                 public DataGridCell CurrentCell {
446                         get {
447                                 return current_cell;
448                         }
449
450                         set {
451                                 if (!current_cell.Equals (value)) {
452                                         CancelEditing ();
453                                         
454                                         int old_row = current_cell.RowNumber;
455                                         
456                                         if (value.RowNumber >= RowsCount) {
457                                                 value.RowNumber = RowsCount == 0 ? 0 : RowsCount - 1;
458                                         }
459                                         
460                                         if (value.ColumnNumber >= CurrentTableStyle.GridColumnStyles.Count) {
461                                                 value.ColumnNumber = CurrentTableStyle.GridColumnStyles.Count == 0 ? 0: CurrentTableStyle.GridColumnStyles.Count - 1;
462                                         }
463                                         
464                                         EnsureCellVisilibility (value);
465                                         current_cell = value;                                   
466                                         
467                                         if (current_cell.RowNumber != old_row) {
468                                                 grid_drawing.InvalidateRowHeader (old_row);
469                                         }
470                                         
471                                         accept_listmgrevents = false;
472
473                                         if (cached_currencymgr_events !=  null) {
474                                                 cached_currencymgr_events.Position = current_cell.RowNumber;
475                                         }
476                                         accept_listmgrevents = true;
477                                         InvalidateCurrentRowHeader ();
478                                         OnCurrentCellChanged (EventArgs.Empty);
479                                 }
480                         }
481                 }
482
483                 [Browsable(false)]
484                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
485                 public int CurrentRowIndex {
486                         get {
487                                 if (ListManager == null) {
488                                         return -1;
489                                 }
490                                 
491                                 return current_cell.RowNumber;
492                         }
493
494                         set {
495                                 if (current_cell.RowNumber != value) {
496                                         CurrentCell = new DataGridCell (value, current_cell.ColumnNumber);
497                                 }
498                         }
499                 }
500
501                 [Browsable(false)]
502                 [EditorBrowsable(EditorBrowsableState.Never)]
503                 public override Cursor Cursor {
504                         get {
505                                 return base.Cursor;
506                         }
507                         set {
508                                 base.Cursor = value;
509                         }
510                 }
511
512                 [DefaultValue(null)]
513                 [Editor ("System.Windows.Forms.Design.DataMemberListEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
514                 public string DataMember {
515                         get { return datamember; }
516                         set {
517                                 if (SetDataMember (value)) {                                    
518                                         SetDataSource (datasource);
519                                         if (styles_collection.Contains (value) == true) {
520                                                 CurrentTableStyle = styles_collection[value];
521                                                 current_style.CreateColumnsForTable (true);
522                                         } else {
523                                                 CurrentTableStyle = default_style;
524                                                 current_style.GridColumnStyles.Clear ();
525                                                 current_style.CreateColumnsForTable (false);
526                                         }                                       
527                                 }
528                         }
529                 }
530
531                 [DefaultValue(null)]
532                 [RefreshProperties(RefreshProperties.Repaint)]
533                 [TypeConverter("System.Windows.Forms.Design.DataSourceConverter, " + Consts.AssemblySystem_Design)]
534                 public object DataSource {
535                         get {
536                                 return datasource;
537                         }
538
539                         set {
540                                 if (SetDataSource (value)) {
541                                         SetNewDataSource ();                                    
542                                 }
543                         }
544                 }
545
546                 protected override Size DefaultSize {
547                         get {
548                                 return new Size (130, 80);
549                         }
550                 }
551
552                 [Browsable(false)]
553                 public int FirstVisibleColumn {
554                         get {
555                                 return firstvisible_column;
556                         }
557                 }
558
559                 [DefaultValue(false)]
560                 public bool FlatMode {
561                         get {
562                                 return flatmode;
563                         }
564
565                         set {
566                                 if (flatmode != value) {
567                                         flatmode = value;
568                                         OnFlatModeChanged (EventArgs.Empty);
569                                         Refresh ();
570                                 }
571                         }
572                 }
573
574                 public Color ForeColor {
575                         get {
576                                 return base.ForeColor;
577                         }
578
579                         set {
580                                 base.ForeColor = value;
581                         }
582                 }
583
584                 public Color GridLineColor {
585                         get {
586                                 return gridline_color;
587                         }
588
589                         set {
590                                 if (value == Color.Empty) {
591                                         throw new ArgumentException ("Color.Empty value is invalid.");
592                                 }
593
594                                 if (gridline_color != value) {
595                                         gridline_color = value;
596                                         Refresh ();
597                                 }
598                         }
599                 }
600
601                 [DefaultValue(DataGridLineStyle.Solid)]
602                 public DataGridLineStyle GridLineStyle {
603                         get {
604                                 return gridline_style;
605                         }
606
607                         set {
608                                 if (gridline_style != value) {
609                                         gridline_style = value;
610                                         Refresh ();
611                                 }
612                         }
613                 }
614
615                 public Color HeaderBackColor {
616                         get {
617                                 return header_backcolor;
618                         }
619
620                         set {
621                                 if (value == Color.Empty) {
622                                         throw new ArgumentException ("Color.Empty value is invalid.");
623                                 }
624
625                                 if (header_backcolor != value) {
626                                         header_backcolor = value;
627                                         Refresh ();
628                                 }
629                         }
630                 }
631
632                 public Font HeaderFont {
633                         get {
634                                 return header_font;
635                         }
636
637                         set {
638                                 if (header_font != null && !header_font.Equals (value)) {
639                                         header_font = value;
640                                         CalcAreasAndInvalidate ();
641                                 }
642                         }
643                 }
644
645                 public Color HeaderForeColor {
646                         get {
647                                 return header_forecolor;
648                         }
649
650                         set {
651                                 if (header_forecolor != value) {
652                                         header_forecolor = value;
653                                         Refresh ();
654                                 }
655                         }
656                 }
657
658                 protected ScrollBar HorizScrollBar {
659                         get {
660                                 return horiz_scrollbar;
661                         }
662                 }
663
664                 public object this [DataGridCell cell] {
665                         get  {
666                                 return this [cell.RowNumber, cell.ColumnNumber];
667                         }
668
669                         set {
670                                 this [cell.RowNumber, cell.ColumnNumber] = value;
671                         }
672                 }
673
674                 public object this [int rowIndex, int columnIndex] {
675                         get  {
676                                 return CurrentTableStyle.GridColumnStyles[columnIndex].GetColumnValueAtRow (ListManager,
677                                         rowIndex);
678                         }
679
680                         set {
681                                 CurrentTableStyle.GridColumnStyles[columnIndex].SetColumnValueAtRow (ListManager,
682                                         rowIndex, value);
683                         }
684                 }
685
686                 public Color LinkColor {
687                         get {
688                                 return link_color;
689                         }
690                         set {
691                                 if (link_color != value) {
692                                         link_color = value;
693                                         Refresh ();
694                                 }
695                         }
696                 }
697
698                 [ComVisible(false)]
699                 [Browsable(false)]
700                 [EditorBrowsable(EditorBrowsableState.Never)]
701                 public Color LinkHoverColor {
702                         get {
703                                 return link_hovercolor;
704                         }
705
706                         set {
707                                 if (link_hovercolor != value) {
708                                         link_hovercolor = value;
709                                         Refresh ();
710                                 }
711                         }
712                 }
713
714                 [Browsable(false)]
715                 [EditorBrowsable(EditorBrowsableState.Advanced)]
716                 protected internal CurrencyManager ListManager {
717                         get {
718                                 if (BindingContext == null || DataSource  == null) {
719                                         return null;
720                                 }
721
722                                 if (cached_currencymgr != null) {
723                                         return cached_currencymgr;
724                                 }
725
726                                 // If we bind real_datasource object we do not get the events from ListManger
727                                 // since the object is not the datasource and does not match
728                                 cached_currencymgr = (CurrencyManager) BindingContext [real_datasource, DataMember];
729                                 cached_currencymgr_events = (CurrencyManager) BindingContext [datasource, DataMember];
730                                 ConnectListManagerEvents ();
731                                 return cached_currencymgr;
732                         }
733
734                         set {
735                                 throw new NotSupportedException ("Operation is not supported.");
736                         }
737                 }
738
739                 public Color ParentRowsBackColor {
740                         get {
741                                 return parentrowsback_color;
742                         }
743
744                         set {
745                                 if (parentrowsback_color != value) {
746                                         parentrowsback_color = value;
747                                         if (parentrows_visible) {
748                                                 Refresh ();
749                                         }
750                                 }
751                         }
752                 }
753
754                 public Color ParentRowsForeColor {
755                         get {
756                                 return parentrowsfore_color;
757                         }
758
759                         set {
760                                 if (parentrowsfore_color != value) {
761                                         parentrowsfore_color = value;
762                                         if (parentrows_visible) {
763                                                 Refresh ();
764                                         }
765                                 }
766                         }
767                 }
768
769                 [DefaultValue(DataGridParentRowsLabelStyle.Both)]
770                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
771                 public DataGridParentRowsLabelStyle ParentRowsLabelStyle {
772                         get {
773                                 return parentrowslabel_style;
774                         }
775
776                         set {
777                                 if (parentrowslabel_style != value) {
778                                         parentrowslabel_style = value;
779                                         if (parentrows_visible) {
780                                                 Refresh ();
781                                         }
782
783                                         OnParentRowsLabelStyleChanged (EventArgs.Empty);
784                                 }
785                         }
786                 }
787
788                 [DefaultValue(true)]
789                 public bool ParentRowsVisible {
790                         get {
791                                 return parentrows_visible;
792                         }
793
794                         set {
795                                 if (parentrows_visible != value) {
796                                         parentrows_visible = value;
797                                         CalcAreasAndInvalidate ();
798                                         OnParentRowsVisibleChanged (EventArgs.Empty);
799                                 }
800                         }
801                 }
802
803                 // Settting this property seems to have no effect.
804                 [DefaultValue(75)]
805                 [TypeConverter(typeof(DataGridPreferredColumnWidthTypeConverter))]
806                 public int PreferredColumnWidth {
807                         get {
808                                 return preferredcolumn_width;
809                         }
810
811                         set {
812                                 if (value < 0) {
813                                         throw new ArgumentException ("PreferredColumnWidth is less than 0");
814                                 }
815
816                                 if (preferredcolumn_width != value) {
817                                         preferredcolumn_width = value;
818                                         Refresh ();
819                                 }
820                         }
821                 }
822
823                 public int PreferredRowHeight {
824                         get {
825                                 return preferredrow_height;
826                         }
827
828                         set {
829                                 if (preferredrow_height != value) {
830                                         preferredrow_height = value;
831                                         CalcAreasAndInvalidate ();
832                                 }
833                         }
834                 }
835
836                 [DefaultValue(false)]
837                 public bool ReadOnly {
838                         get {
839                                 return _readonly;
840                         }
841
842                         set {
843                                 if (_readonly != value) {
844                                         _readonly = value;
845                                         OnReadOnlyChanged (EventArgs.Empty);
846                                         CalcAreasAndInvalidate ();
847                                 }
848                         }
849                 }
850
851                 [DefaultValue(true)]
852                 public bool RowHeadersVisible {
853                         get {
854                                 return rowheaders_visible;
855                         }
856
857                         set {
858                                 if (rowheaders_visible != value) {
859                                         rowheaders_visible = value;
860                                         CalcAreasAndInvalidate ();
861                                 }
862                         }
863                 }
864
865                 [DefaultValue(35)]
866                 public int RowHeaderWidth {
867                         get {
868                                 return rowheaders_width;
869                         }
870
871                         set {
872                                 if (rowheaders_width != value) {
873                                         rowheaders_width = value;
874                                         CalcAreasAndInvalidate ();
875                                 }
876                         }
877                 }
878
879                 public Color SelectionBackColor {
880                         get {
881                                 return selection_backcolor;
882                         }
883
884                         set {
885                                 if (selection_backcolor != value) {
886                                         selection_backcolor = value;
887                                         Refresh ();
888                                 }
889                         }
890                 }
891
892                 public Color SelectionForeColor  {
893                         get {
894                                 return selection_forecolor;
895                         }
896
897                         set {
898                                 if (selection_forecolor != value) {
899                                         selection_forecolor = value;
900                                         Refresh ();
901                                 }
902                         }
903                 }
904
905                 public override ISite Site {
906                         get {
907                                 return base.Site;
908                         }
909                         set {
910                                 base.Site = value;
911                         }
912                 }
913
914                 [Localizable(true)]
915                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
916                 public GridTableStylesCollection TableStyles {
917                         get { return styles_collection; }
918                 }
919
920                 [Bindable(false)]
921                 [Browsable(false)]
922                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
923                 [EditorBrowsable(EditorBrowsableState.Never)]
924                 public override string Text {
925                         get {
926                                 return base.Text;
927                         }
928                         set {
929                                 base.Text = value;
930                         }
931                 }
932
933                 [Browsable(false)]
934                 [EditorBrowsable(EditorBrowsableState.Advanced)]
935                 protected ScrollBar VertScrollBar {
936                         get {
937                                 return vert_scrollbar;
938                         }
939                 }
940
941                 [Browsable(false)]
942                 public int VisibleColumnCount {
943                         get {
944                                 return visiblecolumn_count;
945                         }
946                 }
947
948                 // Calculated at DataGridDrawing.CalcRowsHeaders
949                 [Browsable(false)]
950                 public int VisibleRowCount {
951                         get {
952                                 return visiblerow_count;
953                         }
954                 }
955
956                 #endregion      // Public Instance Properties
957
958                 #region Private Instance Properties
959                 internal DataGridTableStyle CurrentTableStyle {
960                         get {
961                                 return current_style;
962                         }
963                         set {
964                                 current_style = value;
965                                 current_style.DataGrid = this;
966                                 CalcAreasAndInvalidate ();
967                         }
968                 }
969
970                 internal int FirstVisibleRow {
971                         get { return first_visiblerow; }
972                         set { first_visiblerow = value;}
973                 }
974                 
975                 internal int RowsCount {
976                         get {                           
977                                 if (ListManager != null) {
978                                         return ListManager.Count;                                       
979                                 }
980
981                                 return 0;
982                         }
983                 }
984
985                 internal int RowHeight {
986                         get {
987                                 if (CurrentTableStyle.CurrentPreferredRowHeight > Font.Height + 3 + 1 /* line */) {
988                                         return CurrentTableStyle.CurrentPreferredRowHeight;
989
990                                 } else {
991                                         return Font.Height + 3 + 1 /* line */;
992                                 }
993                         }
994                 }
995                 
996                 internal bool ShowEditRow {
997                         get {
998                                 if (ListManager != null && ListManager.CanAddRows == false) {
999                                         return false;
1000                                 }
1001                                                                 
1002                                 return _readonly == false;
1003                         }
1004                 }
1005                 
1006                 // It should only be shown if there are relations that
1007                 // we do not support right now
1008                 internal bool ShowParentRowsVisible {
1009                         get {
1010                                 //See parentrows_visible;
1011                                 return false;
1012                         }
1013                 }
1014                 
1015                 #endregion Private Instance Properties
1016
1017                 #region Public Instance Methods
1018
1019                 [MonoTODO]
1020                 public virtual bool BeginEdit (DataGridColumnStyle gridColumn, int rowNumber)
1021                 {
1022                         return false;
1023                 }
1024
1025                 public virtual void BeginInit ()
1026                 {
1027                         begininit = true;
1028                 }
1029
1030                 protected virtual void CancelEditing ()
1031                 {                       
1032                         if (current_cell.ColumnNumber < CurrentTableStyle.GridColumnStyles.Count) {
1033                                 CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].Abort (current_cell.RowNumber);
1034                         }
1035                         
1036                         if (is_adding == true) {
1037                                 ListManager.RemoveAt (RowsCount - 1);
1038                                 is_adding = false;
1039                         }
1040                         
1041                         is_editing = false;
1042                         is_changing = false;
1043                         InvalidateCurrentRowHeader ();
1044                 }
1045
1046                 [MonoTODO]
1047                 public void Collapse (int row)
1048                 {
1049
1050                 }
1051
1052                 protected internal virtual void ColumnStartedEditing (Control editingControl)
1053                 {
1054
1055                 }
1056
1057                 protected internal virtual void ColumnStartedEditing (Rectangle bounds)
1058                 {
1059
1060                 }
1061
1062                 protected override AccessibleObject CreateAccessibilityInstance ()
1063                 {
1064                         return base.CreateAccessibilityInstance ();
1065                 }
1066
1067                 protected virtual DataGridColumnStyle CreateGridColumn (PropertyDescriptor prop)
1068                 {
1069                         return CreateGridColumn (prop, false);
1070                 }
1071
1072                 protected virtual DataGridColumnStyle CreateGridColumn (PropertyDescriptor prop, bool isDefault)
1073                 {
1074                         throw new NotImplementedException();
1075                 }
1076
1077                 protected override void Dispose (bool disposing)
1078                 {
1079                         base.Dispose (disposing);
1080                 }
1081
1082                 public virtual bool EndEdit (DataGridColumnStyle gridColumn, int rowNumber, bool shouldAbort)
1083                 {                                               
1084                         if (is_adding == true) {                                
1085                                 if (shouldAbort) {
1086                                         ListManager.CancelCurrentEdit ();
1087                                 } else {
1088                                         ListManager.EndCurrentEdit ();
1089                                         CalcAreasAndInvalidate ();
1090                                 }
1091                                 is_adding = false;
1092                         } 
1093
1094                         if (shouldAbort || gridColumn.ParentReadOnly ==true) {
1095                                 gridColumn.Abort (rowNumber);
1096                         } else {
1097                                 gridColumn.Commit (ListManager, rowNumber);
1098                         }
1099
1100                         is_editing = false;
1101                         is_changing = false;
1102                         InvalidateCurrentRowHeader ();
1103                         return true;
1104                 }
1105
1106                 public virtual void EndInit ()
1107                 {
1108                         begininit = false;
1109                 }
1110
1111                 public void Expand (int row)
1112                 {
1113
1114                 }
1115
1116                 public Rectangle GetCellBounds (DataGridCell cell)
1117                 {
1118                         return GetCellBounds (cell.RowNumber, cell.ColumnNumber);
1119                 }
1120
1121                 public Rectangle GetCellBounds (int row, int col)
1122                 {
1123                         return grid_drawing.GetCellBounds (row, col);
1124                 }
1125
1126                 public Rectangle GetCurrentCellBounds ()
1127                 {
1128                         return GetCellBounds (current_cell.RowNumber, current_cell.ColumnNumber);
1129                 }
1130
1131                 protected virtual string GetOutputTextDelimiter ()
1132                 {
1133                         return string.Empty;
1134                 }
1135
1136                 protected virtual void GridHScrolled (object sender, ScrollEventArgs se)
1137                 {
1138                         if (se.NewValue == horz_pixeloffset ||
1139                                 se.Type == ScrollEventType.EndScroll) {
1140                                 return;
1141                         }
1142
1143                         ScrollToColumnInPixels (se.NewValue);
1144                 }
1145
1146                 protected virtual void GridVScrolled (object sender, ScrollEventArgs se)
1147                 {
1148                         int old_first_visiblerow = first_visiblerow;
1149                         first_visiblerow = se.NewValue;
1150                         grid_drawing.UpdateVisibleRowCount ();
1151                         
1152                         if (first_visiblerow == old_first_visiblerow) {
1153                                 return;
1154                         }                       
1155                         ScrollToRow (old_first_visiblerow, first_visiblerow);
1156                 }
1157
1158                 public HitTestInfo HitTest (Point position)
1159                 {
1160                         return HitTest (position.X, position.Y);
1161                 }
1162
1163                 public HitTestInfo HitTest (int x, int y)
1164                 {
1165                         return grid_drawing.HitTest (x, y);
1166                 }
1167
1168                 [MonoTODO]
1169                 public bool IsExpanded (int rowNumber)
1170                 {
1171                         return false;
1172                 }
1173
1174                 public bool IsSelected (int row)
1175                 {
1176                         return selected_rows[row] != null;
1177                 }
1178
1179                 [MonoTODO]
1180                 public void NavigateBack ()
1181                 {
1182
1183                 }
1184
1185                 [MonoTODO]
1186                 public void NavigateTo (int rowNumber, string relationName)
1187                 {
1188
1189                 }
1190
1191                 protected virtual void OnAllowNavigationChanged (EventArgs e)
1192                 {
1193                         if (AllowNavigationChanged != null) {
1194                                 AllowNavigationChanged (this, e);
1195                         }
1196                 }
1197
1198                 protected void OnBackButtonClicked (object sender,  EventArgs e)
1199                 {
1200                         if (BackButtonClick != null) {
1201                                 BackButtonClick (sender, e);
1202                         }
1203                 }
1204
1205                 protected override void OnBackColorChanged (EventArgs e)
1206                 {
1207                         base.OnBackColorChanged (e);
1208                 }
1209
1210                 protected virtual void OnBackgroundColorChanged (EventArgs e)
1211                 {
1212                         if (BackgroundColorChanged != null) {
1213                                 BackgroundColorChanged (this, e);
1214                         }
1215                 }
1216
1217                 protected override void OnBindingContextChanged( EventArgs e)
1218                 {
1219                         base.OnBindingContextChanged (e);
1220                 }
1221
1222                 protected virtual void OnBorderStyleChanged (EventArgs e)
1223                 {
1224                         if (BorderStyleChanged != null) {
1225                                 BorderStyleChanged (this, e);
1226                         }
1227                 }
1228
1229                 protected virtual void OnCaptionVisibleChanged (EventArgs e)
1230                 {
1231                         if (CaptionVisibleChanged != null) {
1232                                 CaptionVisibleChanged (this, e);
1233                         }
1234                 }
1235
1236                 protected virtual void OnCurrentCellChanged (EventArgs e)
1237                 {
1238                         if (CurrentCellChanged != null) {
1239                                 CurrentCellChanged (this, e);
1240                         }
1241                 }
1242
1243                 protected virtual void OnDataSourceChanged (EventArgs e)
1244                 {
1245                         if (DataSourceChanged != null) {
1246                                 DataSourceChanged (this, e);
1247                         }
1248                 }
1249
1250                 protected override void OnEnter (EventArgs e)
1251                 {
1252                         base.OnEnter (e);
1253                 }
1254
1255                 protected virtual void OnFlatModeChanged (EventArgs e)
1256                 {
1257                         if (FlatModeChanged != null) {
1258                                 FlatModeChanged (this, e);
1259                         }
1260                 }
1261
1262                 protected override void OnFontChanged (EventArgs e)
1263                 {
1264                         grid_drawing.CalcGridAreas ();
1265                         base.OnFontChanged (e);
1266                 }
1267
1268                 protected override void OnForeColorChanged (EventArgs e)
1269                 {
1270                         base.OnForeColorChanged (e);
1271                 }
1272
1273                 protected override void OnHandleCreated (EventArgs e)
1274                 {
1275                         base.OnHandleCreated (e);
1276                         grid_drawing.CalcGridAreas ();
1277                 }
1278
1279                 protected override void OnHandleDestroyed (EventArgs e)
1280                 {
1281                         base.OnHandleDestroyed (e);
1282                 }
1283
1284                 protected override void OnKeyDown (KeyEventArgs ke)
1285                 {
1286                         base.OnKeyDown (ke);
1287                         
1288                         if (ProcessGridKey (ke) == true) {
1289                                 ke.Handled = true;
1290                         }
1291
1292                         CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].OnKeyDown
1293                                 (ke, current_cell.RowNumber, current_cell.ColumnNumber);
1294                 }
1295
1296                 protected override void OnKeyPress (KeyPressEventArgs kpe)
1297                 {
1298                         base.OnKeyPress (kpe);
1299                 }
1300
1301                 protected override void OnLayout (LayoutEventArgs levent)
1302                 {
1303                         base.OnLayout (levent);
1304                 }
1305
1306                 protected override void OnLeave (EventArgs e)
1307                 {
1308                         base.OnLeave (e);
1309                 }
1310
1311                 protected override void OnMouseDown (MouseEventArgs e)
1312                 {
1313                         base.OnMouseDown (e);
1314
1315                         HitTestInfo testinfo;
1316                         testinfo = grid_drawing.HitTest (e.X, e.Y);
1317
1318                         switch (testinfo.type) {
1319                         case HitTestType.Cell:
1320                         {
1321                                 DataGridCell new_cell = new DataGridCell (testinfo.Row, testinfo.Column);
1322
1323                                 if (new_cell.Equals (current_cell) == false) {
1324                                         CancelEditing ();
1325                                         CurrentCell = new_cell;
1326                                         EditCell (current_cell);
1327
1328                                 } else {
1329                                         CurrentTableStyle.GridColumnStyles[testinfo.Column].OnMouseDown (e, testinfo.Row, testinfo.Column);
1330                                 }
1331
1332                                 break;
1333                         }
1334                         case HitTestType.RowHeader:
1335                         {
1336                                 if (ctrl_pressed == false && shift_pressed == false) {
1337                                         ResetSelection (); // Invalidates selected rows
1338                                 }
1339
1340                                 if (shift_pressed == true) {
1341                                         ShiftSelection (testinfo.Row);
1342                                 } else { // ctrl_pressed or single item
1343                                         Select (testinfo.Row);
1344                                 }
1345
1346                                 CancelEditing ();
1347                                 CurrentCell = new DataGridCell (testinfo.Row, current_cell.ColumnNumber);
1348                                 OnRowHeaderClick (EventArgs.Empty);
1349                                 break;
1350                         }
1351                         default:
1352                                 break;
1353                         }
1354                 }
1355
1356                 protected override void OnMouseLeave (EventArgs e)
1357                 {
1358                         base.OnMouseLeave (e);
1359                 }
1360
1361                 protected override void OnMouseMove (MouseEventArgs e)
1362                 {
1363                         base.OnMouseMove (e);
1364                 }
1365
1366                 protected override void OnMouseUp (MouseEventArgs e)
1367                 {
1368                         base.OnMouseUp (e);
1369                 }
1370
1371                 protected override void OnMouseWheel (MouseEventArgs e)
1372                 {
1373                         base.OnMouseWheel (e);
1374
1375                         if (e.Delta > 0) {
1376                                 if (current_cell.RowNumber > 0) {
1377                                         CurrentCell = new DataGridCell (current_cell.RowNumber - 1, current_cell.ColumnNumber);
1378                                 }
1379                         }
1380                         else {
1381                                 if (current_cell.RowNumber < RowsCount - 1) {
1382                                         CurrentCell = new DataGridCell (current_cell.RowNumber + 1, current_cell.ColumnNumber);                                 
1383                                 }
1384                         }
1385                 }
1386
1387                 protected void OnNavigate (NavigateEventArgs e)
1388                 {
1389                         if (Navigate != null) {
1390                                 Navigate (this, e);
1391                         }
1392                 }
1393
1394                 protected override void OnPaint (PaintEventArgs pe)
1395                 {
1396                         ThemeEngine.Current.DataGridPaint (pe, this);
1397                 }
1398
1399                 protected override void OnPaintBackground (PaintEventArgs ebe)
1400                 {
1401                         base.OnPaintBackground (ebe);
1402                 }
1403
1404                 protected virtual void OnParentRowsLabelStyleChanged (EventArgs e)
1405                 {
1406                         if (ParentRowsLabelStyleChanged != null) {
1407                                 ParentRowsLabelStyleChanged (this, e);
1408                         }
1409                 }
1410
1411                 protected virtual void OnParentRowsVisibleChanged (EventArgs e)
1412                 {
1413                         if (ParentRowsVisibleChanged != null) {
1414                                 ParentRowsVisibleChanged (this, e);
1415                         }
1416                 }
1417
1418                 protected virtual void OnReadOnlyChanged (EventArgs e)
1419                 {
1420                         if (ReadOnlyChanged != null) {
1421                                 ReadOnlyChanged (this, e);
1422                         }
1423                 }
1424
1425                 protected override void OnResize (EventArgs e)
1426                 {
1427                         base.OnResize (e);
1428                 }
1429
1430                 protected void OnRowHeaderClick (EventArgs e)
1431                 {
1432                         if (RowHeaderClick != null) {
1433                                 RowHeaderClick (this, e);
1434                         }
1435                 }
1436
1437                 protected void OnScroll (EventArgs e)
1438                 {
1439                         if (Scroll != null) {
1440                                 Scroll (this, e);
1441                         }
1442                 }
1443
1444                 protected void OnShowParentDetailsButtonClicked (object sender, EventArgs e)
1445                 {
1446                         if (ShowParentDetailsButtonClick != null) {
1447                                 ShowParentDetailsButtonClick (sender, e);
1448                         }
1449                 }
1450
1451                 protected override bool ProcessDialogKey (Keys keyData)
1452                 {
1453                         return base.ProcessDialogKey (keyData);
1454                 }
1455
1456                 protected bool ProcessGridKey (KeyEventArgs ke)
1457                 {
1458                         if (RowsCount == 0) {
1459                                 return false;
1460                         }
1461
1462                         switch (ke.KeyCode) {
1463                         case Keys.ControlKey:
1464                                 ctrl_pressed = true;
1465                                 break;
1466                         case Keys.ShiftKey:
1467                                 shift_pressed = true;
1468                                 break;
1469                         case Keys.Up:
1470                         {
1471                                 if (current_cell.RowNumber > 0) {
1472                                         CurrentCell = new DataGridCell (current_cell.RowNumber - 1, current_cell.ColumnNumber);
1473                                         EditCell (current_cell);
1474                                 }
1475                                 break;
1476                         }
1477                         case Keys.Down:
1478                         {
1479                                 if (current_cell.RowNumber < RowsCount - 1) {
1480                                         CurrentCell = new DataGridCell (current_cell.RowNumber + 1, current_cell.ColumnNumber);
1481                                         EditCell (current_cell);
1482                                 }
1483                                 break;
1484                         }
1485                         case Keys.Tab:
1486                         case Keys.Right:
1487                         {                               
1488                                 if (current_cell.ColumnNumber + 1 < CurrentTableStyle.GridColumnStyles.Count) {
1489                                         CurrentCell = new DataGridCell (current_cell.RowNumber, current_cell.ColumnNumber + 1);
1490                                         EditCell (current_cell);
1491                                 }
1492                                 break;
1493                         }
1494                         case Keys.Left:
1495                         {
1496                                 if (current_cell.ColumnNumber > 0) {
1497                                         CurrentCell = new DataGridCell (current_cell.RowNumber, current_cell.ColumnNumber - 1);
1498                                         EditCell (current_cell);
1499                                 }
1500                                 break;
1501                         }
1502                         case Keys.PageUp:
1503                         {
1504                                 if (current_cell.RowNumber > grid_drawing.VLargeChange) {
1505                                         CurrentCell = new DataGridCell (current_cell.RowNumber - grid_drawing.VLargeChange, current_cell.ColumnNumber);
1506                                 } else {
1507                                         CurrentCell = new DataGridCell (0, current_cell.ColumnNumber);
1508                                 }
1509
1510                                 EditCell (current_cell);
1511                                 break;
1512                         }
1513                         case Keys.PageDown:
1514                         {
1515                                 if (current_cell.RowNumber + grid_drawing.VLargeChange < RowsCount) {
1516                                         CurrentCell = new DataGridCell (current_cell.RowNumber + grid_drawing.VLargeChange, current_cell.ColumnNumber);
1517                                 } else {
1518                                         CurrentCell = new DataGridCell (RowsCount - 1, current_cell.ColumnNumber);
1519                                 }
1520
1521                                 EditCell (current_cell);
1522                                 break;
1523                         }
1524                         case Keys.Home:
1525                         {
1526                                 CurrentCell = new DataGridCell (0, current_cell.ColumnNumber);
1527                                 EditCell (current_cell);
1528                                 break;
1529                         }
1530                         case Keys.End:
1531                         {
1532                                 CurrentCell = new DataGridCell (RowsCount - 1, current_cell.ColumnNumber);
1533                                 EditCell (current_cell);
1534                                 break;
1535                         }
1536                         case Keys.Delete:
1537                         {                               
1538                                 foreach (int row in selected_rows.Keys) {
1539                                         ListManager.RemoveAt (row);                                             
1540                                 }
1541                                 selected_rows.Clear ();
1542                                 CalcAreasAndInvalidate ();
1543                                 break;                                  
1544                         }
1545                         default:
1546                                 return false; // message not processed
1547                         }
1548
1549                         return true; // message processed
1550                 }
1551
1552                 // Called from DataGridTextBox
1553                 protected override bool ProcessKeyPreview (ref Message m)
1554                 {
1555                         Keys key = (Keys) m.WParam.ToInt32 ();
1556                         KeyEventArgs ke = new KeyEventArgs (key);
1557                         if (ProcessGridKey (ke) == true) {
1558                                 return true;
1559                         }
1560
1561                         return base.ProcessKeyPreview (ref m);
1562                 }
1563                 
1564                 protected bool ProcessTabKey (Keys keyData)
1565                 {
1566                         return false;
1567                 }
1568
1569                 public void ResetAlternatingBackColor ()
1570                 {
1571                         alternating_backcolor = def_alternating_backcolor;
1572                 }
1573
1574                 public override void ResetBackColor ()
1575                 {
1576                         base.ResetBackColor ();
1577                 }
1578
1579                 public override void ResetForeColor ()
1580                 {
1581                         base.ResetForeColor ();
1582                 }
1583
1584                 public void ResetGridLineColor ()
1585                 {
1586                         gridline_color = def_gridline_color;
1587                 }
1588
1589                 public void ResetHeaderBackColor ()
1590                 {
1591                         header_backcolor = def_header_backcolor;
1592                 }
1593
1594                 public void ResetHeaderFont ()
1595                 {
1596                         header_font = def_header_font;
1597                 }
1598
1599                 public void ResetHeaderForeColor ()
1600                 {
1601                         header_forecolor = def_header_forecolor;
1602                 }
1603
1604                 public void ResetLinkColor ()
1605                 {
1606                         link_color = def_link_color;
1607                 }
1608
1609                 public void ResetLinkHoverColor ()
1610                 {
1611                         link_hovercolor = def_link_hovercolor;
1612                 }
1613
1614                 protected void ResetSelection ()
1615                 {                       
1616                         foreach (int row in selected_rows.Keys) {
1617                                 grid_drawing.InvalidateRow (row);
1618                                 grid_drawing.InvalidateRowHeader (row);
1619                         }
1620
1621                         selected_rows.Clear ();
1622                 }
1623
1624                 public void ResetSelectionBackColor ()
1625                 {
1626                         selection_backcolor = def_selection_backcolor;
1627                 }
1628
1629                 public void ResetSelectionForeColor ()
1630                 {
1631                         selection_forecolor = def_selection_forecolor;
1632                 }
1633
1634                 public void Select (int row)
1635                 {
1636                         if (selected_rows[row] == null) {
1637                                 selected_rows.Add (row, true);
1638                         } else {
1639                                 selected_rows[row] = true;
1640                         }
1641
1642                         grid_drawing.InvalidateRow (row);
1643                 }
1644
1645                 public void SetDataBinding (object dataSource, string dataMember)
1646                 {
1647                         bool source = SetDataSource (dataSource);
1648                         bool member = SetDataMember (dataMember);
1649                         
1650                         if (source == false  && member == false) {
1651                                 return;
1652                         }
1653
1654                         SetNewDataSource ();
1655                 }
1656
1657                 protected virtual bool ShouldSerializeAlternatingBackColor ()
1658                 {
1659                         return (alternating_backcolor != def_alternating_backcolor);
1660                 }
1661
1662                 protected virtual bool ShouldSerializeBackgroundColor ()
1663                 {
1664                         return (background_color != def_background_color);
1665                 }
1666
1667                 protected virtual bool ShouldSerializeCaptionBackColor ()
1668                 {
1669                         return (caption_backcolor != def_caption_backcolor);
1670                 }
1671
1672                 protected virtual bool ShouldSerializeCaptionForeColor ()
1673                 {
1674                         return (caption_forecolor != def_caption_forecolor);
1675                 }
1676
1677                 protected virtual bool ShouldSerializeGridLineColor ()
1678                 {
1679                         return (gridline_color != def_gridline_color);
1680                 }
1681
1682                 protected virtual bool ShouldSerializeHeaderBackColor ()
1683                 {
1684                         return (header_backcolor != def_header_backcolor);
1685                 }
1686
1687                 protected bool ShouldSerializeHeaderFont ()
1688                 {
1689                         return (header_font != def_header_font);
1690                 }
1691
1692                 protected virtual bool ShouldSerializeHeaderForeColor ()
1693                 {
1694                         return (header_forecolor != def_header_forecolor);
1695                 }
1696
1697                 protected virtual bool ShouldSerializeLinkHoverColor ()
1698                 {
1699                         return (link_hovercolor != def_link_hovercolor);
1700                 }
1701
1702                 protected virtual bool ShouldSerializeParentRowsBackColor ()
1703                 {
1704                         return (parentrowsback_color != def_parentrowsback_color);
1705                 }
1706
1707                 protected virtual bool ShouldSerializeParentRowsForeColor ()
1708                 {
1709                         return (parentrowsback_color != def_parentrowsback_color);
1710                 }
1711
1712                 protected bool ShouldSerializePreferredRowHeight ()
1713                 {
1714                         return (preferredrow_height != def_preferredrow_height);
1715                 }
1716
1717                 protected bool ShouldSerializeSelectionBackColor ()
1718                 {
1719                         return (selection_backcolor != def_selection_backcolor);
1720                 }
1721
1722                 protected virtual bool ShouldSerializeSelectionForeColor ()
1723                 {
1724                         return (selection_forecolor != def_selection_forecolor);
1725                 }
1726
1727                 public void SubObjectsSiteChange (bool site)
1728                 {
1729
1730                 }
1731
1732                 public void UnSelect (int row)
1733                 {
1734                         selected_rows.Remove (row);
1735                         grid_drawing.InvalidateRow (row);
1736
1737                 }
1738                 #endregion      // Public Instance Methods
1739
1740                 #region Private Instance Methods
1741
1742                 internal void CalcAreasAndInvalidate ()
1743                 {
1744                         grid_drawing.CalcGridAreas ();
1745                         Invalidate ();
1746                 }
1747                 
1748                 private void ConnectListManagerEvents ()
1749                 {
1750                         cached_currencymgr_events.CurrentChanged += new EventHandler (OnListManagerCurrentChanged);                     
1751                 }
1752                 
1753                 private void DisconnectListManagerEvents ()
1754                 {
1755                         
1756                 }
1757
1758                 // EndEdit current editing operation
1759                 internal virtual bool EndEdit (bool shouldAbort)
1760                 {
1761                         return EndEdit (CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber],
1762                                 current_cell.RowNumber, shouldAbort);
1763                 }
1764
1765                 private void EnsureCellVisilibility (DataGridCell cell)
1766                 {
1767                         if (cell.ColumnNumber <= first_visiblecolumn ||
1768                                 cell.ColumnNumber + 1 >= first_visiblecolumn + visiblecolumn_count) {                   
1769                                         
1770                                 first_visiblecolumn = grid_drawing.GetFirstColumnForColumnVisilibility (first_visiblecolumn, cell.ColumnNumber);                                                
1771                                 
1772                                 int pixel = grid_drawing.GetColumnStartingPixel (first_visiblecolumn);
1773                                 ScrollToColumnInPixels (pixel);
1774                         }
1775
1776                         if (cell.RowNumber < first_visiblerow ||
1777                                 cell.RowNumber + 1 >= first_visiblerow + visiblerow_count) {
1778
1779                                 if (cell.RowNumber + 1 >= first_visiblerow + visiblerow_count) {
1780                                         int old_first_visiblerow = first_visiblerow;
1781                                         first_visiblerow = 1 + cell.RowNumber - visiblerow_count;
1782                                         grid_drawing.UpdateVisibleRowCount ();
1783                                         ScrollToRow (old_first_visiblerow, first_visiblerow);
1784                                 }else {
1785                                         int old_first_visiblerow = first_visiblerow;
1786                                         first_visiblerow = cell.RowNumber;
1787                                         grid_drawing.UpdateVisibleRowCount ();
1788                                         ScrollToRow (old_first_visiblerow, first_visiblerow);
1789                                 }
1790
1791                                 vert_scrollbar.Value = first_visiblerow;
1792                         }
1793                 }
1794                 
1795                 internal IEnumerable GetDataSource (object source, string member)
1796                 {       
1797                         IListSource src = (IListSource) source;
1798                         IList list = src.GetList();
1799                         IListSource listsource;
1800                         ITypedList typedlist;
1801                                         
1802                         if (source is IEnumerable) {
1803                                 return (IEnumerable) source;
1804                         }
1805                         
1806                         if(src.ContainsListCollection == false) {
1807                                 return list;
1808                         }
1809                         
1810                         listsource = (IListSource) source;
1811                         
1812                         if (listsource == null) {
1813                                 return null;
1814                         }
1815                         
1816                         list = src.GetList ();
1817                         
1818                         if (list == null) {
1819                                 return null;
1820                         }
1821                         
1822                         typedlist = (ITypedList) list;
1823                                 
1824                         if (typedlist == null) {
1825                                 return null;
1826                         }                       
1827
1828                         PropertyDescriptorCollection col = typedlist.GetItemProperties (new PropertyDescriptor [0]);
1829                         PropertyDescriptor prop = col.Find (member, true);
1830                                                                 
1831                         if (prop == null) {
1832                                 if (col.Count > 0) {
1833                                         prop = col[0];
1834
1835                                         if (prop == null) {
1836                                                 return null;
1837                                         }
1838                                 }
1839                         }
1840                         
1841                         IEnumerable result =  (IEnumerable)(prop.GetValue (list[0]));
1842                         return result;          
1843                         
1844                 }
1845
1846                 internal void InvalidateCurrentRowHeader ()
1847                 {
1848                         grid_drawing.InvalidateRowHeader (current_cell.RowNumber);
1849                 }
1850
1851                 private bool SetDataMember (string member)
1852                 {                       
1853                         if (member == datamember) {
1854                                 return false;
1855                         }
1856
1857                         datamember = member;
1858                         real_datasource = GetDataSource (datasource, member);
1859                         DisconnectListManagerEvents ();
1860                         cached_currencymgr = cached_currencymgr_events = null;
1861                         return true;
1862                 }
1863
1864                 private bool SetDataSource (object source)
1865                 {                       
1866
1867                         if (source != null && source as IListSource != null && source as IList != null) {
1868                                 throw new Exception ("Wrong complex data binding source");
1869                         }
1870                         
1871                         current_cell = new DataGridCell ();
1872                         datasource = source;
1873                         DisconnectListManagerEvents ();
1874                         cached_currencymgr = cached_currencymgr_events = null;
1875                         try {
1876                                 real_datasource = GetDataSource (datasource, DataMember);
1877                         }catch (Exception e) {                          
1878                                 real_datasource = source;
1879                         }
1880
1881                         OnDataSourceChanged (EventArgs.Empty);
1882                         return true;
1883                 }
1884
1885                 private void SetNewDataSource ()
1886                 {                               
1887                         current_style.GridColumnStyles.Clear ();
1888                         current_style.CreateColumnsForTable (false);
1889                         CalcAreasAndInvalidate ();                      
1890                 }
1891
1892                 private void OnKeyUpDG (object sender, KeyEventArgs e)
1893                 {
1894                         switch (e.KeyCode) {
1895                         case Keys.ControlKey:
1896                                 ctrl_pressed = false;
1897                                 break;
1898                         case Keys.ShiftKey:
1899                                 shift_pressed = false;
1900                                 break;
1901                         default:
1902                                 break;
1903                         }
1904                 }
1905                 
1906                 private void OnListManagerCurrentChanged (object sender, EventArgs e)
1907                 {                       
1908                         if (accept_listmgrevents == false) {
1909                                 return;
1910                         }
1911                         
1912                         CurrentCell = new DataGridCell (cached_currencymgr_events.Position, current_cell.RowNumber);
1913                 }
1914                 
1915                 private void OnTableStylesCollectionChanged (object sender, CollectionChangeEventArgs e)
1916                 {       
1917                         if (ListManager != null && String.Compare (ListManager.ListName, ((DataGridTableStyle)e.Element).MappingName, true) == 0) {                     
1918                                 CurrentTableStyle = (DataGridTableStyle)e.Element;
1919                                 ((DataGridTableStyle) e.Element).CreateColumnsForTable (false);                         
1920                         }
1921                                                 
1922                         CalcAreasAndInvalidate ();
1923                 }
1924
1925                 private void EditCell (DataGridCell cell)
1926                 {
1927                         ResetSelection (); // Invalidates selected rows
1928                         is_editing = false;
1929                         is_changing = false;
1930                         
1931                         if (ShowEditRow && is_adding == false && cell.RowNumber >= RowsCount) {
1932                                 ListManager.AddNew ();
1933                                 is_adding = true;
1934                                 Invalidate (); // We have just added a new row
1935                         }
1936                         
1937                         CurrentTableStyle.GridColumnStyles[cell.ColumnNumber].Edit (ListManager,
1938                                 cell.RowNumber, GetCellBounds (cell.RowNumber, cell.ColumnNumber),
1939                                 _readonly, string.Empty, true);
1940                 }
1941
1942                 private void ShiftSelection (int index)
1943                 {
1944                         int shorter_item = -1, dist = RowsCount + 1, cur_dist;                  
1945
1946                         foreach (int row in selected_rows.Keys) {
1947
1948                                 if (row > index) {
1949                                         cur_dist = row - index;
1950                                 }
1951                                 else {
1952                                         cur_dist = index - row;
1953                                 }
1954
1955                                 if (cur_dist < dist) {
1956                                         dist = cur_dist;
1957                                         shorter_item = row;
1958                                 }
1959                         }
1960
1961                         if (shorter_item != -1) {
1962                                 int start, end;
1963
1964                                 if (shorter_item > index) {
1965                                         start = index;
1966                                         end = shorter_item;
1967                                 } else {
1968                                         start = shorter_item;
1969                                         end = index;
1970                                 }
1971
1972                                 ResetSelection ();
1973                                 for (int idx = start; idx <= end; idx++) {
1974                                         Select (idx);
1975                                 }
1976                         }
1977                 }
1978
1979                 private void ScrollToColumnInPixels (int pixel)
1980                 {
1981                         Rectangle invalidate = new Rectangle ();
1982                         Rectangle invalidate_column = new Rectangle ();
1983
1984                         if (pixel > horz_pixeloffset) { // ScrollRight
1985                                 int pixels = pixel - horz_pixeloffset;
1986                                 
1987                                 horz_pixeloffset = horiz_scrollbar.Value = pixel;
1988                                 grid_drawing.UpdateVisibleColumn ();
1989
1990                                 // Columns header
1991                                 invalidate_column.X = grid_drawing.ColumnsHeadersArea.X + grid_drawing.ColumnsHeadersArea.Width - pixels;
1992                                 invalidate_column.Y = grid_drawing.ColumnsHeadersArea.Y;
1993                                 invalidate_column.Width = pixels;
1994                                 invalidate_column.Height = grid_drawing.ColumnsHeadersArea.Height;
1995                                 XplatUI.ScrollWindow (Handle, grid_drawing.ColumnsHeadersArea, -pixels, 0, false);
1996
1997                                 // Cells
1998                                 invalidate.X = grid_drawing.CellsArea.X + grid_drawing.CellsArea.Width - pixels;
1999                                 invalidate.Y = grid_drawing.CellsArea.Y;
2000                                 invalidate.Width = pixels;
2001                                 invalidate.Height = grid_drawing.CellsArea.Height;
2002                                 
2003                                 
2004                                 if (columnheaders_visible == true) {
2005                                         invalidate.Y -= grid_drawing.ColumnsHeadersArea.Height;
2006                                         invalidate.Height += grid_drawing.ColumnsHeadersArea.Height;
2007                                 }
2008                                 
2009                                 XplatUI.ScrollWindow (Handle, grid_drawing.CellsArea, -pixels, 0, false);
2010                                 Invalidate (invalidate_column);
2011                                 Invalidate (invalidate);
2012
2013
2014                         } else {
2015                                 int pixels = horz_pixeloffset - pixel;
2016                                 Rectangle area = grid_drawing.CellsArea;
2017                                 
2018                                 horz_pixeloffset = horiz_scrollbar.Value = pixel;
2019                                 grid_drawing.UpdateVisibleColumn ();
2020
2021                                 // Columns header
2022                                 invalidate_column.X = grid_drawing.ColumnsHeadersArea.X;
2023                                 invalidate_column.Y = grid_drawing.ColumnsHeadersArea.Y;
2024                                 invalidate_column.Width = pixels;
2025                                 invalidate_column.Height = grid_drawing.ColumnsHeadersArea.Height;
2026                                 //XplatUI.ScrollWindow (Handle, grid_drawing.ColumnsHeadersArea, pixels, 0, false);
2027
2028                                 // Cells
2029                                 invalidate.X =  grid_drawing.CellsArea.X;
2030                                 invalidate.Y =  grid_drawing.CellsArea.Y;
2031                                 invalidate.Width = pixels;
2032                                 invalidate.Height = grid_drawing.CellsArea.Height;
2033                                 
2034                                 if (columnheaders_visible == true) {
2035                                         invalidate.Y -= grid_drawing.ColumnsHeadersArea.Height;
2036                                         invalidate.Height += grid_drawing.ColumnsHeadersArea.Height;
2037                                         area.Y -= grid_drawing.ColumnsHeadersArea.Height;
2038                                         area.Height += grid_drawing.ColumnsHeadersArea.Height;
2039                                 }
2040                                 
2041                                 XplatUI.ScrollWindow (Handle, area, pixels, 0, false);
2042                                 Invalidate (invalidate);
2043                         }               
2044                         
2045                 }
2046
2047                 private void ScrollToRow (int old_row, int new_row)
2048                 {
2049                         Rectangle invalidate = new Rectangle ();                        
2050                         
2051                         if (new_row > old_row) { // Scrolldown
2052                                 int scrolled_rows = new_row - old_row;
2053                                 int pixels = scrolled_rows * RowHeight;
2054                                 Rectangle rows_area = grid_drawing.CellsArea; // Cells area - partial rows space
2055                                 rows_area.Height = grid_drawing.CellsArea.Height - grid_drawing.CellsArea.Height % RowHeight;
2056                                 
2057                                 invalidate.X =  grid_drawing.CellsArea.X;
2058                                 invalidate.Y =  grid_drawing.CellsArea.Y + rows_area.Height - pixels;
2059                                 invalidate.Width = grid_drawing.CellsArea.Width;
2060                                 invalidate.Height = pixels;
2061
2062                                 XplatUI.ScrollWindow (Handle, rows_area, 0, -pixels, false);
2063
2064                         } else { // ScrollUp
2065                                 int scrolled_rows = old_row - new_row;                          
2066                                 int pixels = scrolled_rows * RowHeight;
2067
2068                                 invalidate.X =  grid_drawing.CellsArea.X;
2069                                 invalidate.Y =  grid_drawing.CellsArea.Y;
2070                                 invalidate.Width = grid_drawing.CellsArea.Width;
2071                                 invalidate.Height = pixels;
2072                                 XplatUI.ScrollWindow (Handle, grid_drawing.CellsArea, 0, pixels, false);                                
2073                         }
2074
2075                         // Right now we use ScrollWindow Invalidate, let's leave remarked it here for X11 if need it
2076                         //Invalidate (invalidate);
2077                         Invalidate (grid_drawing.RowsHeadersArea);
2078                 }
2079
2080                 #endregion Private Instance Methods
2081
2082
2083                 #region Events
2084                 public event EventHandler AllowNavigationChanged;
2085                 public event EventHandler BackButtonClick;
2086                 public event EventHandler BackgroundColorChanged;
2087
2088                 [Browsable(false)]
2089                 [EditorBrowsable(EditorBrowsableState.Never)]
2090                 public new event EventHandler BackgroundImageChanged;
2091
2092                 public event EventHandler BorderStyleChanged;
2093                 public event EventHandler CaptionVisibleChanged;
2094                 public event EventHandler CurrentCellChanged;
2095
2096                 [Browsable(false)]
2097                 [EditorBrowsable(EditorBrowsableState.Never)]
2098                 public new event EventHandler CursorChanged;
2099
2100                 public event EventHandler DataSourceChanged;
2101                 public event EventHandler FlatModeChanged;
2102                 public event NavigateEventHandler Navigate;
2103                 public event EventHandler ParentRowsLabelStyleChanged;
2104                 public event EventHandler ParentRowsVisibleChanged;
2105                 public event EventHandler ReadOnlyChanged;
2106                 protected event EventHandler RowHeaderClick;
2107                 public event EventHandler Scroll;
2108                 public event EventHandler ShowParentDetailsButtonClick;
2109
2110                 [Browsable(false)]
2111                 [EditorBrowsable(EditorBrowsableState.Never)]
2112                 public new event EventHandler TextChanged;
2113                 #endregion      // Events
2114         }
2115 }