1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
23 // Jordi Mas i Hernandez <jordi@ximian.com>
31 using System.ComponentModel;
33 using System.Runtime.InteropServices;
34 using System.Collections;
36 namespace System.Windows.Forms
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
45 public enum HitTestType
57 public sealed class HitTestInfo
59 public static readonly HitTestInfo Nowhere = null;
61 #region Local Variables
64 internal HitTestType type;
65 #endregion // Local Variables
67 #region Private Constructors
68 internal HitTestInfo ()
72 type = HitTestType.None;
77 #region Public Instance Properties
79 get { return column; }
85 public DataGrid.HitTestType Type {
88 #endregion //Public Instance Properties
90 public override bool Equals (object o)
92 if (!(o is HitTestInfo))
95 HitTestInfo obj = (HitTestInfo) o;
96 return (obj.Column == column && obj.Row == row && obj.Type ==type);
99 public override int GetHashCode ()
104 public override string ToString ()
106 return base.ToString ();
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;
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
187 #region Public Constructors
190 grid_drawing = new DataGridDrawing (this);
191 allow_navigation = true;
192 allow_sorting = true;
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;
200 caption_forecolor = def_caption_forecolor;
201 caption_text = string.Empty;
202 caption_visible = true;
203 columnheaders_visible = true;
205 real_datasource = null;
206 datamember = string.Empty;
207 firstvisible_column = 0;
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;
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;
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;
242 default_style = new DataGridTableStyle (true);
243 styles_collection = new GridTableStylesCollection (this);
244 styles_collection.CollectionChanged += new CollectionChangeEventHandler (OnTableStylesCollectionChanged);
246 CurrentTableStyle = default_style;
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);
254 SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
258 #endregion // Public Constructor
260 #region Public Instance Properties
263 public bool AllowNavigation {
265 return allow_navigation;
269 if (allow_navigation != value) {
270 allow_navigation = value;
271 OnAllowNavigationChanged (EventArgs.Empty);
277 public bool AllowSorting {
279 return allow_sorting;
283 if (allow_sorting != value) {
284 allow_sorting = value;
289 public Color AlternatingBackColor {
291 return alternating_backcolor;
295 if (alternating_backcolor != value) {
296 alternating_backcolor = value;
302 public Color BackColor {
311 public Color BackgroundColor {
313 return background_color;
316 if (background_color != value) {
317 background_color = value;
318 OnBackgroundColorChanged (EventArgs.Empty);
325 [EditorBrowsable(EditorBrowsableState.Never)]
326 public Image BackgroundImage {
328 return base.BackgroundImage;
332 base.BackgroundImage = value;
337 [DefaultValue(BorderStyle.Fixed3D)]
338 public BorderStyle BorderStyle {
344 if (border_style != value) {
345 border_style = value;
346 CalcAreasAndInvalidate ();
347 OnBorderStyleChanged (EventArgs.Empty);
352 public Color CaptionBackColor {
354 return caption_backcolor;
358 if (caption_backcolor != value) {
359 caption_backcolor = value;
360 grid_drawing.InvalidateCaption ();
367 public Font CaptionFont {
369 if (caption_font == null) {
377 if (caption_font != null && caption_font.Equals (value)) {
381 caption_font = value;
382 CalcAreasAndInvalidate ();
386 public Color CaptionForeColor {
388 return caption_forecolor;
392 if (caption_forecolor != value) {
393 caption_forecolor = value;
394 grid_drawing.InvalidateCaption ();
401 public string CaptionText {
407 if (caption_text != value) {
408 caption_text = value;
409 grid_drawing.InvalidateCaption ();
415 public bool CaptionVisible {
417 return caption_visible;
421 if (caption_visible != value) {
422 caption_visible = value;
423 CalcAreasAndInvalidate ();
424 OnCaptionVisibleChanged (EventArgs.Empty);
430 public bool ColumnHeadersVisible {
432 return columnheaders_visible;
436 if (columnheaders_visible != value) {
437 columnheaders_visible = value;
438 CalcAreasAndInvalidate ();
444 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
445 public DataGridCell CurrentCell {
451 if (!current_cell.Equals (value)) {
454 int old_row = current_cell.RowNumber;
456 if (value.RowNumber >= RowsCount) {
457 value.RowNumber = RowsCount == 0 ? 0 : RowsCount - 1;
460 if (value.ColumnNumber >= CurrentTableStyle.GridColumnStyles.Count) {
461 value.ColumnNumber = CurrentTableStyle.GridColumnStyles.Count == 0 ? 0: CurrentTableStyle.GridColumnStyles.Count - 1;
464 EnsureCellVisilibility (value);
465 current_cell = value;
467 if (current_cell.RowNumber != old_row) {
468 grid_drawing.InvalidateRowHeader (old_row);
471 accept_listmgrevents = false;
473 if (cached_currencymgr_events != null) {
474 cached_currencymgr_events.Position = current_cell.RowNumber;
476 accept_listmgrevents = true;
477 InvalidateCurrentRowHeader ();
478 OnCurrentCellChanged (EventArgs.Empty);
484 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
485 public int CurrentRowIndex {
487 if (ListManager == null) {
491 return current_cell.RowNumber;
495 if (current_cell.RowNumber != value) {
496 CurrentCell = new DataGridCell (value, current_cell.ColumnNumber);
502 [EditorBrowsable(EditorBrowsableState.Never)]
503 public override Cursor Cursor {
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; }
517 if (SetDataMember (value)) {
518 SetDataSource (datasource);
519 if (styles_collection.Contains (value) == true) {
520 CurrentTableStyle = styles_collection[value];
521 current_style.CreateColumnsForTable (true);
523 CurrentTableStyle = default_style;
524 current_style.GridColumnStyles.Clear ();
525 current_style.CreateColumnsForTable (false);
532 [RefreshProperties(RefreshProperties.Repaint)]
533 [TypeConverter("System.Windows.Forms.Design.DataSourceConverter, " + Consts.AssemblySystem_Design)]
534 public object DataSource {
540 if (SetDataSource (value)) {
546 protected override Size DefaultSize {
548 return new Size (130, 80);
553 public int FirstVisibleColumn {
555 return firstvisible_column;
559 [DefaultValue(false)]
560 public bool FlatMode {
566 if (flatmode != value) {
568 OnFlatModeChanged (EventArgs.Empty);
574 public Color ForeColor {
576 return base.ForeColor;
580 base.ForeColor = value;
584 public Color GridLineColor {
586 return gridline_color;
590 if (value == Color.Empty) {
591 throw new ArgumentException ("Color.Empty value is invalid.");
594 if (gridline_color != value) {
595 gridline_color = value;
601 [DefaultValue(DataGridLineStyle.Solid)]
602 public DataGridLineStyle GridLineStyle {
604 return gridline_style;
608 if (gridline_style != value) {
609 gridline_style = value;
615 public Color HeaderBackColor {
617 return header_backcolor;
621 if (value == Color.Empty) {
622 throw new ArgumentException ("Color.Empty value is invalid.");
625 if (header_backcolor != value) {
626 header_backcolor = value;
632 public Font HeaderFont {
638 if (header_font != null && !header_font.Equals (value)) {
640 CalcAreasAndInvalidate ();
645 public Color HeaderForeColor {
647 return header_forecolor;
651 if (header_forecolor != value) {
652 header_forecolor = value;
658 protected ScrollBar HorizScrollBar {
660 return horiz_scrollbar;
664 public object this [DataGridCell cell] {
666 return this [cell.RowNumber, cell.ColumnNumber];
670 this [cell.RowNumber, cell.ColumnNumber] = value;
674 public object this [int rowIndex, int columnIndex] {
676 return CurrentTableStyle.GridColumnStyles[columnIndex].GetColumnValueAtRow (ListManager,
681 CurrentTableStyle.GridColumnStyles[columnIndex].SetColumnValueAtRow (ListManager,
686 public Color LinkColor {
691 if (link_color != value) {
700 [EditorBrowsable(EditorBrowsableState.Never)]
701 public Color LinkHoverColor {
703 return link_hovercolor;
707 if (link_hovercolor != value) {
708 link_hovercolor = value;
715 [EditorBrowsable(EditorBrowsableState.Advanced)]
716 protected internal CurrencyManager ListManager {
718 if (BindingContext == null || DataSource == null) {
722 if (cached_currencymgr != null) {
723 return cached_currencymgr;
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;
735 throw new NotSupportedException ("Operation is not supported.");
739 public Color ParentRowsBackColor {
741 return parentrowsback_color;
745 if (parentrowsback_color != value) {
746 parentrowsback_color = value;
747 if (parentrows_visible) {
754 public Color ParentRowsForeColor {
756 return parentrowsfore_color;
760 if (parentrowsfore_color != value) {
761 parentrowsfore_color = value;
762 if (parentrows_visible) {
769 [DefaultValue(DataGridParentRowsLabelStyle.Both)]
770 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
771 public DataGridParentRowsLabelStyle ParentRowsLabelStyle {
773 return parentrowslabel_style;
777 if (parentrowslabel_style != value) {
778 parentrowslabel_style = value;
779 if (parentrows_visible) {
783 OnParentRowsLabelStyleChanged (EventArgs.Empty);
789 public bool ParentRowsVisible {
791 return parentrows_visible;
795 if (parentrows_visible != value) {
796 parentrows_visible = value;
797 CalcAreasAndInvalidate ();
798 OnParentRowsVisibleChanged (EventArgs.Empty);
803 // Settting this property seems to have no effect.
805 [TypeConverter(typeof(DataGridPreferredColumnWidthTypeConverter))]
806 public int PreferredColumnWidth {
808 return preferredcolumn_width;
813 throw new ArgumentException ("PreferredColumnWidth is less than 0");
816 if (preferredcolumn_width != value) {
817 preferredcolumn_width = value;
823 public int PreferredRowHeight {
825 return preferredrow_height;
829 if (preferredrow_height != value) {
830 preferredrow_height = value;
831 CalcAreasAndInvalidate ();
836 [DefaultValue(false)]
837 public bool ReadOnly {
843 if (_readonly != value) {
845 OnReadOnlyChanged (EventArgs.Empty);
846 CalcAreasAndInvalidate ();
852 public bool RowHeadersVisible {
854 return rowheaders_visible;
858 if (rowheaders_visible != value) {
859 rowheaders_visible = value;
860 CalcAreasAndInvalidate ();
866 public int RowHeaderWidth {
868 return rowheaders_width;
872 if (rowheaders_width != value) {
873 rowheaders_width = value;
874 CalcAreasAndInvalidate ();
879 public Color SelectionBackColor {
881 return selection_backcolor;
885 if (selection_backcolor != value) {
886 selection_backcolor = value;
892 public Color SelectionForeColor {
894 return selection_forecolor;
898 if (selection_forecolor != value) {
899 selection_forecolor = value;
905 public override ISite Site {
915 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
916 public GridTableStylesCollection TableStyles {
917 get { return styles_collection; }
922 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
923 [EditorBrowsable(EditorBrowsableState.Never)]
924 public override string Text {
934 [EditorBrowsable(EditorBrowsableState.Advanced)]
935 protected ScrollBar VertScrollBar {
937 return vert_scrollbar;
942 public int VisibleColumnCount {
944 return visiblecolumn_count;
948 // Calculated at DataGridDrawing.CalcRowsHeaders
950 public int VisibleRowCount {
952 return visiblerow_count;
956 #endregion // Public Instance Properties
958 #region Private Instance Properties
959 internal DataGridTableStyle CurrentTableStyle {
961 return current_style;
964 current_style = value;
965 current_style.DataGrid = this;
966 CalcAreasAndInvalidate ();
970 internal int FirstVisibleRow {
971 get { return first_visiblerow; }
972 set { first_visiblerow = value;}
975 internal int RowsCount {
977 if (ListManager != null) {
978 return ListManager.Count;
985 internal int RowHeight {
987 if (CurrentTableStyle.CurrentPreferredRowHeight > Font.Height + 3 + 1 /* line */) {
988 return CurrentTableStyle.CurrentPreferredRowHeight;
991 return Font.Height + 3 + 1 /* line */;
996 internal bool ShowEditRow {
998 if (ListManager != null && ListManager.CanAddRows == false) {
1002 return _readonly == false;
1006 // It should only be shown if there are relations that
1007 // we do not support right now
1008 internal bool ShowParentRowsVisible {
1010 //See parentrows_visible;
1015 #endregion Private Instance Properties
1017 #region Public Instance Methods
1020 public virtual bool BeginEdit (DataGridColumnStyle gridColumn, int rowNumber)
1025 public virtual void BeginInit ()
1030 protected virtual void CancelEditing ()
1032 if (current_cell.ColumnNumber < CurrentTableStyle.GridColumnStyles.Count) {
1033 CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].Abort (current_cell.RowNumber);
1036 if (is_adding == true) {
1037 ListManager.RemoveAt (RowsCount - 1);
1042 is_changing = false;
1043 InvalidateCurrentRowHeader ();
1047 public void Collapse (int row)
1052 protected internal virtual void ColumnStartedEditing (Control editingControl)
1057 protected internal virtual void ColumnStartedEditing (Rectangle bounds)
1062 protected override AccessibleObject CreateAccessibilityInstance ()
1064 return base.CreateAccessibilityInstance ();
1067 protected virtual DataGridColumnStyle CreateGridColumn (PropertyDescriptor prop)
1069 return CreateGridColumn (prop, false);
1072 protected virtual DataGridColumnStyle CreateGridColumn (PropertyDescriptor prop, bool isDefault)
1074 throw new NotImplementedException();
1077 protected override void Dispose (bool disposing)
1079 base.Dispose (disposing);
1082 public virtual bool EndEdit (DataGridColumnStyle gridColumn, int rowNumber, bool shouldAbort)
1084 if (is_adding == true) {
1086 ListManager.CancelCurrentEdit ();
1088 ListManager.EndCurrentEdit ();
1089 CalcAreasAndInvalidate ();
1094 if (shouldAbort || gridColumn.ParentReadOnly ==true) {
1095 gridColumn.Abort (rowNumber);
1097 gridColumn.Commit (ListManager, rowNumber);
1101 is_changing = false;
1102 InvalidateCurrentRowHeader ();
1106 public virtual void EndInit ()
1111 public void Expand (int row)
1116 public Rectangle GetCellBounds (DataGridCell cell)
1118 return GetCellBounds (cell.RowNumber, cell.ColumnNumber);
1121 public Rectangle GetCellBounds (int row, int col)
1123 return grid_drawing.GetCellBounds (row, col);
1126 public Rectangle GetCurrentCellBounds ()
1128 return GetCellBounds (current_cell.RowNumber, current_cell.ColumnNumber);
1131 protected virtual string GetOutputTextDelimiter ()
1133 return string.Empty;
1136 protected virtual void GridHScrolled (object sender, ScrollEventArgs se)
1138 if (se.NewValue == horz_pixeloffset ||
1139 se.Type == ScrollEventType.EndScroll) {
1143 ScrollToColumnInPixels (se.NewValue);
1146 protected virtual void GridVScrolled (object sender, ScrollEventArgs se)
1148 int old_first_visiblerow = first_visiblerow;
1149 first_visiblerow = se.NewValue;
1150 grid_drawing.UpdateVisibleRowCount ();
1152 if (first_visiblerow == old_first_visiblerow) {
1155 ScrollToRow (old_first_visiblerow, first_visiblerow);
1158 public HitTestInfo HitTest (Point position)
1160 return HitTest (position.X, position.Y);
1163 public HitTestInfo HitTest (int x, int y)
1165 return grid_drawing.HitTest (x, y);
1169 public bool IsExpanded (int rowNumber)
1174 public bool IsSelected (int row)
1176 return selected_rows[row] != null;
1180 public void NavigateBack ()
1186 public void NavigateTo (int rowNumber, string relationName)
1191 protected virtual void OnAllowNavigationChanged (EventArgs e)
1193 if (AllowNavigationChanged != null) {
1194 AllowNavigationChanged (this, e);
1198 protected void OnBackButtonClicked (object sender, EventArgs e)
1200 if (BackButtonClick != null) {
1201 BackButtonClick (sender, e);
1205 protected override void OnBackColorChanged (EventArgs e)
1207 base.OnBackColorChanged (e);
1210 protected virtual void OnBackgroundColorChanged (EventArgs e)
1212 if (BackgroundColorChanged != null) {
1213 BackgroundColorChanged (this, e);
1217 protected override void OnBindingContextChanged( EventArgs e)
1219 base.OnBindingContextChanged (e);
1222 protected virtual void OnBorderStyleChanged (EventArgs e)
1224 if (BorderStyleChanged != null) {
1225 BorderStyleChanged (this, e);
1229 protected virtual void OnCaptionVisibleChanged (EventArgs e)
1231 if (CaptionVisibleChanged != null) {
1232 CaptionVisibleChanged (this, e);
1236 protected virtual void OnCurrentCellChanged (EventArgs e)
1238 if (CurrentCellChanged != null) {
1239 CurrentCellChanged (this, e);
1243 protected virtual void OnDataSourceChanged (EventArgs e)
1245 if (DataSourceChanged != null) {
1246 DataSourceChanged (this, e);
1250 protected override void OnEnter (EventArgs e)
1255 protected virtual void OnFlatModeChanged (EventArgs e)
1257 if (FlatModeChanged != null) {
1258 FlatModeChanged (this, e);
1262 protected override void OnFontChanged (EventArgs e)
1264 grid_drawing.CalcGridAreas ();
1265 base.OnFontChanged (e);
1268 protected override void OnForeColorChanged (EventArgs e)
1270 base.OnForeColorChanged (e);
1273 protected override void OnHandleCreated (EventArgs e)
1275 base.OnHandleCreated (e);
1276 grid_drawing.CalcGridAreas ();
1279 protected override void OnHandleDestroyed (EventArgs e)
1281 base.OnHandleDestroyed (e);
1284 protected override void OnKeyDown (KeyEventArgs ke)
1286 base.OnKeyDown (ke);
1288 if (ProcessGridKey (ke) == true) {
1292 CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].OnKeyDown
1293 (ke, current_cell.RowNumber, current_cell.ColumnNumber);
1296 protected override void OnKeyPress (KeyPressEventArgs kpe)
1298 base.OnKeyPress (kpe);
1301 protected override void OnLayout (LayoutEventArgs levent)
1303 base.OnLayout (levent);
1306 protected override void OnLeave (EventArgs e)
1311 protected override void OnMouseDown (MouseEventArgs e)
1313 base.OnMouseDown (e);
1315 HitTestInfo testinfo;
1316 testinfo = grid_drawing.HitTest (e.X, e.Y);
1318 switch (testinfo.type) {
1319 case HitTestType.Cell:
1321 DataGridCell new_cell = new DataGridCell (testinfo.Row, testinfo.Column);
1323 if (new_cell.Equals (current_cell) == false) {
1325 CurrentCell = new_cell;
1326 EditCell (current_cell);
1329 CurrentTableStyle.GridColumnStyles[testinfo.Column].OnMouseDown (e, testinfo.Row, testinfo.Column);
1334 case HitTestType.RowHeader:
1336 if (ctrl_pressed == false && shift_pressed == false) {
1337 ResetSelection (); // Invalidates selected rows
1340 if (shift_pressed == true) {
1341 ShiftSelection (testinfo.Row);
1342 } else { // ctrl_pressed or single item
1343 Select (testinfo.Row);
1347 CurrentCell = new DataGridCell (testinfo.Row, current_cell.ColumnNumber);
1348 OnRowHeaderClick (EventArgs.Empty);
1356 protected override void OnMouseLeave (EventArgs e)
1358 base.OnMouseLeave (e);
1361 protected override void OnMouseMove (MouseEventArgs e)
1363 base.OnMouseMove (e);
1366 protected override void OnMouseUp (MouseEventArgs e)
1371 protected override void OnMouseWheel (MouseEventArgs e)
1373 base.OnMouseWheel (e);
1376 if (current_cell.RowNumber > 0) {
1377 CurrentCell = new DataGridCell (current_cell.RowNumber - 1, current_cell.ColumnNumber);
1381 if (current_cell.RowNumber < RowsCount - 1) {
1382 CurrentCell = new DataGridCell (current_cell.RowNumber + 1, current_cell.ColumnNumber);
1387 protected void OnNavigate (NavigateEventArgs e)
1389 if (Navigate != null) {
1394 protected override void OnPaint (PaintEventArgs pe)
1396 ThemeEngine.Current.DataGridPaint (pe, this);
1399 protected override void OnPaintBackground (PaintEventArgs ebe)
1401 base.OnPaintBackground (ebe);
1404 protected virtual void OnParentRowsLabelStyleChanged (EventArgs e)
1406 if (ParentRowsLabelStyleChanged != null) {
1407 ParentRowsLabelStyleChanged (this, e);
1411 protected virtual void OnParentRowsVisibleChanged (EventArgs e)
1413 if (ParentRowsVisibleChanged != null) {
1414 ParentRowsVisibleChanged (this, e);
1418 protected virtual void OnReadOnlyChanged (EventArgs e)
1420 if (ReadOnlyChanged != null) {
1421 ReadOnlyChanged (this, e);
1425 protected override void OnResize (EventArgs e)
1430 protected void OnRowHeaderClick (EventArgs e)
1432 if (RowHeaderClick != null) {
1433 RowHeaderClick (this, e);
1437 protected void OnScroll (EventArgs e)
1439 if (Scroll != null) {
1444 protected void OnShowParentDetailsButtonClicked (object sender, EventArgs e)
1446 if (ShowParentDetailsButtonClick != null) {
1447 ShowParentDetailsButtonClick (sender, e);
1451 protected override bool ProcessDialogKey (Keys keyData)
1453 return base.ProcessDialogKey (keyData);
1456 protected bool ProcessGridKey (KeyEventArgs ke)
1458 if (RowsCount == 0) {
1462 switch (ke.KeyCode) {
1463 case Keys.ControlKey:
1464 ctrl_pressed = true;
1467 shift_pressed = true;
1471 if (current_cell.RowNumber > 0) {
1472 CurrentCell = new DataGridCell (current_cell.RowNumber - 1, current_cell.ColumnNumber);
1473 EditCell (current_cell);
1479 if (current_cell.RowNumber < RowsCount - 1) {
1480 CurrentCell = new DataGridCell (current_cell.RowNumber + 1, current_cell.ColumnNumber);
1481 EditCell (current_cell);
1488 if (current_cell.ColumnNumber + 1 < CurrentTableStyle.GridColumnStyles.Count) {
1489 CurrentCell = new DataGridCell (current_cell.RowNumber, current_cell.ColumnNumber + 1);
1490 EditCell (current_cell);
1496 if (current_cell.ColumnNumber > 0) {
1497 CurrentCell = new DataGridCell (current_cell.RowNumber, current_cell.ColumnNumber - 1);
1498 EditCell (current_cell);
1504 if (current_cell.RowNumber > grid_drawing.VLargeChange) {
1505 CurrentCell = new DataGridCell (current_cell.RowNumber - grid_drawing.VLargeChange, current_cell.ColumnNumber);
1507 CurrentCell = new DataGridCell (0, current_cell.ColumnNumber);
1510 EditCell (current_cell);
1515 if (current_cell.RowNumber + grid_drawing.VLargeChange < RowsCount) {
1516 CurrentCell = new DataGridCell (current_cell.RowNumber + grid_drawing.VLargeChange, current_cell.ColumnNumber);
1518 CurrentCell = new DataGridCell (RowsCount - 1, current_cell.ColumnNumber);
1521 EditCell (current_cell);
1526 CurrentCell = new DataGridCell (0, current_cell.ColumnNumber);
1527 EditCell (current_cell);
1532 CurrentCell = new DataGridCell (RowsCount - 1, current_cell.ColumnNumber);
1533 EditCell (current_cell);
1538 foreach (int row in selected_rows.Keys) {
1539 ListManager.RemoveAt (row);
1541 selected_rows.Clear ();
1542 CalcAreasAndInvalidate ();
1546 return false; // message not processed
1549 return true; // message processed
1552 // Called from DataGridTextBox
1553 protected override bool ProcessKeyPreview (ref Message m)
1555 Keys key = (Keys) m.WParam.ToInt32 ();
1556 KeyEventArgs ke = new KeyEventArgs (key);
1557 if (ProcessGridKey (ke) == true) {
1561 return base.ProcessKeyPreview (ref m);
1564 protected bool ProcessTabKey (Keys keyData)
1569 public void ResetAlternatingBackColor ()
1571 alternating_backcolor = def_alternating_backcolor;
1574 public override void ResetBackColor ()
1576 base.ResetBackColor ();
1579 public override void ResetForeColor ()
1581 base.ResetForeColor ();
1584 public void ResetGridLineColor ()
1586 gridline_color = def_gridline_color;
1589 public void ResetHeaderBackColor ()
1591 header_backcolor = def_header_backcolor;
1594 public void ResetHeaderFont ()
1596 header_font = def_header_font;
1599 public void ResetHeaderForeColor ()
1601 header_forecolor = def_header_forecolor;
1604 public void ResetLinkColor ()
1606 link_color = def_link_color;
1609 public void ResetLinkHoverColor ()
1611 link_hovercolor = def_link_hovercolor;
1614 protected void ResetSelection ()
1616 foreach (int row in selected_rows.Keys) {
1617 grid_drawing.InvalidateRow (row);
1618 grid_drawing.InvalidateRowHeader (row);
1621 selected_rows.Clear ();
1624 public void ResetSelectionBackColor ()
1626 selection_backcolor = def_selection_backcolor;
1629 public void ResetSelectionForeColor ()
1631 selection_forecolor = def_selection_forecolor;
1634 public void Select (int row)
1636 if (selected_rows[row] == null) {
1637 selected_rows.Add (row, true);
1639 selected_rows[row] = true;
1642 grid_drawing.InvalidateRow (row);
1645 public void SetDataBinding (object dataSource, string dataMember)
1647 bool source = SetDataSource (dataSource);
1648 bool member = SetDataMember (dataMember);
1650 if (source == false && member == false) {
1654 SetNewDataSource ();
1657 protected virtual bool ShouldSerializeAlternatingBackColor ()
1659 return (alternating_backcolor != def_alternating_backcolor);
1662 protected virtual bool ShouldSerializeBackgroundColor ()
1664 return (background_color != def_background_color);
1667 protected virtual bool ShouldSerializeCaptionBackColor ()
1669 return (caption_backcolor != def_caption_backcolor);
1672 protected virtual bool ShouldSerializeCaptionForeColor ()
1674 return (caption_forecolor != def_caption_forecolor);
1677 protected virtual bool ShouldSerializeGridLineColor ()
1679 return (gridline_color != def_gridline_color);
1682 protected virtual bool ShouldSerializeHeaderBackColor ()
1684 return (header_backcolor != def_header_backcolor);
1687 protected bool ShouldSerializeHeaderFont ()
1689 return (header_font != def_header_font);
1692 protected virtual bool ShouldSerializeHeaderForeColor ()
1694 return (header_forecolor != def_header_forecolor);
1697 protected virtual bool ShouldSerializeLinkHoverColor ()
1699 return (link_hovercolor != def_link_hovercolor);
1702 protected virtual bool ShouldSerializeParentRowsBackColor ()
1704 return (parentrowsback_color != def_parentrowsback_color);
1707 protected virtual bool ShouldSerializeParentRowsForeColor ()
1709 return (parentrowsback_color != def_parentrowsback_color);
1712 protected bool ShouldSerializePreferredRowHeight ()
1714 return (preferredrow_height != def_preferredrow_height);
1717 protected bool ShouldSerializeSelectionBackColor ()
1719 return (selection_backcolor != def_selection_backcolor);
1722 protected virtual bool ShouldSerializeSelectionForeColor ()
1724 return (selection_forecolor != def_selection_forecolor);
1727 public void SubObjectsSiteChange (bool site)
1732 public void UnSelect (int row)
1734 selected_rows.Remove (row);
1735 grid_drawing.InvalidateRow (row);
1738 #endregion // Public Instance Methods
1740 #region Private Instance Methods
1742 internal void CalcAreasAndInvalidate ()
1744 grid_drawing.CalcGridAreas ();
1748 private void ConnectListManagerEvents ()
1750 cached_currencymgr_events.CurrentChanged += new EventHandler (OnListManagerCurrentChanged);
1753 private void DisconnectListManagerEvents ()
1758 // EndEdit current editing operation
1759 internal virtual bool EndEdit (bool shouldAbort)
1761 return EndEdit (CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber],
1762 current_cell.RowNumber, shouldAbort);
1765 private void EnsureCellVisilibility (DataGridCell cell)
1767 if (cell.ColumnNumber <= first_visiblecolumn ||
1768 cell.ColumnNumber + 1 >= first_visiblecolumn + visiblecolumn_count) {
1770 first_visiblecolumn = grid_drawing.GetFirstColumnForColumnVisilibility (first_visiblecolumn, cell.ColumnNumber);
1772 int pixel = grid_drawing.GetColumnStartingPixel (first_visiblecolumn);
1773 ScrollToColumnInPixels (pixel);
1776 if (cell.RowNumber < first_visiblerow ||
1777 cell.RowNumber + 1 >= first_visiblerow + visiblerow_count) {
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);
1785 int old_first_visiblerow = first_visiblerow;
1786 first_visiblerow = cell.RowNumber;
1787 grid_drawing.UpdateVisibleRowCount ();
1788 ScrollToRow (old_first_visiblerow, first_visiblerow);
1791 vert_scrollbar.Value = first_visiblerow;
1795 internal IEnumerable GetDataSource (object source, string member)
1797 IListSource src = (IListSource) source;
1798 IList list = src.GetList();
1799 IListSource listsource;
1800 ITypedList typedlist;
1802 if (source is IEnumerable) {
1803 return (IEnumerable) source;
1806 if(src.ContainsListCollection == false) {
1810 listsource = (IListSource) source;
1812 if (listsource == null) {
1816 list = src.GetList ();
1822 typedlist = (ITypedList) list;
1824 if (typedlist == null) {
1828 PropertyDescriptorCollection col = typedlist.GetItemProperties (new PropertyDescriptor [0]);
1829 PropertyDescriptor prop = col.Find (member, true);
1832 if (col.Count > 0) {
1841 IEnumerable result = (IEnumerable)(prop.GetValue (list[0]));
1846 internal void InvalidateCurrentRowHeader ()
1848 grid_drawing.InvalidateRowHeader (current_cell.RowNumber);
1851 private bool SetDataMember (string member)
1853 if (member == datamember) {
1857 datamember = member;
1858 real_datasource = GetDataSource (datasource, member);
1859 DisconnectListManagerEvents ();
1860 cached_currencymgr = cached_currencymgr_events = null;
1864 private bool SetDataSource (object source)
1867 if (source != null && source as IListSource != null && source as IList != null) {
1868 throw new Exception ("Wrong complex data binding source");
1871 current_cell = new DataGridCell ();
1872 datasource = source;
1873 DisconnectListManagerEvents ();
1874 cached_currencymgr = cached_currencymgr_events = null;
1876 real_datasource = GetDataSource (datasource, DataMember);
1877 }catch (Exception e) {
1878 real_datasource = source;
1881 OnDataSourceChanged (EventArgs.Empty);
1885 private void SetNewDataSource ()
1887 current_style.GridColumnStyles.Clear ();
1888 current_style.CreateColumnsForTable (false);
1889 CalcAreasAndInvalidate ();
1892 private void OnKeyUpDG (object sender, KeyEventArgs e)
1894 switch (e.KeyCode) {
1895 case Keys.ControlKey:
1896 ctrl_pressed = false;
1899 shift_pressed = false;
1906 private void OnListManagerCurrentChanged (object sender, EventArgs e)
1908 if (accept_listmgrevents == false) {
1912 CurrentCell = new DataGridCell (cached_currencymgr_events.Position, current_cell.RowNumber);
1915 private void OnTableStylesCollectionChanged (object sender, CollectionChangeEventArgs e)
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);
1922 CalcAreasAndInvalidate ();
1925 private void EditCell (DataGridCell cell)
1927 ResetSelection (); // Invalidates selected rows
1929 is_changing = false;
1931 if (ShowEditRow && is_adding == false && cell.RowNumber >= RowsCount) {
1932 ListManager.AddNew ();
1934 Invalidate (); // We have just added a new row
1937 CurrentTableStyle.GridColumnStyles[cell.ColumnNumber].Edit (ListManager,
1938 cell.RowNumber, GetCellBounds (cell.RowNumber, cell.ColumnNumber),
1939 _readonly, string.Empty, true);
1942 private void ShiftSelection (int index)
1944 int shorter_item = -1, dist = RowsCount + 1, cur_dist;
1946 foreach (int row in selected_rows.Keys) {
1949 cur_dist = row - index;
1952 cur_dist = index - row;
1955 if (cur_dist < dist) {
1961 if (shorter_item != -1) {
1964 if (shorter_item > index) {
1968 start = shorter_item;
1973 for (int idx = start; idx <= end; idx++) {
1979 private void ScrollToColumnInPixels (int pixel)
1981 Rectangle invalidate = new Rectangle ();
1982 Rectangle invalidate_column = new Rectangle ();
1984 if (pixel > horz_pixeloffset) { // ScrollRight
1985 int pixels = pixel - horz_pixeloffset;
1987 horz_pixeloffset = horiz_scrollbar.Value = pixel;
1988 grid_drawing.UpdateVisibleColumn ();
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);
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;
2004 if (columnheaders_visible == true) {
2005 invalidate.Y -= grid_drawing.ColumnsHeadersArea.Height;
2006 invalidate.Height += grid_drawing.ColumnsHeadersArea.Height;
2009 XplatUI.ScrollWindow (Handle, grid_drawing.CellsArea, -pixels, 0, false);
2010 Invalidate (invalidate_column);
2011 Invalidate (invalidate);
2015 int pixels = horz_pixeloffset - pixel;
2016 Rectangle area = grid_drawing.CellsArea;
2018 horz_pixeloffset = horiz_scrollbar.Value = pixel;
2019 grid_drawing.UpdateVisibleColumn ();
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);
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;
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;
2041 XplatUI.ScrollWindow (Handle, area, pixels, 0, false);
2042 Invalidate (invalidate);
2047 private void ScrollToRow (int old_row, int new_row)
2049 Rectangle invalidate = new Rectangle ();
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;
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;
2062 XplatUI.ScrollWindow (Handle, rows_area, 0, -pixels, false);
2064 } else { // ScrollUp
2065 int scrolled_rows = old_row - new_row;
2066 int pixels = scrolled_rows * RowHeight;
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);
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);
2080 #endregion Private Instance Methods
2084 public event EventHandler AllowNavigationChanged;
2085 public event EventHandler BackButtonClick;
2086 public event EventHandler BackgroundColorChanged;
2089 [EditorBrowsable(EditorBrowsableState.Never)]
2090 public new event EventHandler BackgroundImageChanged;
2092 public event EventHandler BorderStyleChanged;
2093 public event EventHandler CaptionVisibleChanged;
2094 public event EventHandler CurrentCellChanged;
2097 [EditorBrowsable(EditorBrowsableState.Never)]
2098 public new event EventHandler CursorChanged;
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;
2111 [EditorBrowsable(EditorBrowsableState.Never)]
2112 public new event EventHandler TextChanged;
2113 #endregion // Events