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 "{ " + type + "," + row + "," + column + "}";
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 private Color caption_backcolor;
134 private Font caption_font;
135 private Color caption_forecolor;
136 private string caption_text;
137 internal bool caption_visible;
138 internal bool columnheaders_visible;
139 private object datasource;
140 private object real_datasource;
141 private string datamember;
142 private int firstvisible_column;
143 private bool flatmode;
144 private Color gridline_color;
145 private DataGridLineStyle gridline_style;
146 private Color header_backcolor;
147 private Color header_forecolor;
148 private Font header_font;
149 private Color link_color;
150 private Color link_hovercolor;
151 private Color parentrowsback_color;
152 private Color parentrowsfore_color;
153 private bool parentrows_visible;
154 private int preferredcolumn_width;
155 private int preferredrow_height;
156 private bool _readonly;
157 internal bool rowheaders_visible;
158 private Color selection_backcolor;
159 private Color selection_forecolor;
160 private int rowheaders_width;
161 internal int visiblecolumn_count;
162 internal int visiblerow_count;
163 internal int first_visiblecolumn;
164 private GridTableStylesCollection styles_collection;
165 private DataGridParentRowsLabelStyle parentrowslabel_style;
166 internal DataGridCell current_cell;
167 private DataGridTableStyle default_style;
168 private DataGridTableStyle current_style;
169 internal HScrollBar horiz_scrollbar;
170 internal VScrollBar vert_scrollbar;
171 internal DataGridDrawing grid_drawing;
172 internal int first_visiblerow;
173 internal int horz_pixeloffset;
174 internal bool is_editing; // Current cell is edit mode
175 internal bool is_changing; // Indicates if current cell is been changed (in edit mode)
176 internal bool is_adding; // Indicates when we are adding a row
177 private Hashtable selected_rows;
178 private bool ctrl_pressed;
179 private bool shift_pressed;
180 private bool begininit;
181 private CurrencyManager cached_currencymgr;
182 private CurrencyManager cached_currencymgr_events;
183 private bool accept_listmgrevents;
184 #endregion // Local Variables
186 #region Public Constructors
189 grid_drawing = new DataGridDrawing (this);
190 allow_navigation = true;
191 allow_sorting = true;
193 backColor = ThemeEngine.Current.DataGridBackColor;
194 alternating_backcolor = def_alternating_backcolor;
195 background_color = def_background_color;
196 border_style = BorderStyle.Fixed3D;
197 caption_backcolor = def_caption_backcolor;
199 caption_forecolor = def_caption_forecolor;
200 caption_text = string.Empty;
201 caption_visible = true;
202 columnheaders_visible = true;
204 real_datasource = null;
205 datamember = string.Empty;
206 firstvisible_column = 0;
208 gridline_color = def_gridline_color;
209 gridline_style = DataGridLineStyle.Solid;
210 header_backcolor = def_header_backcolor;
211 header_forecolor = def_header_forecolor;
212 header_font = def_header_font;
213 link_color = def_link_color;
214 link_hovercolor = def_link_hovercolor;
215 parentrowsback_color = def_parentrowsback_color;
216 parentrowsfore_color = def_parentrowsfore_color;
217 parentrows_visible = true;
218 preferredcolumn_width = ThemeEngine.Current.DataGridPreferredColumnWidth;
220 rowheaders_visible = true;
221 selection_backcolor = def_selection_backcolor;
222 selection_forecolor = def_selection_forecolor;
223 rowheaders_width = 35;
224 visiblecolumn_count = 0;
225 visiblerow_count = 0;
226 current_cell = new DataGridCell ();
227 first_visiblerow = 0;
228 first_visiblecolumn = 0;
229 horz_pixeloffset = 0;
233 parentrowslabel_style = DataGridParentRowsLabelStyle.Both;
234 selected_rows = new Hashtable ();
235 ctrl_pressed = false;
236 shift_pressed = false;
237 preferredrow_height = def_preferredrow_height = FontHeight + 3;
238 cached_currencymgr_events = cached_currencymgr = null;
239 accept_listmgrevents = true;
241 default_style = new DataGridTableStyle (true);
242 styles_collection = new GridTableStylesCollection (this);
243 styles_collection.CollectionChanged += new CollectionChangeEventHandler (OnTableStylesCollectionChanged);
245 CurrentTableStyle = default_style;
247 horiz_scrollbar = new HScrollBar ();
248 horiz_scrollbar.Scroll += new ScrollEventHandler (GridHScrolled);
249 vert_scrollbar = new VScrollBar ();
250 vert_scrollbar.Scroll += new ScrollEventHandler (GridVScrolled);
251 KeyUp += new KeyEventHandler (OnKeyUpDG);
253 SetStyle (ControlStyles.UserMouse, true);
257 #endregion // Public Constructor
259 #region Public Instance Properties
262 public bool AllowNavigation {
264 return allow_navigation;
268 if (allow_navigation != value) {
269 allow_navigation = value;
270 OnAllowNavigationChanged (EventArgs.Empty);
276 public bool AllowSorting {
278 return allow_sorting;
282 if (allow_sorting != value) {
283 allow_sorting = value;
288 public Color AlternatingBackColor {
290 return alternating_backcolor;
294 if (alternating_backcolor != value) {
295 alternating_backcolor = value;
301 public Color BackColor {
310 public Color BackgroundColor {
312 return background_color;
315 if (background_color != value) {
316 background_color = value;
317 OnBackgroundColorChanged (EventArgs.Empty);
324 [EditorBrowsable(EditorBrowsableState.Never)]
325 public Image BackgroundImage {
327 return base.BackgroundImage;
331 base.BackgroundImage = value;
336 [DefaultValue(BorderStyle.Fixed3D)]
337 public BorderStyle BorderStyle {
338 get { return InternalBorderStyle; }
340 InternalBorderStyle = value;
341 CalcAreasAndInvalidate ();
342 OnBorderStyleChanged (EventArgs.Empty);
346 public Color CaptionBackColor {
348 return caption_backcolor;
352 if (caption_backcolor != value) {
353 caption_backcolor = value;
354 grid_drawing.InvalidateCaption ();
361 public Font CaptionFont {
363 if (caption_font == null) {
371 if (caption_font != null && caption_font.Equals (value)) {
375 caption_font = value;
376 CalcAreasAndInvalidate ();
380 public Color CaptionForeColor {
382 return caption_forecolor;
386 if (caption_forecolor != value) {
387 caption_forecolor = value;
388 grid_drawing.InvalidateCaption ();
395 public string CaptionText {
401 if (caption_text != value) {
402 caption_text = value;
403 grid_drawing.InvalidateCaption ();
409 public bool CaptionVisible {
411 return caption_visible;
415 if (caption_visible != value) {
416 caption_visible = value;
417 CalcAreasAndInvalidate ();
418 OnCaptionVisibleChanged (EventArgs.Empty);
424 public bool ColumnHeadersVisible {
426 return columnheaders_visible;
430 if (columnheaders_visible != value) {
431 columnheaders_visible = value;
432 CalcAreasAndInvalidate ();
438 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
439 public DataGridCell CurrentCell {
445 if (!current_cell.Equals (value)) {
448 int old_row = current_cell.RowNumber;
450 if (value.RowNumber >= RowsCount) {
451 value.RowNumber = RowsCount == 0 ? 0 : RowsCount - 1;
454 if (value.ColumnNumber >= CurrentTableStyle.GridColumnStyles.Count) {
455 value.ColumnNumber = CurrentTableStyle.GridColumnStyles.Count == 0 ? 0: CurrentTableStyle.GridColumnStyles.Count - 1;
458 EnsureCellVisilibility (value);
459 current_cell = value;
461 if (current_cell.RowNumber != old_row) {
462 grid_drawing.InvalidateRowHeader (old_row);
465 accept_listmgrevents = false;
467 if (cached_currencymgr_events != null) {
468 cached_currencymgr_events.Position = current_cell.RowNumber;
470 accept_listmgrevents = true;
471 InvalidateCurrentRowHeader ();
472 OnCurrentCellChanged (EventArgs.Empty);
478 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
479 public int CurrentRowIndex {
481 if (ListManager == null) {
485 return current_cell.RowNumber;
489 if (current_cell.RowNumber != value) {
490 CurrentCell = new DataGridCell (value, current_cell.ColumnNumber);
496 [EditorBrowsable(EditorBrowsableState.Never)]
497 public override Cursor Cursor {
507 [Editor ("System.Windows.Forms.Design.DataMemberListEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
508 public string DataMember {
509 get { return datamember; }
511 if (SetDataMember (value)) {
512 SetDataSource (datasource);
513 if (styles_collection.Contains (value) == true) {
514 CurrentTableStyle = styles_collection[value];
515 current_style.CreateColumnsForTable (true);
517 CurrentTableStyle = default_style;
518 current_style.GridColumnStyles.Clear ();
519 current_style.CreateColumnsForTable (false);
526 [RefreshProperties(RefreshProperties.Repaint)]
527 [TypeConverter("System.Windows.Forms.Design.DataSourceConverter, " + Consts.AssemblySystem_Design)]
528 public object DataSource {
534 if (SetDataSource (value)) {
540 protected override Size DefaultSize {
542 return new Size (130, 80);
547 public int FirstVisibleColumn {
549 return firstvisible_column;
553 [DefaultValue(false)]
554 public bool FlatMode {
560 if (flatmode != value) {
562 OnFlatModeChanged (EventArgs.Empty);
568 public Color ForeColor {
570 return base.ForeColor;
574 base.ForeColor = value;
578 public Color GridLineColor {
580 return gridline_color;
584 if (value == Color.Empty) {
585 throw new ArgumentException ("Color.Empty value is invalid.");
588 if (gridline_color != value) {
589 gridline_color = value;
595 [DefaultValue(DataGridLineStyle.Solid)]
596 public DataGridLineStyle GridLineStyle {
598 return gridline_style;
602 if (gridline_style != value) {
603 gridline_style = value;
609 public Color HeaderBackColor {
611 return header_backcolor;
615 if (value == Color.Empty) {
616 throw new ArgumentException ("Color.Empty value is invalid.");
619 if (header_backcolor != value) {
620 header_backcolor = value;
626 public Font HeaderFont {
632 if (header_font != null && !header_font.Equals (value)) {
634 CalcAreasAndInvalidate ();
639 public Color HeaderForeColor {
641 return header_forecolor;
645 if (header_forecolor != value) {
646 header_forecolor = value;
652 protected ScrollBar HorizScrollBar {
654 return horiz_scrollbar;
658 public object this [DataGridCell cell] {
660 return this [cell.RowNumber, cell.ColumnNumber];
664 this [cell.RowNumber, cell.ColumnNumber] = value;
668 public object this [int rowIndex, int columnIndex] {
670 return CurrentTableStyle.GridColumnStyles[columnIndex].GetColumnValueAtRow (ListManager,
675 CurrentTableStyle.GridColumnStyles[columnIndex].SetColumnValueAtRow (ListManager,
680 public Color LinkColor {
685 if (link_color != value) {
694 [EditorBrowsable(EditorBrowsableState.Never)]
695 public Color LinkHoverColor {
697 return link_hovercolor;
701 if (link_hovercolor != value) {
702 link_hovercolor = value;
709 [EditorBrowsable(EditorBrowsableState.Advanced)]
710 protected internal CurrencyManager ListManager {
712 if (BindingContext == null || DataSource == null) {
716 if (cached_currencymgr != null) {
717 return cached_currencymgr;
720 // If we bind real_datasource object we do not get the events from ListManger
721 // since the object is not the datasource and does not match
722 cached_currencymgr = (CurrencyManager) BindingContext [real_datasource, DataMember];
723 cached_currencymgr_events = (CurrencyManager) BindingContext [datasource, DataMember];
724 ConnectListManagerEvents ();
725 return cached_currencymgr;
729 throw new NotSupportedException ("Operation is not supported.");
733 public Color ParentRowsBackColor {
735 return parentrowsback_color;
739 if (parentrowsback_color != value) {
740 parentrowsback_color = value;
741 if (parentrows_visible) {
748 public Color ParentRowsForeColor {
750 return parentrowsfore_color;
754 if (parentrowsfore_color != value) {
755 parentrowsfore_color = value;
756 if (parentrows_visible) {
763 [DefaultValue(DataGridParentRowsLabelStyle.Both)]
764 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
765 public DataGridParentRowsLabelStyle ParentRowsLabelStyle {
767 return parentrowslabel_style;
771 if (parentrowslabel_style != value) {
772 parentrowslabel_style = value;
773 if (parentrows_visible) {
777 OnParentRowsLabelStyleChanged (EventArgs.Empty);
783 public bool ParentRowsVisible {
785 return parentrows_visible;
789 if (parentrows_visible != value) {
790 parentrows_visible = value;
791 CalcAreasAndInvalidate ();
792 OnParentRowsVisibleChanged (EventArgs.Empty);
797 // Settting this property seems to have no effect.
799 [TypeConverter(typeof(DataGridPreferredColumnWidthTypeConverter))]
800 public int PreferredColumnWidth {
802 return preferredcolumn_width;
807 throw new ArgumentException ("PreferredColumnWidth is less than 0");
810 if (preferredcolumn_width != value) {
811 preferredcolumn_width = value;
817 public int PreferredRowHeight {
819 return preferredrow_height;
823 if (preferredrow_height != value) {
824 preferredrow_height = value;
825 CalcAreasAndInvalidate ();
830 [DefaultValue(false)]
831 public bool ReadOnly {
837 if (_readonly != value) {
839 OnReadOnlyChanged (EventArgs.Empty);
840 CalcAreasAndInvalidate ();
846 public bool RowHeadersVisible {
848 return rowheaders_visible;
852 if (rowheaders_visible != value) {
853 rowheaders_visible = value;
854 CalcAreasAndInvalidate ();
860 public int RowHeaderWidth {
862 return rowheaders_width;
866 if (rowheaders_width != value) {
867 rowheaders_width = value;
868 CalcAreasAndInvalidate ();
873 public Color SelectionBackColor {
875 return selection_backcolor;
879 if (selection_backcolor != value) {
880 selection_backcolor = value;
886 public Color SelectionForeColor {
888 return selection_forecolor;
892 if (selection_forecolor != value) {
893 selection_forecolor = value;
899 public override ISite Site {
909 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
910 public GridTableStylesCollection TableStyles {
911 get { return styles_collection; }
916 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
917 [EditorBrowsable(EditorBrowsableState.Never)]
918 public override string Text {
928 [EditorBrowsable(EditorBrowsableState.Advanced)]
929 protected ScrollBar VertScrollBar {
931 return vert_scrollbar;
936 public int VisibleColumnCount {
938 return visiblecolumn_count;
942 // Calculated at DataGridDrawing.CalcRowsHeaders
944 public int VisibleRowCount {
946 return visiblerow_count;
950 #endregion // Public Instance Properties
952 #region Private Instance Properties
953 internal DataGridTableStyle CurrentTableStyle {
955 return current_style;
958 current_style = value;
959 current_style.DataGrid = this;
960 CalcAreasAndInvalidate ();
964 internal int FirstVisibleRow {
965 get { return first_visiblerow; }
966 set { first_visiblerow = value;}
969 internal int RowsCount {
971 if (ListManager != null) {
972 return ListManager.Count;
979 internal int RowHeight {
981 if (CurrentTableStyle.CurrentPreferredRowHeight > Font.Height + 3 + 1 /* line */) {
982 return CurrentTableStyle.CurrentPreferredRowHeight;
985 return Font.Height + 3 + 1 /* line */;
990 internal bool ShowEditRow {
992 if (ListManager != null && ListManager.CanAddRows == false) {
996 return _readonly == false;
1000 // It should only be shown if there are relations that
1001 // we do not support right now
1002 internal bool ShowParentRowsVisible {
1004 //See parentrows_visible;
1009 #endregion Private Instance Properties
1011 #region Public Instance Methods
1014 public virtual bool BeginEdit (DataGridColumnStyle gridColumn, int rowNumber)
1019 public virtual void BeginInit ()
1024 protected virtual void CancelEditing ()
1026 if (current_cell.ColumnNumber < CurrentTableStyle.GridColumnStyles.Count) {
1027 CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].Abort (current_cell.RowNumber);
1030 if (is_adding == true) {
1031 ListManager.RemoveAt (RowsCount - 1);
1036 is_changing = false;
1037 InvalidateCurrentRowHeader ();
1041 public void Collapse (int row)
1046 protected internal virtual void ColumnStartedEditing (Control editingControl)
1051 protected internal virtual void ColumnStartedEditing (Rectangle bounds)
1056 protected override AccessibleObject CreateAccessibilityInstance ()
1058 return base.CreateAccessibilityInstance ();
1061 protected virtual DataGridColumnStyle CreateGridColumn (PropertyDescriptor prop)
1063 return CreateGridColumn (prop, false);
1066 protected virtual DataGridColumnStyle CreateGridColumn (PropertyDescriptor prop, bool isDefault)
1068 throw new NotImplementedException();
1071 protected override void Dispose (bool disposing)
1073 base.Dispose (disposing);
1076 public virtual bool EndEdit (DataGridColumnStyle gridColumn, int rowNumber, bool shouldAbort)
1078 if (is_adding == true) {
1080 ListManager.CancelCurrentEdit ();
1082 ListManager.EndCurrentEdit ();
1083 CalcAreasAndInvalidate ();
1088 if (shouldAbort || gridColumn.ParentReadOnly ==true) {
1089 gridColumn.Abort (rowNumber);
1091 gridColumn.Commit (ListManager, rowNumber);
1095 is_changing = false;
1096 InvalidateCurrentRowHeader ();
1100 public virtual void EndInit ()
1105 public void Expand (int row)
1110 public Rectangle GetCellBounds (DataGridCell cell)
1112 return GetCellBounds (cell.RowNumber, cell.ColumnNumber);
1115 public Rectangle GetCellBounds (int row, int col)
1117 return grid_drawing.GetCellBounds (row, col);
1120 public Rectangle GetCurrentCellBounds ()
1122 return GetCellBounds (current_cell.RowNumber, current_cell.ColumnNumber);
1125 protected virtual string GetOutputTextDelimiter ()
1127 return string.Empty;
1130 protected virtual void GridHScrolled (object sender, ScrollEventArgs se)
1132 if (se.NewValue == horz_pixeloffset ||
1133 se.Type == ScrollEventType.EndScroll) {
1137 ScrollToColumnInPixels (se.NewValue);
1140 protected virtual void GridVScrolled (object sender, ScrollEventArgs se)
1142 int old_first_visiblerow = first_visiblerow;
1143 first_visiblerow = se.NewValue;
1144 grid_drawing.UpdateVisibleRowCount ();
1146 if (first_visiblerow == old_first_visiblerow) {
1149 ScrollToRow (old_first_visiblerow, first_visiblerow);
1152 public HitTestInfo HitTest (Point position)
1154 return HitTest (position.X, position.Y);
1157 public HitTestInfo HitTest (int x, int y)
1159 return grid_drawing.HitTest (x, y);
1163 public bool IsExpanded (int rowNumber)
1168 public bool IsSelected (int row)
1170 return selected_rows[row] != null;
1174 public void NavigateBack ()
1180 public void NavigateTo (int rowNumber, string relationName)
1185 protected virtual void OnAllowNavigationChanged (EventArgs e)
1187 if (AllowNavigationChanged != null) {
1188 AllowNavigationChanged (this, e);
1192 protected void OnBackButtonClicked (object sender, EventArgs e)
1194 if (BackButtonClick != null) {
1195 BackButtonClick (sender, e);
1199 protected override void OnBackColorChanged (EventArgs e)
1201 base.OnBackColorChanged (e);
1204 protected virtual void OnBackgroundColorChanged (EventArgs e)
1206 if (BackgroundColorChanged != null) {
1207 BackgroundColorChanged (this, e);
1211 protected override void OnBindingContextChanged( EventArgs e)
1213 base.OnBindingContextChanged (e);
1216 protected virtual void OnBorderStyleChanged (EventArgs e)
1218 if (BorderStyleChanged != null) {
1219 BorderStyleChanged (this, e);
1223 protected virtual void OnCaptionVisibleChanged (EventArgs e)
1225 if (CaptionVisibleChanged != null) {
1226 CaptionVisibleChanged (this, e);
1230 protected virtual void OnCurrentCellChanged (EventArgs e)
1232 if (CurrentCellChanged != null) {
1233 CurrentCellChanged (this, e);
1237 protected virtual void OnDataSourceChanged (EventArgs e)
1239 if (DataSourceChanged != null) {
1240 DataSourceChanged (this, e);
1244 protected override void OnEnter (EventArgs e)
1249 protected virtual void OnFlatModeChanged (EventArgs e)
1251 if (FlatModeChanged != null) {
1252 FlatModeChanged (this, e);
1256 protected override void OnFontChanged (EventArgs e)
1258 grid_drawing.CalcGridAreas ();
1259 base.OnFontChanged (e);
1262 protected override void OnForeColorChanged (EventArgs e)
1264 base.OnForeColorChanged (e);
1267 protected override void OnHandleCreated (EventArgs e)
1269 base.OnHandleCreated (e);
1270 grid_drawing.CalcGridAreas ();
1273 protected override void OnHandleDestroyed (EventArgs e)
1275 base.OnHandleDestroyed (e);
1278 protected override void OnKeyDown (KeyEventArgs ke)
1280 base.OnKeyDown (ke);
1282 if (ProcessGridKey (ke) == true) {
1286 CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].OnKeyDown
1287 (ke, current_cell.RowNumber, current_cell.ColumnNumber);
1290 protected override void OnKeyPress (KeyPressEventArgs kpe)
1292 base.OnKeyPress (kpe);
1295 protected override void OnLayout (LayoutEventArgs levent)
1297 base.OnLayout (levent);
1300 protected override void OnLeave (EventArgs e)
1305 protected override void OnMouseDown (MouseEventArgs e)
1307 base.OnMouseDown (e);
1309 HitTestInfo testinfo;
1310 testinfo = grid_drawing.HitTest (e.X, e.Y);
1312 switch (testinfo.type) {
1313 case HitTestType.Cell:
1315 DataGridCell new_cell = new DataGridCell (testinfo.Row, testinfo.Column);
1317 if (new_cell.Equals (current_cell) == false) {
1319 CurrentCell = new_cell;
1320 EditCell (current_cell);
1323 CurrentTableStyle.GridColumnStyles[testinfo.Column].OnMouseDown (e, testinfo.Row, testinfo.Column);
1328 case HitTestType.RowHeader:
1330 if (ctrl_pressed == false && shift_pressed == false) {
1331 ResetSelection (); // Invalidates selected rows
1334 if (shift_pressed == true) {
1335 ShiftSelection (testinfo.Row);
1336 } else { // ctrl_pressed or single item
1337 Select (testinfo.Row);
1341 CurrentCell = new DataGridCell (testinfo.Row, current_cell.ColumnNumber);
1342 OnRowHeaderClick (EventArgs.Empty);
1346 case HitTestType.ColumnHeader:
1348 if (allow_sorting == false)
1351 if (ListManager.List is IBindingList == false)
1354 ListSortDirection direction = ListSortDirection.Ascending;
1355 PropertyDescriptor prop = CurrentTableStyle.GridColumnStyles[testinfo.Column].PropertyDescriptor;
1356 IBindingList list = (IBindingList) ListManager.List;
1358 if (list.SortProperty != null) {
1359 CurrentTableStyle.GridColumnStyles[list.SortProperty].ArrowDrawingMode
1360 = DataGridColumnStyle.ArrowDrawing.No;
1363 if (prop == list.SortProperty && list.SortDirection == ListSortDirection.Ascending) {
1364 direction = ListSortDirection.Descending;
1367 CurrentTableStyle.GridColumnStyles[testinfo.Column].ArrowDrawingMode =
1368 direction == ListSortDirection.Ascending ?
1369 DataGridColumnStyle.ArrowDrawing.Ascending : DataGridColumnStyle.ArrowDrawing.Descending;
1371 list.ApplySort (prop, direction);
1381 protected override void OnMouseLeave (EventArgs e)
1383 base.OnMouseLeave (e);
1386 protected override void OnMouseMove (MouseEventArgs e)
1388 base.OnMouseMove (e);
1391 protected override void OnMouseUp (MouseEventArgs e)
1396 protected override void OnMouseWheel (MouseEventArgs e)
1398 base.OnMouseWheel (e);
1400 if (ctrl_pressed == false) { // scroll horizontal
1402 if (current_cell.RowNumber > 0) {
1403 CurrentCell = new DataGridCell (current_cell.RowNumber - 1, current_cell.ColumnNumber);
1407 if (current_cell.RowNumber < RowsCount - 1) {
1408 CurrentCell = new DataGridCell (current_cell.RowNumber + 1, current_cell.ColumnNumber);
1413 if (current_cell.ColumnNumber > 0) {
1414 CurrentCell = new DataGridCell (current_cell.RowNumber, current_cell.ColumnNumber - 1);
1418 if (current_cell.ColumnNumber < CurrentTableStyle.GridColumnStyles.Count - 1) {
1419 CurrentCell = new DataGridCell (current_cell.RowNumber, current_cell.ColumnNumber + 1);
1425 protected void OnNavigate (NavigateEventArgs e)
1427 if (Navigate != null) {
1432 protected override void OnPaint (PaintEventArgs pe)
1434 ThemeEngine.Current.DataGridPaint (pe, this);
1437 protected override void OnPaintBackground (PaintEventArgs ebe)
1441 protected virtual void OnParentRowsLabelStyleChanged (EventArgs e)
1443 if (ParentRowsLabelStyleChanged != null) {
1444 ParentRowsLabelStyleChanged (this, e);
1448 protected virtual void OnParentRowsVisibleChanged (EventArgs e)
1450 if (ParentRowsVisibleChanged != null) {
1451 ParentRowsVisibleChanged (this, e);
1455 protected virtual void OnReadOnlyChanged (EventArgs e)
1457 if (ReadOnlyChanged != null) {
1458 ReadOnlyChanged (this, e);
1462 protected override void OnResize (EventArgs e)
1467 protected void OnRowHeaderClick (EventArgs e)
1469 if (RowHeaderClick != null) {
1470 RowHeaderClick (this, e);
1474 protected void OnScroll (EventArgs e)
1476 if (Scroll != null) {
1481 protected void OnShowParentDetailsButtonClicked (object sender, EventArgs e)
1483 if (ShowParentDetailsButtonClick != null) {
1484 ShowParentDetailsButtonClick (sender, e);
1488 protected override bool ProcessDialogKey (Keys keyData)
1490 return base.ProcessDialogKey (keyData);
1493 protected bool ProcessGridKey (KeyEventArgs ke)
1495 if (RowsCount == 0) {
1499 switch (ke.KeyCode) {
1500 case Keys.ControlKey:
1501 ctrl_pressed = true;
1504 shift_pressed = true;
1508 if (current_cell.RowNumber > 0) {
1509 CurrentCell = new DataGridCell (current_cell.RowNumber - 1, current_cell.ColumnNumber);
1510 EditCell (current_cell);
1516 if (current_cell.RowNumber < RowsCount - 1) {
1517 CurrentCell = new DataGridCell (current_cell.RowNumber + 1, current_cell.ColumnNumber);
1518 EditCell (current_cell);
1525 if (current_cell.ColumnNumber + 1 < CurrentTableStyle.GridColumnStyles.Count) {
1526 CurrentCell = new DataGridCell (current_cell.RowNumber, current_cell.ColumnNumber + 1);
1527 EditCell (current_cell);
1533 if (current_cell.ColumnNumber > 0) {
1534 CurrentCell = new DataGridCell (current_cell.RowNumber, current_cell.ColumnNumber - 1);
1535 EditCell (current_cell);
1541 if (current_cell.RowNumber > grid_drawing.VLargeChange) {
1542 CurrentCell = new DataGridCell (current_cell.RowNumber - grid_drawing.VLargeChange, current_cell.ColumnNumber);
1544 CurrentCell = new DataGridCell (0, current_cell.ColumnNumber);
1547 EditCell (current_cell);
1552 if (current_cell.RowNumber + grid_drawing.VLargeChange < RowsCount) {
1553 CurrentCell = new DataGridCell (current_cell.RowNumber + grid_drawing.VLargeChange, current_cell.ColumnNumber);
1555 CurrentCell = new DataGridCell (RowsCount - 1, current_cell.ColumnNumber);
1558 EditCell (current_cell);
1563 CurrentCell = new DataGridCell (0, current_cell.ColumnNumber);
1564 EditCell (current_cell);
1569 CurrentCell = new DataGridCell (RowsCount - 1, current_cell.ColumnNumber);
1570 EditCell (current_cell);
1575 foreach (int row in selected_rows.Keys) {
1576 ListManager.RemoveAt (row);
1578 selected_rows.Clear ();
1579 CalcAreasAndInvalidate ();
1583 return false; // message not processed
1586 return true; // message processed
1589 // Called from DataGridTextBox
1590 protected override bool ProcessKeyPreview (ref Message m)
1592 Keys key = (Keys) m.WParam.ToInt32 ();
1593 KeyEventArgs ke = new KeyEventArgs (key);
1594 if (ProcessGridKey (ke) == true) {
1598 return base.ProcessKeyPreview (ref m);
1601 protected bool ProcessTabKey (Keys keyData)
1606 public void ResetAlternatingBackColor ()
1608 alternating_backcolor = def_alternating_backcolor;
1611 public override void ResetBackColor ()
1613 backColor = ThemeEngine.Current.DataGridBackColor;
1616 public override void ResetForeColor ()
1618 base.ResetForeColor ();
1621 public void ResetGridLineColor ()
1623 gridline_color = def_gridline_color;
1626 public void ResetHeaderBackColor ()
1628 header_backcolor = def_header_backcolor;
1631 public void ResetHeaderFont ()
1633 header_font = def_header_font;
1636 public void ResetHeaderForeColor ()
1638 header_forecolor = def_header_forecolor;
1641 public void ResetLinkColor ()
1643 link_color = def_link_color;
1646 public void ResetLinkHoverColor ()
1648 link_hovercolor = def_link_hovercolor;
1651 protected void ResetSelection ()
1653 foreach (int row in selected_rows.Keys) {
1654 grid_drawing.InvalidateRow (row);
1655 grid_drawing.InvalidateRowHeader (row);
1658 selected_rows.Clear ();
1661 public void ResetSelectionBackColor ()
1663 selection_backcolor = def_selection_backcolor;
1666 public void ResetSelectionForeColor ()
1668 selection_forecolor = def_selection_forecolor;
1671 public void Select (int row)
1673 if (selected_rows[row] == null) {
1674 selected_rows.Add (row, true);
1676 selected_rows[row] = true;
1679 grid_drawing.InvalidateRow (row);
1682 public void SetDataBinding (object dataSource, string dataMember)
1684 bool source = SetDataSource (dataSource);
1685 bool member = SetDataMember (dataMember);
1687 if (source == false && member == false) {
1691 SetNewDataSource ();
1694 protected virtual bool ShouldSerializeAlternatingBackColor ()
1696 return (alternating_backcolor != def_alternating_backcolor);
1699 protected virtual bool ShouldSerializeBackgroundColor ()
1701 return (background_color != def_background_color);
1704 protected virtual bool ShouldSerializeCaptionBackColor ()
1706 return (caption_backcolor != def_caption_backcolor);
1709 protected virtual bool ShouldSerializeCaptionForeColor ()
1711 return (caption_forecolor != def_caption_forecolor);
1714 protected virtual bool ShouldSerializeGridLineColor ()
1716 return (gridline_color != def_gridline_color);
1719 protected virtual bool ShouldSerializeHeaderBackColor ()
1721 return (header_backcolor != def_header_backcolor);
1724 protected bool ShouldSerializeHeaderFont ()
1726 return (header_font != def_header_font);
1729 protected virtual bool ShouldSerializeHeaderForeColor ()
1731 return (header_forecolor != def_header_forecolor);
1734 protected virtual bool ShouldSerializeLinkHoverColor ()
1736 return (link_hovercolor != def_link_hovercolor);
1739 protected virtual bool ShouldSerializeParentRowsBackColor ()
1741 return (parentrowsback_color != def_parentrowsback_color);
1744 protected virtual bool ShouldSerializeParentRowsForeColor ()
1746 return (parentrowsback_color != def_parentrowsback_color);
1749 protected bool ShouldSerializePreferredRowHeight ()
1751 return (preferredrow_height != def_preferredrow_height);
1754 protected bool ShouldSerializeSelectionBackColor ()
1756 return (selection_backcolor != def_selection_backcolor);
1759 protected virtual bool ShouldSerializeSelectionForeColor ()
1761 return (selection_forecolor != def_selection_forecolor);
1764 public void SubObjectsSiteChange (bool site)
1769 public void UnSelect (int row)
1771 selected_rows.Remove (row);
1772 grid_drawing.InvalidateRow (row);
1775 #endregion // Public Instance Methods
1777 #region Private Instance Methods
1779 internal void CalcAreasAndInvalidate ()
1781 grid_drawing.CalcGridAreas ();
1785 private void ConnectListManagerEvents ()
1787 cached_currencymgr_events.CurrentChanged += new EventHandler (OnListManagerCurrentChanged);
1790 private void DisconnectListManagerEvents ()
1795 // EndEdit current editing operation
1796 internal virtual bool EndEdit (bool shouldAbort)
1798 return EndEdit (CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber],
1799 current_cell.RowNumber, shouldAbort);
1802 private void EnsureCellVisilibility (DataGridCell cell)
1804 if (cell.ColumnNumber <= first_visiblecolumn ||
1805 cell.ColumnNumber + 1 >= first_visiblecolumn + visiblecolumn_count) {
1807 first_visiblecolumn = grid_drawing.GetFirstColumnForColumnVisilibility (first_visiblecolumn, cell.ColumnNumber);
1809 int pixel = grid_drawing.GetColumnStartingPixel (first_visiblecolumn);
1810 ScrollToColumnInPixels (pixel);
1813 if (cell.RowNumber < first_visiblerow ||
1814 cell.RowNumber + 1 >= first_visiblerow + visiblerow_count) {
1816 if (cell.RowNumber + 1 >= first_visiblerow + visiblerow_count) {
1817 int old_first_visiblerow = first_visiblerow;
1818 first_visiblerow = 1 + cell.RowNumber - visiblerow_count;
1819 grid_drawing.UpdateVisibleRowCount ();
1820 ScrollToRow (old_first_visiblerow, first_visiblerow);
1822 int old_first_visiblerow = first_visiblerow;
1823 first_visiblerow = cell.RowNumber;
1824 grid_drawing.UpdateVisibleRowCount ();
1825 ScrollToRow (old_first_visiblerow, first_visiblerow);
1828 vert_scrollbar.Value = first_visiblerow;
1832 internal IEnumerable GetDataSource (object source, string member)
1834 IListSource src = (IListSource) source;
1835 IList list = src.GetList();
1836 IListSource listsource;
1837 ITypedList typedlist;
1839 if (source is IEnumerable) {
1840 return (IEnumerable) source;
1843 if(src.ContainsListCollection == false) {
1847 listsource = (IListSource) source;
1849 if (listsource == null) {
1853 list = src.GetList ();
1859 typedlist = (ITypedList) list;
1861 if (typedlist == null) {
1865 PropertyDescriptorCollection col = typedlist.GetItemProperties (new PropertyDescriptor [0]);
1866 PropertyDescriptor prop = col.Find (member, true);
1869 if (col.Count > 0) {
1878 IEnumerable result = (IEnumerable)(prop.GetValue (list[0]));
1883 internal void InvalidateCurrentRowHeader ()
1885 grid_drawing.InvalidateRowHeader (current_cell.RowNumber);
1888 private bool SetDataMember (string member)
1890 if (member == datamember) {
1894 datamember = member;
1895 real_datasource = GetDataSource (datasource, member);
1896 DisconnectListManagerEvents ();
1897 cached_currencymgr = cached_currencymgr_events = null;
1901 private bool SetDataSource (object source)
1904 if (source != null && source as IListSource != null && source as IList != null) {
1905 throw new Exception ("Wrong complex data binding source");
1908 current_cell = new DataGridCell ();
1909 datasource = source;
1910 DisconnectListManagerEvents ();
1911 cached_currencymgr = cached_currencymgr_events = null;
1913 real_datasource = GetDataSource (datasource, DataMember);
1914 }catch (Exception e) {
1915 real_datasource = source;
1918 OnDataSourceChanged (EventArgs.Empty);
1922 private void SetNewDataSource ()
1924 current_style.GridColumnStyles.Clear ();
1925 current_style.CreateColumnsForTable (false);
1926 CalcAreasAndInvalidate ();
1929 private void OnKeyUpDG (object sender, KeyEventArgs e)
1931 switch (e.KeyCode) {
1932 case Keys.ControlKey:
1933 ctrl_pressed = false;
1936 shift_pressed = false;
1943 private void OnListManagerCurrentChanged (object sender, EventArgs e)
1945 if (accept_listmgrevents == false) {
1949 CurrentCell = new DataGridCell (cached_currencymgr_events.Position, current_cell.RowNumber);
1952 private void OnTableStylesCollectionChanged (object sender, CollectionChangeEventArgs e)
1954 if (ListManager != null && String.Compare (ListManager.ListName, ((DataGridTableStyle)e.Element).MappingName, true) == 0) {
1955 CurrentTableStyle = (DataGridTableStyle)e.Element;
1956 ((DataGridTableStyle) e.Element).CreateColumnsForTable (false);
1959 CalcAreasAndInvalidate ();
1962 private void EditCell (DataGridCell cell)
1964 ResetSelection (); // Invalidates selected rows
1966 is_changing = false;
1968 if (ShowEditRow && is_adding == false && cell.RowNumber >= RowsCount) {
1969 ListManager.AddNew ();
1971 Invalidate (); // We have just added a new row
1974 CurrentTableStyle.GridColumnStyles[cell.ColumnNumber].Edit (ListManager,
1975 cell.RowNumber, GetCellBounds (cell.RowNumber, cell.ColumnNumber),
1976 _readonly, string.Empty, true);
1979 private void ShiftSelection (int index)
1981 int shorter_item = -1, dist = RowsCount + 1, cur_dist;
1983 foreach (int row in selected_rows.Keys) {
1986 cur_dist = row - index;
1989 cur_dist = index - row;
1992 if (cur_dist < dist) {
1998 if (shorter_item != -1) {
2001 if (shorter_item > index) {
2005 start = shorter_item;
2010 for (int idx = start; idx <= end; idx++) {
2016 private void ScrollToColumnInPixels (int pixel)
2018 Rectangle invalidate = new Rectangle ();
2019 Rectangle invalidate_column = new Rectangle ();
2021 if (pixel > horz_pixeloffset) { // ScrollRight
2022 int pixels = pixel - horz_pixeloffset;
2024 horz_pixeloffset = horiz_scrollbar.Value = pixel;
2025 grid_drawing.UpdateVisibleColumn ();
2028 invalidate_column.X = grid_drawing.ColumnsHeadersArea.X + grid_drawing.ColumnsHeadersArea.Width - pixels;
2029 invalidate_column.Y = grid_drawing.ColumnsHeadersArea.Y;
2030 invalidate_column.Width = pixels;
2031 invalidate_column.Height = grid_drawing.ColumnsHeadersArea.Height;
2032 XplatUI.ScrollWindow (Handle, grid_drawing.ColumnsHeadersArea, -pixels, 0, false);
2035 invalidate.X = grid_drawing.CellsArea.X + grid_drawing.CellsArea.Width - pixels;
2036 invalidate.Y = grid_drawing.CellsArea.Y;
2037 invalidate.Width = pixels;
2038 invalidate.Height = grid_drawing.CellsArea.Height;
2041 if (columnheaders_visible == true) {
2042 invalidate.Y -= grid_drawing.ColumnsHeadersArea.Height;
2043 invalidate.Height += grid_drawing.ColumnsHeadersArea.Height;
2046 XplatUI.ScrollWindow (Handle, grid_drawing.CellsArea, -pixels, 0, false);
2047 Invalidate (invalidate_column);
2048 Invalidate (invalidate);
2052 int pixels = horz_pixeloffset - pixel;
2053 Rectangle area = grid_drawing.CellsArea;
2055 horz_pixeloffset = horiz_scrollbar.Value = pixel;
2056 grid_drawing.UpdateVisibleColumn ();
2059 invalidate_column.X = grid_drawing.ColumnsHeadersArea.X;
2060 invalidate_column.Y = grid_drawing.ColumnsHeadersArea.Y;
2061 invalidate_column.Width = pixels;
2062 invalidate_column.Height = grid_drawing.ColumnsHeadersArea.Height;
2063 //XplatUI.ScrollWindow (Handle, grid_drawing.ColumnsHeadersArea, pixels, 0, false);
2066 invalidate.X = grid_drawing.CellsArea.X;
2067 invalidate.Y = grid_drawing.CellsArea.Y;
2068 invalidate.Width = pixels;
2069 invalidate.Height = grid_drawing.CellsArea.Height;
2071 if (columnheaders_visible == true) {
2072 invalidate.Y -= grid_drawing.ColumnsHeadersArea.Height;
2073 invalidate.Height += grid_drawing.ColumnsHeadersArea.Height;
2074 area.Y -= grid_drawing.ColumnsHeadersArea.Height;
2075 area.Height += grid_drawing.ColumnsHeadersArea.Height;
2078 XplatUI.ScrollWindow (Handle, area, pixels, 0, false);
2079 Invalidate (invalidate);
2084 private void ScrollToRow (int old_row, int new_row)
2086 Rectangle invalidate = new Rectangle ();
2088 if (new_row > old_row) { // Scrolldown
2089 int scrolled_rows = new_row - old_row;
2090 int pixels = scrolled_rows * RowHeight;
2091 Rectangle rows_area = grid_drawing.CellsArea; // Cells area - partial rows space
2092 rows_area.Height = grid_drawing.CellsArea.Height - grid_drawing.CellsArea.Height % RowHeight;
2094 invalidate.X = grid_drawing.CellsArea.X;
2095 invalidate.Y = grid_drawing.CellsArea.Y + rows_area.Height - pixels;
2096 invalidate.Width = grid_drawing.CellsArea.Width;
2097 invalidate.Height = pixels;
2099 XplatUI.ScrollWindow (Handle, rows_area, 0, -pixels, false);
2101 } else { // ScrollUp
2102 int scrolled_rows = old_row - new_row;
2103 int pixels = scrolled_rows * RowHeight;
2105 invalidate.X = grid_drawing.CellsArea.X;
2106 invalidate.Y = grid_drawing.CellsArea.Y;
2107 invalidate.Width = grid_drawing.CellsArea.Width;
2108 invalidate.Height = pixels;
2109 XplatUI.ScrollWindow (Handle, grid_drawing.CellsArea, 0, pixels, false);
2112 // Right now we use ScrollWindow Invalidate, let's leave remarked it here for X11 if need it
2113 //Invalidate (invalidate);
2114 Invalidate (grid_drawing.RowsHeadersArea);
2117 #endregion Private Instance Methods
2121 public event EventHandler AllowNavigationChanged;
2122 public event EventHandler BackButtonClick;
2123 public event EventHandler BackgroundColorChanged;
2126 [EditorBrowsable(EditorBrowsableState.Never)]
2127 public new event EventHandler BackgroundImageChanged;
2129 public event EventHandler BorderStyleChanged;
2130 public event EventHandler CaptionVisibleChanged;
2131 public event EventHandler CurrentCellChanged;
2134 [EditorBrowsable(EditorBrowsableState.Never)]
2135 public new event EventHandler CursorChanged;
2137 public event EventHandler DataSourceChanged;
2138 public event EventHandler FlatModeChanged;
2139 public event NavigateEventHandler Navigate;
2140 public event EventHandler ParentRowsLabelStyleChanged;
2141 public event EventHandler ParentRowsVisibleChanged;
2142 public event EventHandler ReadOnlyChanged;
2143 protected event EventHandler RowHeaderClick;
2144 public event EventHandler Scroll;
2145 public event EventHandler ShowParentDetailsButtonClick;
2148 [EditorBrowsable(EditorBrowsableState.Never)]
2149 public new event EventHandler TextChanged;
2150 #endregion // Events