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,2006 Novell, Inc. (http://www.novell.com)
23 // Jordi Mas i Hernandez <jordi@ximian.com>
24 // Chris Toshok <toshok@ximian.com>
32 using System
.ComponentModel
;
35 using System
.Runtime
.InteropServices
;
36 using System
.Collections
;
39 namespace System
.Windows
.Forms
41 internal class DataGridRelationshipRow
{
44 public DataGridRelationshipRow (DataGrid owner
)
52 relation_area
= Rectangle
.Empty
;
57 /* this needs to be a property so that the Autosize
58 * example from the Windows.Forms FAQ will work */
60 get { return height; }
62 if (height
!= value) {
64 owner
.UpdateRowsFrom (this);
69 public bool IsSelected
;
70 public bool IsExpanded
;
71 public int VerticalOffset
;
72 public int RelationHeight
;
73 public Rectangle relation_area
; /* the Y coordinate of this rectangle is updated as needed */
76 internal class DataGridDataSource
78 public DataGrid owner
;
79 public CurrencyManager list_manager
;
81 public string data_member
;
82 public object data_source
;
83 public DataGridCell current
;
85 public DataGridDataSource (DataGrid owner
, CurrencyManager list_manager
, object data_source
, string data_member
, object view_data
, DataGridCell current
)
88 this.list_manager
= list_manager
;
89 this.view
= view_data
;
90 this.data_source
= data_source
;
91 this.data_member
= data_member
;
92 this.current
= current
;
95 DataGridRelationshipRow
[] rows
;
96 public DataGridRelationshipRow
[] Rows
{
101 Hashtable selected_rows
;
102 public Hashtable SelectedRows
{
103 get { return selected_rows; }
104 set { selected_rows = value; }
108 public int SelectionStart
{
109 get { return selection_start; }
110 set { selection_start = value; }
114 [DefaultEvent("Navigate")]
115 [DefaultProperty("DataSource")]
116 [Designer("System.Windows.Forms.Design.DataGridDesigner, " + Consts
.AssemblySystem_Design
, "System.ComponentModel.Design.IDesigner")]
117 public class DataGrid
: Control
, ISupportInitialize
, IDataGridEditingService
121 public enum HitTestType
133 public sealed class HitTestInfo
135 public static readonly HitTestInfo Nowhere
= null;
139 DataGrid
.HitTestType type
;
141 #region Private Constructors
142 internal HitTestInfo () : this (-1, -1, HitTestType
.None
)
146 internal HitTestInfo (int row
, int column
, DataGrid
.HitTestType type
)
149 this.column
= column
;
155 #region Public Instance Properties
157 get { return column; }
163 public DataGrid
.HitTestType Type
{
166 #endregion //Public Instance Properties
168 public override bool Equals (object o
)
170 if (!(o
is HitTestInfo
))
173 HitTestInfo obj
= (HitTestInfo
) o
;
174 return (obj
.Column
== column
&& obj
.Row
== row
&& obj
.Type
==type
);
177 public override int GetHashCode ()
182 public override string ToString ()
184 return "{ " + type + "," + row + "," + column + "}";
189 #region Local Variables
190 /* cached theme defaults */
191 static readonly Color def_background_color
= ThemeEngine
.Current
.DataGridBackgroundColor
;
192 static readonly Color def_caption_backcolor
= ThemeEngine
.Current
.DataGridCaptionBackColor
;
193 static readonly Color def_caption_forecolor
= ThemeEngine
.Current
.DataGridCaptionForeColor
;
194 static readonly Color def_parentrowsback_color
= ThemeEngine
.Current
.DataGridParentRowsBackColor
;
195 static readonly Color def_parentrowsfore_color
= ThemeEngine
.Current
.DataGridParentRowsForeColor
;
198 // XXX this needs addressing. Control.background_color should not be internal.
199 new Color background_color
;
200 Color caption_backcolor
;
201 Color caption_forecolor
;
202 Color parentrowsback_color
;
203 Color parentrowsfore_color
;
205 /* flags to determine which areas of the datagrid are shown */
206 bool caption_visible
;
207 bool parentrows_visible
;
209 GridTableStylesCollection styles_collection
;
210 DataGridParentRowsLabelStyle parentrowslabel_style
;
211 DataGridTableStyle default_style
;
212 DataGridTableStyle grid_style
;
213 DataGridTableStyle current_style
;
216 DataGridCell current_cell
;
217 Hashtable selected_rows
;
218 int selection_start
; // used for range selection
220 /* layout/rendering */
221 bool allow_navigation
;
222 int first_visiblerow
;
223 int first_visiblecolumn
;
224 int visiblerow_count
;
225 int visiblecolumn_count
;
229 HScrollBar horiz_scrollbar
;
230 VScrollBar vert_scrollbar
;
231 int horiz_pixeloffset
;
233 internal Bitmap back_button_image
;
234 internal Rectangle back_button_rect
;
235 internal bool back_button_mouseover
;
236 internal bool back_button_active
;
237 internal Bitmap parent_rows_button_image
;
238 internal Rectangle parent_rows_button_rect
;
239 internal bool parent_rows_button_mouseover
;
240 internal bool parent_rows_button_active
;
245 CurrencyManager list_manager
;
246 bool refetch_list_manager
= true;
248 DataGridRelationshipRow
[] rows
;
250 /* column resize fields */
251 bool column_resize_active
;
253 int resize_column_width_delta
;
256 /* row resize fields */
257 bool row_resize_active
;
259 int resize_row_height_delta
;
262 /* used to make sure we don't endlessly recurse calling set_CurrentCell and OnListManagerPositionChanged */
263 bool from_positionchanged_handler
;
266 bool cursor_in_add_row
;
267 bool add_row_changed
;
268 bool is_editing
; // Current cell is edit mode
271 internal Stack dataSourceStack
;
273 #endregion // Local Variables
275 #region Public Constructors
278 allow_navigation
= true;
279 background_color
= def_background_color
;
280 border_style
= BorderStyle
.Fixed3D
;
281 caption_backcolor
= def_caption_backcolor
;
282 caption_forecolor
= def_caption_forecolor
;
283 caption_text
= string.Empty
;
284 caption_visible
= true;
285 datamember
= string.Empty
;
286 parentrowsback_color
= def_parentrowsback_color
;
287 parentrowsfore_color
= def_parentrowsfore_color
;
288 parentrows_visible
= true;
289 current_cell
= new DataGridCell ();
290 parentrowslabel_style
= DataGridParentRowsLabelStyle
.Both
;
291 selected_rows
= new Hashtable ();
292 selection_start
= -1;
293 rows
= new DataGridRelationshipRow
[0];
295 default_style
= new DataGridTableStyle (true);
296 grid_style
= new DataGridTableStyle ();
298 styles_collection
= new GridTableStylesCollection (this);
299 styles_collection
.CollectionChanged
+= new CollectionChangeEventHandler (OnTableStylesCollectionChanged
);
301 CurrentTableStyle
= grid_style
;
303 horiz_scrollbar
= new ImplicitHScrollBar ();
304 horiz_scrollbar
.Scroll
+= new ScrollEventHandler (GridHScrolled
);
305 vert_scrollbar
= new ImplicitVScrollBar ();
306 vert_scrollbar
.Scroll
+= new ScrollEventHandler (GridVScrolled
);
308 SetStyle (ControlStyles
.UserMouse
, true);
310 dataSourceStack
= new Stack ();
312 back_button_image
= ResourceImageLoader
.Get ("go-previous.png");
313 //back_button_image.MakeTransparent (Color.Transparent);
314 parent_rows_button_image
= ResourceImageLoader
.Get ("go-top.png");
315 //parent_rows_button_image.MakeTransparent (Color.Transparent);
318 #endregion // Public Constructor
320 #region Public Instance Properties
323 public bool AllowNavigation
{
324 get { return allow_navigation; }
326 if (allow_navigation
!= value) {
327 allow_navigation
= value;
328 OnAllowNavigationChanged (EventArgs
.Empty
);
334 public bool AllowSorting
{
335 get { return grid_style.AllowSorting; }
336 set { grid_style.AllowSorting = value; }
339 public Color AlternatingBackColor
{
340 get { return grid_style.AlternatingBackColor; }
341 set { grid_style.AlternatingBackColor = value; }
344 public override Color BackColor
{
345 get { return grid_style.BackColor; }
346 set { grid_style.BackColor = value; }
349 public Color BackgroundColor
{
350 get { return background_color; }
352 if (background_color
!= value) {
353 background_color
= value;
354 OnBackgroundColorChanged (EventArgs
.Empty
);
361 [EditorBrowsable(EditorBrowsableState
.Never
)]
362 public override Image BackgroundImage
{
363 get { return base.BackgroundImage; }
365 if (base.BackgroundImage
== value)
368 base.BackgroundImage
= value;
374 [DefaultValue(BorderStyle
.Fixed3D
)]
375 public BorderStyle BorderStyle
{
376 get { return InternalBorderStyle; }
378 InternalBorderStyle
= value;
379 CalcAreasAndInvalidate ();
380 OnBorderStyleChanged (EventArgs
.Empty
);
384 public Color CaptionBackColor
{
385 get { return caption_backcolor; }
387 if (caption_backcolor
!= value) {
388 caption_backcolor
= value;
389 InvalidateCaption ();
396 public Font CaptionFont
{
398 if (caption_font
== null)
399 return new Font (Font
, FontStyle
.Bold
);
404 if (caption_font
!= null && caption_font
.Equals (value))
407 caption_font
= value;
408 CalcAreasAndInvalidate ();
412 public Color CaptionForeColor
{
413 get { return caption_forecolor; }
415 if (caption_forecolor
!= value) {
416 caption_forecolor
= value;
417 InvalidateCaption ();
424 public string CaptionText
{
425 get { return caption_text; }
427 if (caption_text
!= value) {
428 caption_text
= value;
429 InvalidateCaption ();
435 public bool CaptionVisible
{
436 get { return caption_visible; }
438 if (caption_visible
!= value) {
440 caption_visible
= value;
441 CalcAreasAndInvalidate ();
442 OnCaptionVisibleChanged (EventArgs
.Empty
);
448 public bool ColumnHeadersVisible
{
449 get { return grid_style.ColumnHeadersVisible; }
450 set { grid_style.ColumnHeadersVisible = value; }
453 bool setting_current_cell
;
456 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
457 public DataGridCell CurrentCell
{
458 get { return current_cell; }
460 if (setting_current_cell
)
462 setting_current_cell
= true;
464 if (!IsHandleCreated
) {
465 setting_current_cell
= false;
466 throw new Exception ("CurrentCell cannot be set at this time.");
469 if (current_cell
.Equals (value)) {
470 setting_current_cell
= false;
474 /* make sure the new cell fits in the correct bounds for [row,column] */
475 if (ReadOnly
&& value.RowNumber
> RowsCount
- 1)
476 value.RowNumber
= RowsCount
- 1;
477 else if (value.RowNumber
> RowsCount
)
478 value.RowNumber
= RowsCount
;
479 if (value.ColumnNumber
>= CurrentTableStyle
.GridColumnStyles
.Count
)
480 value.ColumnNumber
= CurrentTableStyle
.GridColumnStyles
.Count
== 0 ? 0 : CurrentTableStyle
.GridColumnStyles
.Count
- 1;
482 bool was_changing
= is_changing
;
484 add_row_changed
= add_row_changed
|| was_changing
;
487 if (value.RowNumber
!= current_cell
.RowNumber
) {
488 if (!from_positionchanged_handler
) {
490 ListManager
.EndCurrentEdit ();
492 catch (Exception e
) {
493 DialogResult r
= MessageBox
.Show (String
.Format ("{0} Do you wish to correct the value?", e
.Message
),
494 "Error when committing the row to the original data source",
495 MessageBoxButtons
.YesNo
);
496 if (r
== DialogResult
.Yes
) {
501 ListManager
.CancelCurrentEdit ();
505 if (value.RowNumber
== RowsCount
&& !ListManager
.CanAddRows
)
508 if (value.RowNumber
== RowsCount
) {
509 cursor_in_add_row
= true;
510 add_row_changed
= false;
514 cursor_in_add_row
= false;
518 int old_row
= current_cell
.RowNumber
;
520 EnsureCellVisibility (value);
522 current_cell
= value;
524 InvalidateRowHeader (old_row
);
525 InvalidateRowHeader (current_cell
.RowNumber
);
527 list_manager
.Position
= current_cell
.RowNumber
;
529 OnCurrentCellChanged (EventArgs
.Empty
);
531 if (!from_positionchanged_handler
)
534 setting_current_cell
= false;
539 get { return current_cell.RowNumber; }
540 set { CurrentCell = new DataGridCell (value, current_cell.ColumnNumber); }
544 get { return current_cell.ColumnNumber; }
545 set { CurrentCell = new DataGridCell (current_cell.RowNumber, value); }
549 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
550 public int CurrentRowIndex
{
552 if (ListManager
== null)
557 set { CurrentRow = value; }
561 [EditorBrowsable(EditorBrowsableState
.Never
)]
562 public override Cursor Cursor
{
563 get { return base.Cursor; }
564 set { base.Cursor = value; }
568 [Editor ("System.Windows.Forms.Design.DataMemberListEditor, " + Consts
.AssemblySystem_Design
, "System.Drawing.Design.UITypeEditor, " + Consts
.AssemblySystem_Drawing
)]
569 public string DataMember
{
570 get { return datamember; }
572 if (BindingContext
!= null) {
573 SetDataSource (datasource
, value);
576 if (list_manager
!= null)
579 refetch_list_manager
= true;
585 [RefreshProperties(RefreshProperties
.Repaint
)]
586 [TypeConverter("System.Windows.Forms.Design.DataSourceConverter, " + Consts
.AssemblySystem_Design
)]
587 public object DataSource
{
588 get { return datasource; }
590 if (BindingContext
!= null) {
591 SetDataSource (value, ListManager
== null ? datamember
: string.Empty
);
595 if (list_manager
!= null)
596 datamember
= string.Empty
;
598 if (list_manager
!= null)
600 refetch_list_manager
= true;
605 protected override Size DefaultSize
{
606 get { return new Size (130, 80); }
610 public int FirstVisibleColumn
{
611 get { return first_visiblecolumn; }
614 [DefaultValue(false)]
615 public bool FlatMode
{
616 get { return flatmode; }
618 if (flatmode
!= value) {
620 OnFlatModeChanged (EventArgs
.Empty
);
626 public override Color ForeColor
{
627 get { return grid_style.ForeColor; }
628 set { grid_style.ForeColor = value; }
631 public Color GridLineColor
{
632 get { return grid_style.GridLineColor; }
634 if (value == Color
.Empty
)
635 throw new ArgumentException ("Color.Empty value is invalid.");
637 grid_style
.GridLineColor
= value;
641 [DefaultValue(DataGridLineStyle
.Solid
)]
642 public DataGridLineStyle GridLineStyle
{
643 get { return grid_style.GridLineStyle; }
644 set { grid_style.GridLineStyle = value; }
647 public Color HeaderBackColor
{
648 get { return grid_style.HeaderBackColor; }
650 if (value == Color
.Empty
)
651 throw new ArgumentException ("Color.Empty value is invalid.");
653 grid_style
.HeaderBackColor
= value;
657 public Font HeaderFont
{
658 get { return grid_style.HeaderFont; }
659 set { grid_style.HeaderFont = value; }
662 public Color HeaderForeColor
{
663 get { return grid_style.HeaderForeColor; }
664 set { grid_style.HeaderForeColor = value; }
667 protected ScrollBar HorizScrollBar
{
668 get { return horiz_scrollbar; }
670 internal ScrollBar HScrollBar
{
671 get { return horiz_scrollbar; }
674 internal int HorizPixelOffset
{
675 get { return horiz_pixeloffset; }
678 internal bool IsChanging
{
679 get { return is_changing; }
682 public object this [DataGridCell cell
] {
683 get { return this [cell.RowNumber, cell.ColumnNumber]; }
684 set { this [cell.RowNumber, cell.ColumnNumber] = value; }
687 public object this [int rowIndex
, int columnIndex
] {
688 get { return CurrentTableStyle
.GridColumnStyles
[columnIndex
].GetColumnValueAtRow (ListManager
,
690 set { CurrentTableStyle
.GridColumnStyles
[columnIndex
].SetColumnValueAtRow (ListManager
,
694 public Color LinkColor
{
695 get { return grid_style.LinkColor; }
696 set { grid_style.LinkColor = value; }
699 internal Font LinkFont
{
700 get { return new Font (Font, FontStyle.Underline); }
705 [EditorBrowsable(EditorBrowsableState
.Never
)]
706 public Color LinkHoverColor
{
707 get { return grid_style.LinkHoverColor; }
708 set { grid_style.LinkHoverColor = value; }
712 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
713 protected internal CurrencyManager ListManager
{
715 if (list_manager
== null && refetch_list_manager
) {
716 SetDataSource (datasource
, datamember
);
717 refetch_list_manager
= false;
722 set { throw new NotSupportedException ("Operation is not supported."); }
725 public Color ParentRowsBackColor
{
726 get { return parentrowsback_color; }
728 if (parentrowsback_color
!= value) {
729 parentrowsback_color
= value;
730 if (parentrows_visible
) {
737 public Color ParentRowsForeColor
{
738 get { return parentrowsfore_color; }
740 if (parentrowsfore_color
!= value) {
741 parentrowsfore_color
= value;
742 if (parentrows_visible
) {
749 [DefaultValue(DataGridParentRowsLabelStyle
.Both
)]
750 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
751 public DataGridParentRowsLabelStyle ParentRowsLabelStyle
{
752 get { return parentrowslabel_style; }
754 if (parentrowslabel_style
!= value) {
755 parentrowslabel_style
= value;
756 if (parentrows_visible
) {
760 OnParentRowsLabelStyleChanged (EventArgs
.Empty
);
766 public bool ParentRowsVisible
{
767 get { return parentrows_visible; }
769 if (parentrows_visible
!= value) {
770 parentrows_visible
= value;
771 CalcAreasAndInvalidate ();
772 OnParentRowsVisibleChanged (EventArgs
.Empty
);
777 // Settting this property seems to have no effect.
779 [TypeConverter(typeof(DataGridPreferredColumnWidthTypeConverter
))]
780 public int PreferredColumnWidth
{
781 get { return grid_style.PreferredColumnWidth; }
782 set { grid_style.PreferredColumnWidth = value; }
785 public int PreferredRowHeight
{
786 get { return grid_style.PreferredRowHeight; }
787 set { grid_style.PreferredRowHeight = value; }
790 [DefaultValue(false)]
791 public bool ReadOnly
{
792 get { return _readonly; }
794 if (_readonly
!= value) {
796 OnReadOnlyChanged (EventArgs
.Empty
);
797 CalcAreasAndInvalidate ();
803 public bool RowHeadersVisible
{
804 get { return grid_style.RowHeadersVisible; }
805 set { grid_style.RowHeadersVisible = value; }
809 public int RowHeaderWidth
{
810 get { return grid_style.RowHeaderWidth; }
811 set { grid_style.RowHeaderWidth = value; }
814 internal DataGridRelationshipRow
[] DataGridRows
{
819 public Color SelectionBackColor
{
820 get { return grid_style.SelectionBackColor; }
821 set { grid_style.SelectionBackColor = value; }
824 public Color SelectionForeColor
{
825 get { return grid_style.SelectionForeColor; }
826 set { grid_style.SelectionForeColor = value; }
829 public override ISite Site
{
830 get { return base.Site; }
831 set { base.Site = value; }
835 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
)]
836 public GridTableStylesCollection TableStyles
{
837 get { return styles_collection; }
842 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
843 [EditorBrowsable(EditorBrowsableState
.Never
)]
844 public override string Text
{
845 get { return base.Text; }
846 set { base.Text = value; }
850 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
851 protected ScrollBar VertScrollBar
{
852 get { return vert_scrollbar; }
854 internal ScrollBar VScrollBar
{
855 get { return vert_scrollbar; }
859 public int VisibleColumnCount
{
860 get { return visiblecolumn_count; }
864 public int VisibleRowCount
{
865 get { return visiblerow_count; }
868 #endregion // Public Instance Properties
870 #region Private Instance Properties
871 internal DataGridTableStyle CurrentTableStyle
{
872 get { return current_style; }
874 if (current_style
!= value) {
875 if (current_style
!= null)
876 DisconnectTableStyleEvents ();
878 current_style
= value;
880 if (current_style
!= null) {
881 current_style
.DataGrid
= this;
882 ConnectTableStyleEvents ();
884 CalcAreasAndInvalidate ();
889 internal int FirstVisibleRow
{
890 get { return first_visiblerow; }
893 internal int RowsCount
{
894 get { return ListManager != null ? ListManager.Count : 0; }
897 internal int RowHeight
{
899 if (CurrentTableStyle
.CurrentPreferredRowHeight
> Font
.Height
+ 3 + 1 /* line */)
900 return CurrentTableStyle
.CurrentPreferredRowHeight
;
902 return Font
.Height
+ 3 + 1 /* line */;
906 internal bool ShowEditRow
{
908 if (ListManager
!= null && !ListManager
.CanAddRows
)
915 internal bool ShowParentRows
{
916 get { return ParentRowsVisible && dataSourceStack.Count > 0; }
919 #endregion Private Instance Properties
921 #region Public Instance Methods
926 CurrentTableStyle
.GridColumnStyles
[current_cell
.ColumnNumber
].Abort (current_cell
.RowNumber
);
928 InvalidateRowHeader (current_cell
.RowNumber
);
933 public bool BeginEdit (DataGridColumnStyle gridColumn
, int rowNumber
)
938 int column
= CurrentTableStyle
.GridColumnStyles
.IndexOf (gridColumn
);
942 CurrentCell
= new DataGridCell (rowNumber
, column
);
944 /* force editing of CurrentCell if we aren't already editing */
950 public void BeginInit ()
954 protected virtual void CancelEditing ()
956 if (CurrentTableStyle
.GridColumnStyles
.Count
== 0)
959 CurrentTableStyle
.GridColumnStyles
[current_cell
.ColumnNumber
].ConcedeFocus ();
962 if (current_cell
.ColumnNumber
< CurrentTableStyle
.GridColumnStyles
.Count
)
963 CurrentTableStyle
.GridColumnStyles
[current_cell
.ColumnNumber
].Abort (current_cell
.RowNumber
);
964 InvalidateRowHeader (current_cell
.RowNumber
);
967 if (cursor_in_add_row
&& !is_changing
) {
968 ListManager
.CancelCurrentEdit ();
976 public void Collapse (int row
)
978 if (!rows
[row
].IsExpanded
)
982 rows
[row
].IsExpanded
= false;
983 for (int i
= 1; i
< rows
.Length
- row
; i
++)
984 rows
[row
+ i
].VerticalOffset
-= rows
[row
].RelationHeight
;
986 rows
[row
].height
-= rows
[row
].RelationHeight
;
987 rows
[row
].RelationHeight
= 0;
988 ResumeLayout (false);
990 /* XX need to redraw from @row down */
991 CalcAreasAndInvalidate ();
994 protected internal virtual void ColumnStartedEditing (Control editingControl
)
996 ColumnStartedEditing (editingControl
.Bounds
);
999 protected internal virtual void ColumnStartedEditing (Rectangle bounds
)
1001 bool need_invalidate
= is_changing
== false;
1002 // XXX calculate the row header to invalidate
1003 // instead of using CurrentRow
1006 if (cursor_in_add_row
&& need_invalidate
)
1007 RecreateDataGridRows (true);
1009 if (need_invalidate
)
1010 InvalidateRowHeader (CurrentRow
);
1013 protected override AccessibleObject
CreateAccessibilityInstance ()
1015 return base.CreateAccessibilityInstance ();
1018 protected virtual DataGridColumnStyle
CreateGridColumn (PropertyDescriptor prop
)
1020 return CreateGridColumn (prop
, false);
1023 protected virtual DataGridColumnStyle
CreateGridColumn (PropertyDescriptor prop
, bool isDefault
)
1025 throw new NotImplementedException();
1028 protected override void Dispose (bool disposing
)
1030 base.Dispose (disposing
);
1033 public bool EndEdit (DataGridColumnStyle gridColumn
, int rowNumber
, bool shouldAbort
)
1035 if (shouldAbort
|| gridColumn
.ParentReadOnly
)
1036 gridColumn
.Abort (rowNumber
);
1038 gridColumn
.Commit (ListManager
, rowNumber
);
1039 gridColumn
.ConcedeFocus ();
1042 if (is_editing
|| is_changing
) {
1044 is_changing
= false;
1045 InvalidateRowHeader (rowNumber
);
1050 public void EndInit ()
1054 public void Expand (int row
)
1056 if (rows
[row
].IsExpanded
)
1059 rows
[row
].IsExpanded
= true;
1063 string[] relations
= CurrentTableStyle
.Relations
;
1064 StringBuilder relation_builder
= new StringBuilder ("");
1066 for (i
= 0; i
< relations
.Length
; i
++) {
1068 relation_builder
.Append ("\n");
1070 relation_builder
.Append (relations
[i
]);
1072 string relation_text
= relation_builder
.ToString ();
1074 SizeF measured_area
= DeviceContext
.MeasureString (relation_text
, LinkFont
);
1076 rows
[row
].relation_area
= new Rectangle (cells_area
.X
+ 1,
1077 0, /* updated as needed at the usage sites for relation_area */
1078 (int)measured_area
.Width
+ 4,
1079 Font
.Height
* relations
.Length
);
1081 for (i
= 1; i
< rows
.Length
- row
; i
++)
1082 rows
[row
+ i
].VerticalOffset
+= rows
[row
].relation_area
.Height
;
1083 rows
[row
].height
+= rows
[row
].relation_area
.Height
;
1084 rows
[row
].RelationHeight
= rows
[row
].relation_area
.Height
;
1086 /* XX need to redraw from @row down */
1087 CalcAreasAndInvalidate ();
1090 public Rectangle
GetCellBounds (DataGridCell cell
)
1092 return GetCellBounds (cell
.RowNumber
, cell
.ColumnNumber
);
1095 public Rectangle
GetCellBounds (int row
, int col
)
1097 Rectangle bounds
= new Rectangle ();
1100 bounds
.Width
= CurrentTableStyle
.GridColumnStyles
[col
].Width
;
1101 bounds
.Height
= rows
[row
].Height
- rows
[row
].RelationHeight
;
1102 bounds
.Y
= cells_area
.Y
+ rows
[row
].VerticalOffset
- rows
[FirstVisibleRow
].VerticalOffset
;
1103 col_pixel
= GetColumnStartingPixel (col
);
1104 bounds
.X
= cells_area
.X
+ col_pixel
- horiz_pixeloffset
;
1108 public Rectangle
GetCurrentCellBounds ()
1110 return GetCellBounds (current_cell
.RowNumber
, current_cell
.ColumnNumber
);
1113 protected virtual string GetOutputTextDelimiter ()
1115 return string.Empty
;
1118 protected virtual void GridHScrolled (object sender
, ScrollEventArgs se
)
1120 if (se
.NewValue
== horiz_pixeloffset
||
1121 se
.Type
== ScrollEventType
.EndScroll
) {
1125 ScrollToColumnInPixels (se
.NewValue
);
1128 protected virtual void GridVScrolled (object sender
, ScrollEventArgs se
)
1130 int old_first_visiblerow
= first_visiblerow
;
1131 first_visiblerow
= se
.NewValue
;
1133 if (first_visiblerow
== old_first_visiblerow
)
1136 UpdateVisibleRowCount ();
1138 if (first_visiblerow
== old_first_visiblerow
)
1141 ScrollToRow (old_first_visiblerow
, first_visiblerow
);
1144 public HitTestInfo
HitTest (Point position
)
1146 return HitTest (position
.X
, position
.Y
);
1149 const int RESIZE_HANDLE_HORIZ_SIZE
= 5;
1150 const int RESIZE_HANDLE_VERT_SIZE
= 3;
1152 // From Point to Cell
1153 public HitTestInfo
HitTest (int x
, int y
)
1155 if (columnhdrs_area
.Contains (x
, y
)) {
1156 int offset_x
= x
+ horiz_pixeloffset
;
1158 int column_under_mouse
= FromPixelToColumn (offset_x
, out column_x
);
1160 if ((column_x
+ CurrentTableStyle
.GridColumnStyles
[column_under_mouse
].Width
- offset_x
< RESIZE_HANDLE_HORIZ_SIZE
)
1161 && column_under_mouse
< CurrentTableStyle
.GridColumnStyles
.Count
) {
1163 return new HitTestInfo (-1, column_under_mouse
, HitTestType
.ColumnResize
);
1166 return new HitTestInfo (-1, column_under_mouse
, HitTestType
.ColumnHeader
);
1170 if (rowhdrs_area
.Contains (x
, y
)) {
1172 int rcnt
= FirstVisibleRow
+ VisibleRowCount
;
1173 for (int r
= FirstVisibleRow
; r
< rcnt
; r
++) {
1174 posy
= cells_area
.Y
+ rows
[r
].VerticalOffset
- rows
[FirstVisibleRow
].VerticalOffset
;
1175 if (y
<= posy
+ rows
[r
].Height
) {
1176 if ((posy
+ rows
[r
].Height
) - y
< RESIZE_HANDLE_VERT_SIZE
) {
1177 return new HitTestInfo (r
, -1, HitTestType
.RowResize
);
1180 return new HitTestInfo (r
, -1, HitTestType
.RowHeader
);
1186 if (caption_area
.Contains (x
, y
)) {
1187 return new HitTestInfo (-1, -1, HitTestType
.Caption
);
1190 if (parent_rows
.Contains (x
, y
)) {
1191 return new HitTestInfo (-1, -1, HitTestType
.ParentRows
);
1194 int pos_y
, pos_x
, width
;
1195 int rowcnt
= FirstVisibleRow
+ VisibleRowCount
;
1196 for (int row
= FirstVisibleRow
; row
< rowcnt
; row
++) {
1198 pos_y
= cells_area
.Y
+ rows
[row
].VerticalOffset
- rows
[FirstVisibleRow
].VerticalOffset
;
1199 if (y
<= pos_y
+ rows
[row
].Height
) {
1201 int column_cnt
= first_visiblecolumn
+ visiblecolumn_count
;
1202 if (column_cnt
> 0) {
1203 for (int column
= first_visiblecolumn
; column
< column_cnt
; column
++) {
1204 if (CurrentTableStyle
.GridColumnStyles
[column
].bound
== false)
1206 col_pixel
= GetColumnStartingPixel (column
);
1207 pos_x
= cells_area
.X
+ col_pixel
- horiz_pixeloffset
;
1208 width
= CurrentTableStyle
.GridColumnStyles
[column
].Width
;
1210 if (x
<= pos_x
+ width
) { // Column found
1211 return new HitTestInfo (row
, column
, HitTestType
.Cell
);
1215 else if (CurrentTableStyle
.HasRelations
) {
1216 /* XXX this needs checking against MS somehow... */
1217 if (x
< rows
[row
].relation_area
.X
+ rows
[row
].relation_area
.Width
)
1218 return new HitTestInfo (row
, 0/*XXX?*/, HitTestType
.Cell
);
1225 return new HitTestInfo ();
1228 public bool IsExpanded (int rowNumber
)
1230 return (rows
[rowNumber
].IsExpanded
);
1233 public bool IsSelected (int row
)
1235 return rows
[row
].IsSelected
;
1239 public void NavigateBack ()
1241 if (dataSourceStack
.Count
== 0)
1244 DataGridDataSource source
= (DataGridDataSource
)dataSourceStack
.Pop ();
1245 list_manager
= source
.list_manager
;
1247 selected_rows
= source
.SelectedRows
;
1248 selection_start
= source
.SelectionStart
;
1249 SetDataSource (source
.data_source
, source
.data_member
);
1251 CurrentCell
= source
.current
;
1255 public void NavigateTo (int rowNumber
, string relationName
)
1257 if (allow_navigation
== false)
1260 DataGridDataSource previous_source
= new DataGridDataSource (this, list_manager
, datasource
, datamember
, list_manager
.Current
, CurrentCell
);
1261 previous_source
.Rows
= rows
;
1262 previous_source
.SelectedRows
= selected_rows
;
1263 previous_source
.SelectionStart
= selection_start
;
1265 dataSourceStack
.Push (previous_source
);
1268 selected_rows
= new Hashtable ();
1269 selection_start
= -1;
1271 DataMember
= String
.Format ("{0}.{1}", DataMember
, relationName
);
1272 OnDataSourceChanged (EventArgs
.Empty
);
1275 protected virtual void OnAllowNavigationChanged (EventArgs e
)
1277 EventHandler eh
= (EventHandler
)(Events
[AllowNavigationChangedEvent
]);
1282 protected void OnBackButtonClicked (object sender
, EventArgs e
)
1284 EventHandler eh
= (EventHandler
)(Events
[BackButtonClickEvent
]);
1289 protected override void OnBackColorChanged (EventArgs e
)
1291 base.OnBackColorChanged (e
);
1294 protected virtual void OnBackgroundColorChanged (EventArgs e
)
1296 EventHandler eh
= (EventHandler
)(Events
[BackgroundColorChangedEvent
]);
1301 protected override void OnBindingContextChanged (EventArgs e
)
1303 base.OnBindingContextChanged (e
);
1305 SetDataSource (datasource
, datamember
);
1308 protected virtual void OnBorderStyleChanged (EventArgs e
)
1310 EventHandler eh
= (EventHandler
)(Events
[BorderStyleChangedEvent
]);
1315 protected virtual void OnCaptionVisibleChanged (EventArgs e
)
1317 EventHandler eh
= (EventHandler
)(Events
[CaptionVisibleChangedEvent
]);
1322 protected virtual void OnCurrentCellChanged (EventArgs e
)
1324 EventHandler eh
= (EventHandler
)(Events
[CurrentCellChangedEvent
]);
1329 protected virtual void OnDataSourceChanged (EventArgs e
)
1331 EventHandler eh
= (EventHandler
)(Events
[DataSourceChangedEvent
]);
1336 protected override void OnEnter (EventArgs e
)
1341 protected virtual void OnFlatModeChanged (EventArgs e
)
1343 EventHandler eh
= (EventHandler
)(Events
[FlatModeChangedEvent
]);
1348 protected override void OnFontChanged (EventArgs e
)
1351 base.OnFontChanged (e
);
1354 protected override void OnForeColorChanged (EventArgs e
)
1356 base.OnForeColorChanged (e
);
1359 protected override void OnHandleCreated (EventArgs e
)
1361 base.OnHandleCreated (e
);
1362 SetDataSource (datasource
, datamember
);
1365 protected override void OnHandleDestroyed (EventArgs e
)
1367 base.OnHandleDestroyed (e
);
1370 protected override void OnKeyDown (KeyEventArgs ke
)
1372 base.OnKeyDown (ke
);
1374 if (ProcessGridKey (ke
) == true)
1377 /* TODO: we probably don't need this check,
1378 * since current_cell wouldn't have been set
1379 * to something invalid */
1380 if (CurrentTableStyle
.GridColumnStyles
.Count
> 0) {
1381 CurrentTableStyle
.GridColumnStyles
[current_cell
.ColumnNumber
].OnKeyDown
1382 (ke
, current_cell
.RowNumber
, current_cell
.ColumnNumber
);
1386 protected override void OnKeyPress (KeyPressEventArgs kpe
)
1388 base.OnKeyPress (kpe
);
1391 protected override void OnLayout (LayoutEventArgs levent
)
1393 base.OnLayout (levent
);
1394 CalcAreasAndInvalidate ();
1397 protected override void OnLeave (EventArgs e
)
1402 /* we get an OnLeave call when the
1403 * DataGridTextBox control is focused, so we
1404 * need to ignore that. If we get an OnLeave
1405 * call when a child control is not receiving
1406 * focus, we need to cancel the current
1408 if (cursor_in_add_row
) {
1409 ListManager
.CancelCurrentEdit ();
1414 protected override void OnMouseDown (MouseEventArgs e
)
1416 base.OnMouseDown (e
);
1418 bool ctrl_pressed
= ((Control
.ModifierKeys
& Keys
.Control
) != 0);
1419 bool shift_pressed
= ((Control
.ModifierKeys
& Keys
.Shift
) != 0);
1421 HitTestInfo testinfo
;
1422 testinfo
= HitTest (e
.X
, e
.Y
);
1424 switch (testinfo
.Type
) {
1425 case HitTestType
.Cell
:
1426 if (testinfo
.Row
< 0 || testinfo
.Column
< 0)
1429 if (rows
[testinfo
.Row
].IsExpanded
) {
1430 Rectangle relation_area
= rows
[testinfo
.Row
].relation_area
;
1431 relation_area
.Y
= rows
[testinfo
.Row
].VerticalOffset
+ cells_area
.Y
+ rows
[testinfo
.Row
].Height
- rows
[testinfo
.Row
].RelationHeight
;
1432 if (relation_area
.Contains (e
.X
, e
.Y
)) {
1433 /* the click happened in the relation area, navigate to the new table */
1434 int relative
= e
.Y
- relation_area
.Y
;
1435 NavigateTo (testinfo
.Row
, CurrentTableStyle
.Relations
[relative
/ LinkFont
.Height
]);
1440 DataGridCell new_cell
= new DataGridCell (testinfo
.Row
, testinfo
.Column
);
1442 if ((new_cell
.Equals (current_cell
) == false) || (!is_editing
)) {
1443 EnsureCellVisibility (new_cell
);
1444 CurrentCell
= new_cell
;
1447 CurrentTableStyle
.GridColumnStyles
[testinfo
.Column
].OnMouseDown (e
, testinfo
.Row
, testinfo
.Column
);
1452 case HitTestType
.RowHeader
:
1453 bool expansion_click
= false;
1454 if (CurrentTableStyle
.HasRelations
) {
1455 if (e
.X
> rowhdrs_area
.X
+ rowhdrs_area
.Width
/ 2) {
1456 /* it's in the +/- space */
1457 if (IsExpanded (testinfo
.Row
))
1458 Collapse (testinfo
.Row
);
1460 Expand (testinfo
.Row
);
1462 expansion_click
= true;
1466 if (!ctrl_pressed
&&
1469 ResetSelection (); // Invalidates selected rows
1472 if ((shift_pressed
||
1474 && selection_start
!= -1) {
1475 ShiftSelection (testinfo
.Row
);
1476 } else { // ctrl_pressed or single item
1477 selection_start
= testinfo
.Row
;
1478 Select (testinfo
.Row
);
1482 CurrentRow
= testinfo
.Row
;
1483 OnRowHeaderClick (EventArgs
.Empty
);
1487 case HitTestType
.ColumnHeader
:
1488 if (CurrentTableStyle
.GridColumnStyles
.Count
== 0)
1491 if (AllowSorting
== false)
1494 if (ListManager
.List
is IBindingList
== false)
1497 ListSortDirection direction
= ListSortDirection
.Ascending
;
1498 PropertyDescriptor prop
= CurrentTableStyle
.GridColumnStyles
[testinfo
.Column
].PropertyDescriptor
;
1499 IBindingList list
= (IBindingList
) ListManager
.List
;
1501 if (list
.SortProperty
!= null) {
1502 CurrentTableStyle
.GridColumnStyles
[list
.SortProperty
].ArrowDrawingMode
1503 = DataGridColumnStyle
.ArrowDrawing
.No
;
1506 if (prop
== list
.SortProperty
&& list
.SortDirection
== ListSortDirection
.Ascending
) {
1507 direction
= ListSortDirection
.Descending
;
1510 CurrentTableStyle
.GridColumnStyles
[testinfo
.Column
].ArrowDrawingMode
=
1511 direction
== ListSortDirection
.Ascending
?
1512 DataGridColumnStyle
.ArrowDrawing
.Ascending
: DataGridColumnStyle
.ArrowDrawing
.Descending
;
1514 list
.ApplySort (prop
, direction
);
1518 case HitTestType
.ColumnResize
:
1519 if (e
.Clicks
== 2) {
1520 // double click column resize goes here
1523 resize_column
= testinfo
.Column
;
1524 column_resize_active
= true;
1525 resize_column_x
= e
.X
;
1526 resize_column_width_delta
= 0;
1528 DrawResizeLineVert (resize_column_x
);
1532 case HitTestType
.RowResize
:
1533 if (e
.Clicks
== 2) {
1534 // double click row resize goes here
1537 resize_row
= testinfo
.Row
;
1538 row_resize_active
= true;
1540 resize_row_height_delta
= 0;
1542 DrawResizeLineHoriz (resize_row_y
);
1546 case HitTestType
.Caption
:
1547 if (back_button_rect
.Contains (e
.X
, e
.Y
)) {
1548 back_button_active
= true;
1549 Invalidate (back_button_rect
);
1551 if (parent_rows_button_rect
.Contains (e
.X
, e
.Y
)) {
1552 parent_rows_button_active
= true;
1553 Invalidate (parent_rows_button_rect
);
1562 protected override void OnMouseLeave (EventArgs e
)
1564 base.OnMouseLeave (e
);
1567 protected override void OnMouseMove (MouseEventArgs e
)
1569 base.OnMouseMove (e
);
1571 if (column_resize_active
) {
1572 /* erase the old line */
1573 DrawResizeLineVert (resize_column_x
+ resize_column_width_delta
);
1575 resize_column_width_delta
= e
.X
- resize_column_x
;
1577 /* draw the new line */
1578 DrawResizeLineVert (resize_column_x
+ resize_column_width_delta
);
1581 else if (row_resize_active
) {
1582 /* erase the old line */
1583 DrawResizeLineHoriz (resize_row_y
+ resize_row_height_delta
);
1585 resize_row_height_delta
= e
.Y
- resize_row_y
;
1587 /* draw the new line */
1588 DrawResizeLineHoriz (resize_row_y
+ resize_row_height_delta
);
1592 /* determine the cursor to use */
1593 HitTestInfo testinfo
;
1594 testinfo
= HitTest (e
.X
, e
.Y
);
1596 switch (testinfo
.Type
) {
1597 case HitTestType
.ColumnResize
:
1598 Cursor
= Cursors
.VSplit
;
1600 case HitTestType
.RowResize
:
1601 Cursor
= Cursors
.HSplit
;
1603 case HitTestType
.Caption
:
1604 Cursor
= Cursors
.Default
;
1605 if (back_button_rect
.Contains (e
.X
, e
.Y
)) {
1606 if (!back_button_mouseover
)
1607 Invalidate (back_button_rect
);
1608 back_button_mouseover
= true;
1610 else if (back_button_mouseover
) {
1611 Invalidate (back_button_rect
);
1612 back_button_mouseover
= false;
1615 if (parent_rows_button_rect
.Contains (e
.X
, e
.Y
)) {
1616 if (parent_rows_button_mouseover
)
1617 Invalidate (parent_rows_button_rect
);
1618 parent_rows_button_mouseover
= true;
1620 else if (parent_rows_button_mouseover
) {
1621 Invalidate (parent_rows_button_rect
);
1622 parent_rows_button_mouseover
= false;
1625 case HitTestType
.Cell
:
1626 if (rows
[testinfo
.Row
].IsExpanded
) {
1627 Rectangle relation_area
= rows
[testinfo
.Row
].relation_area
;
1628 relation_area
.Y
= rows
[testinfo
.Row
].VerticalOffset
+ cells_area
.Y
+ rows
[testinfo
.Row
].Height
- rows
[testinfo
.Row
].RelationHeight
;
1629 if (relation_area
.Contains (e
.X
, e
.Y
)) {
1630 Cursor
= Cursors
.Hand
;
1635 Cursor
= Cursors
.Default
;
1638 Cursor
= Cursors
.Default
;
1644 protected override void OnMouseUp (MouseEventArgs e
)
1648 if (column_resize_active
) {
1649 column_resize_active
= false;
1650 if (resize_column_width_delta
+ CurrentTableStyle
.GridColumnStyles
[resize_column
].Width
< 0)
1651 resize_column_width_delta
= -CurrentTableStyle
.GridColumnStyles
[resize_column
].Width
;
1652 CurrentTableStyle
.GridColumnStyles
[resize_column
].Width
+= resize_column_width_delta
;
1653 width_of_all_columns
+= resize_column_width_delta
;
1657 else if (row_resize_active
) {
1658 row_resize_active
= false;
1660 if (resize_row_height_delta
+ rows
[resize_row
].Height
< 0)
1661 resize_row_height_delta
= -rows
[resize_row
].Height
;
1663 rows
[resize_row
].height
= rows
[resize_row
].Height
+ resize_row_height_delta
;
1664 for (int i
= resize_row
+ 1; i
< rows
.Length
; i
++)
1665 rows
[i
].VerticalOffset
+= resize_row_height_delta
;
1668 CalcAreasAndInvalidate ();
1670 else if (back_button_active
) {
1671 if (back_button_rect
.Contains (e
.X
, e
.Y
)) {
1672 Invalidate (back_button_rect
);
1674 OnBackButtonClicked (this, EventArgs
.Empty
);
1676 back_button_active
= false;
1678 else if (parent_rows_button_active
) {
1679 if (parent_rows_button_rect
.Contains (e
.X
, e
.Y
)) {
1680 Invalidate (parent_rows_button_rect
);
1681 ParentRowsVisible
= !ParentRowsVisible
;
1682 OnShowParentDetailsButtonClicked (this, EventArgs
.Empty
);
1684 parent_rows_button_active
= false;
1688 protected override void OnMouseWheel (MouseEventArgs e
)
1690 base.OnMouseWheel (e
);
1692 bool ctrl_pressed
= ((Control
.ModifierKeys
& Keys
.Control
) != 0);
1695 if (ctrl_pressed
) { // scroll horizontally
1696 if (!horiz_scrollbar
.Visible
)
1701 pixels
= Math
.Max (horiz_scrollbar
.Minimum
,
1702 horiz_scrollbar
.Value
- horiz_scrollbar
.LargeChange
);
1706 pixels
= Math
.Min (horiz_scrollbar
.Maximum
- horiz_scrollbar
.LargeChange
+ 1,
1707 horiz_scrollbar
.Value
+ horiz_scrollbar
.LargeChange
);
1710 GridHScrolled (this, new ScrollEventArgs (ScrollEventType
.ThumbPosition
, pixels
));
1711 horiz_scrollbar
.Value
= pixels
;
1713 if (!vert_scrollbar
.Visible
)
1718 pixels
= Math
.Max (vert_scrollbar
.Minimum
,
1719 vert_scrollbar
.Value
- vert_scrollbar
.LargeChange
);
1723 pixels
= Math
.Min (vert_scrollbar
.Maximum
- vert_scrollbar
.LargeChange
+ 1,
1724 vert_scrollbar
.Value
+ vert_scrollbar
.LargeChange
);
1727 GridVScrolled (this, new ScrollEventArgs (ScrollEventType
.ThumbPosition
, pixels
));
1728 vert_scrollbar
.Value
= pixels
;
1732 protected void OnNavigate (NavigateEventArgs e
)
1734 EventHandler eh
= (EventHandler
)(Events
[NavigateEvent
]);
1739 protected override void OnPaint (PaintEventArgs pe
)
1741 ThemeEngine
.Current
.DataGridPaint (pe
, this);
1744 protected override void OnPaintBackground (PaintEventArgs ebe
)
1748 protected virtual void OnParentRowsLabelStyleChanged (EventArgs e
)
1750 EventHandler eh
= (EventHandler
)(Events
[ParentRowsLabelStyleChangedEvent
]);
1755 protected virtual void OnParentRowsVisibleChanged (EventArgs e
)
1757 EventHandler eh
= (EventHandler
)(Events
[ParentRowsVisibleChangedEvent
]);
1762 protected virtual void OnReadOnlyChanged (EventArgs e
)
1764 EventHandler eh
= (EventHandler
)(Events
[ReadOnlyChangedEvent
]);
1769 protected override void OnResize (EventArgs e
)
1774 protected void OnRowHeaderClick (EventArgs e
)
1776 EventHandler eh
= (EventHandler
)(Events
[RowHeaderClickEvent
]);
1781 protected void OnScroll (EventArgs e
)
1783 EventHandler eh
= (EventHandler
)(Events
[ScrollEvent
]);
1788 protected void OnShowParentDetailsButtonClicked (object sender
, EventArgs e
)
1790 EventHandler eh
= (EventHandler
)(Events
[ShowParentDetailsButtonClickEvent
]);
1795 protected override bool ProcessDialogKey (Keys keyData
)
1797 return ProcessGridKey (new KeyEventArgs (keyData
));
1800 void UpdateSelectionAfterCursorMove (bool extend_selection
)
1802 if (extend_selection
) {
1804 ShiftSelection (CurrentRow
);
1811 protected bool ProcessGridKey (KeyEventArgs ke
)
1813 /* if we have no rows, exit immediately.
1814 XXX is this necessary? */
1818 bool ctrl_pressed
= ((ke
.Modifiers
& Keys
.Control
) != 0);
1819 bool alt_pressed
= ((ke
.Modifiers
& Keys
.Alt
) != 0);
1820 bool shift_pressed
= ((ke
.Modifiers
& Keys
.Shift
) != 0);
1822 switch (ke
.KeyCode
) {
1834 CurrentTableStyle
.GridColumnStyles
[CurrentColumn
].EnterNullValue ();
1845 if (shift_pressed
) {
1846 if (CurrentColumn
> 0)
1848 else if ((CurrentRow
> 0) && (CurrentColumn
== 0))
1849 CurrentCell
= new DataGridCell (CurrentRow
- 1, CurrentTableStyle
.GridColumnStyles
.Count
- 1);
1852 if (CurrentColumn
< CurrentTableStyle
.GridColumnStyles
.Count
- 1)
1854 else if ((CurrentRow
<= RowsCount
) && (CurrentColumn
== CurrentTableStyle
.GridColumnStyles
.Count
- 1))
1855 CurrentCell
= new DataGridCell (CurrentRow
+ 1, 0);
1858 UpdateSelectionAfterCursorMove (false);
1864 CurrentColumn
= CurrentTableStyle
.GridColumnStyles
.Count
- 1;
1867 if (CurrentColumn
< CurrentTableStyle
.GridColumnStyles
.Count
- 1) {
1869 } else if (CurrentRow
< RowsCount
- 1
1870 || (CurrentRow
== RowsCount
- 1
1871 && !cursor_in_add_row
)) {
1872 CurrentCell
= new DataGridCell (CurrentRow
+ 1, 0);
1876 UpdateSelectionAfterCursorMove (false);
1885 if (current_cell
.ColumnNumber
> 0)
1887 else if (CurrentRow
> 0)
1888 CurrentCell
= new DataGridCell (CurrentRow
- 1, CurrentTableStyle
.GridColumnStyles
.Count
- 1);
1891 UpdateSelectionAfterCursorMove (false);
1898 else if (CurrentRow
> 0)
1901 UpdateSelectionAfterCursorMove (shift_pressed
);
1907 CurrentRow
= RowsCount
- 1;
1908 else if (CurrentRow
< RowsCount
- 1)
1910 else if (CurrentRow
== RowsCount
- 1 && cursor_in_add_row
&& (add_row_changed
|| is_changing
))
1912 else if (CurrentRow
== RowsCount
- 1 && !cursor_in_add_row
&& !shift_pressed
)
1915 UpdateSelectionAfterCursorMove (shift_pressed
);
1920 if (CurrentRow
> VLargeChange
)
1921 CurrentRow
-= VLargeChange
;
1925 UpdateSelectionAfterCursorMove (shift_pressed
);
1930 if (CurrentRow
< RowsCount
- VLargeChange
)
1931 CurrentRow
+= VLargeChange
;
1933 CurrentRow
= RowsCount
- 1;
1935 UpdateSelectionAfterCursorMove (shift_pressed
);
1941 CurrentCell
= new DataGridCell (0, 0);
1945 UpdateSelectionAfterCursorMove (ctrl_pressed
&& shift_pressed
);
1951 CurrentCell
= new DataGridCell (RowsCount
- 1, CurrentTableStyle
.GridColumnStyles
.Count
- 1);
1953 CurrentColumn
= CurrentTableStyle
.GridColumnStyles
.Count
- 1;
1955 UpdateSelectionAfterCursorMove (ctrl_pressed
&& shift_pressed
);
1960 foreach (int row
in selected_rows
.Keys
) {
1961 ListManager
.RemoveAt (row
);
1963 selected_rows
.Clear ();
1964 CalcAreasAndInvalidate ();
1969 return false; // message not processed
1972 protected override bool ProcessKeyPreview (ref Message m
)
1974 if ((Msg
)m
.Msg
== Msg
.WM_KEYDOWN
) {
1975 Keys key
= (Keys
) m
.WParam
.ToInt32 ();
1976 KeyEventArgs ke
= new KeyEventArgs (key
);
1977 if (ProcessGridKey (ke
) == true) {
1982 return base.ProcessKeyPreview (ref m
);
1985 protected bool ProcessTabKey (Keys keyData
)
1990 public void ResetAlternatingBackColor ()
1992 grid_style
.AlternatingBackColor
= default_style
.AlternatingBackColor
;
1995 public override void ResetBackColor ()
1997 grid_style
.BackColor
= default_style
.BackColor
;
2000 public override void ResetForeColor ()
2002 grid_style
.ForeColor
= default_style
.ForeColor
;
2005 public void ResetGridLineColor ()
2007 grid_style
.GridLineColor
= default_style
.GridLineColor
;
2010 public void ResetHeaderBackColor ()
2012 grid_style
.HeaderBackColor
= default_style
.HeaderBackColor
;
2015 public void ResetHeaderFont ()
2017 grid_style
.HeaderFont
= default_style
.HeaderFont
;
2020 public void ResetHeaderForeColor ()
2022 grid_style
.HeaderForeColor
= default_style
.HeaderForeColor
;
2025 public void ResetLinkColor ()
2027 grid_style
.LinkColor
= default_style
.LinkColor
;
2030 public void ResetLinkHoverColor ()
2032 grid_style
.LinkHoverColor
= default_style
.LinkHoverColor
;
2035 protected void ResetSelection ()
2037 InvalidateSelection ();
2038 selected_rows
.Clear ();
2039 selection_start
= -1;
2042 void InvalidateSelection ()
2044 foreach (int row
in selected_rows
.Keys
) {
2045 rows
[row
].IsSelected
= false;
2046 InvalidateRow (row
);
2050 public void ResetSelectionBackColor ()
2052 grid_style
.SelectionBackColor
= default_style
.SelectionBackColor
;
2055 public void ResetSelectionForeColor ()
2057 grid_style
.SelectionForeColor
= default_style
.SelectionForeColor
;
2060 public void Select (int row
)
2062 if (selected_rows
.Count
== 0)
2063 selection_start
= row
;
2065 selected_rows
[row
] = true;
2066 rows
[row
].IsSelected
= true;
2068 InvalidateRow (row
);
2071 public void SetDataBinding (object dataSource
, string dataMember
)
2073 SetDataSource (dataSource
, dataMember
);
2076 protected virtual bool ShouldSerializeAlternatingBackColor ()
2078 return (grid_style
.AlternatingBackColor
!= default_style
.AlternatingBackColor
);
2081 protected virtual bool ShouldSerializeBackgroundColor ()
2083 return (background_color
!= def_background_color
);
2086 protected virtual bool ShouldSerializeCaptionBackColor ()
2088 return (caption_backcolor
!= def_caption_backcolor
);
2091 protected virtual bool ShouldSerializeCaptionForeColor ()
2093 return caption_forecolor
!= def_caption_forecolor
;
2096 protected virtual bool ShouldSerializeGridLineColor ()
2098 return grid_style
.GridLineColor
!= default_style
.GridLineColor
;
2101 protected virtual bool ShouldSerializeHeaderBackColor ()
2103 return grid_style
.HeaderBackColor
!= default_style
.HeaderBackColor
;
2106 protected bool ShouldSerializeHeaderFont ()
2108 return grid_style
.HeaderFont
!= default_style
.HeaderFont
;
2111 protected virtual bool ShouldSerializeHeaderForeColor ()
2113 return grid_style
.HeaderForeColor
!= default_style
.HeaderForeColor
;
2116 protected virtual bool ShouldSerializeLinkHoverColor ()
2118 return grid_style
.LinkHoverColor
!= grid_style
.LinkHoverColor
;
2121 protected virtual bool ShouldSerializeParentRowsBackColor ()
2123 return parentrowsback_color
!= def_parentrowsback_color
;
2126 protected virtual bool ShouldSerializeParentRowsForeColor ()
2128 return parentrowsback_color
!= def_parentrowsback_color
;
2131 protected bool ShouldSerializePreferredRowHeight ()
2133 return grid_style
.PreferredRowHeight
!= default_style
.PreferredRowHeight
;
2136 protected bool ShouldSerializeSelectionBackColor ()
2138 return grid_style
.SelectionBackColor
!= default_style
.SelectionBackColor
;
2141 protected virtual bool ShouldSerializeSelectionForeColor ()
2143 return grid_style
.SelectionForeColor
!= default_style
.SelectionForeColor
;
2146 public void SubObjectsSiteChange (bool site
)
2150 public void UnSelect (int row
)
2152 rows
[row
].IsSelected
= false;
2153 selected_rows
.Remove (row
);
2154 InvalidateRow (row
);
2156 #endregion // Public Instance Methods
2158 #region Private Instance Methods
2160 internal void CalcAreasAndInvalidate ()
2166 private void ConnectListManagerEvents ()
2168 list_manager
.PositionChanged
+= new EventHandler (OnListManagerPositionChanged
);
2169 list_manager
.ItemChanged
+= new ItemChangedEventHandler (OnListManagerItemChanged
);
2172 private void DisconnectListManagerEvents ()
2174 list_manager
.PositionChanged
-= new EventHandler (OnListManagerPositionChanged
);
2175 list_manager
.ItemChanged
-= new ItemChangedEventHandler (OnListManagerItemChanged
);
2178 void DisconnectTableStyleEvents ()
2180 current_style
.AllowSortingChanged
-= new EventHandler (TableStyleChanged
);
2181 current_style
.AlternatingBackColorChanged
-= new EventHandler (TableStyleChanged
);
2182 current_style
.BackColorChanged
-= new EventHandler (TableStyleChanged
);
2183 current_style
.ColumnHeadersVisibleChanged
-= new EventHandler (TableStyleChanged
);
2184 current_style
.ForeColorChanged
-= new EventHandler (TableStyleChanged
);
2185 current_style
.GridLineColorChanged
-= new EventHandler (TableStyleChanged
);
2186 current_style
.GridLineStyleChanged
-= new EventHandler (TableStyleChanged
);
2187 current_style
.HeaderBackColorChanged
-= new EventHandler (TableStyleChanged
);
2188 current_style
.HeaderFontChanged
-= new EventHandler (TableStyleChanged
);
2189 current_style
.HeaderForeColorChanged
-= new EventHandler (TableStyleChanged
);
2190 current_style
.LinkColorChanged
-= new EventHandler (TableStyleChanged
);
2191 current_style
.LinkHoverColorChanged
-= new EventHandler (TableStyleChanged
);
2192 current_style
.MappingNameChanged
-= new EventHandler (TableStyleChanged
);
2193 current_style
.PreferredColumnWidthChanged
-= new EventHandler (TableStyleChanged
);
2194 current_style
.PreferredRowHeightChanged
-= new EventHandler (TableStyleChanged
);
2195 current_style
.ReadOnlyChanged
-= new EventHandler (TableStyleChanged
);
2196 current_style
.RowHeadersVisibleChanged
-= new EventHandler (TableStyleChanged
);
2197 current_style
.RowHeaderWidthChanged
-= new EventHandler (TableStyleChanged
);
2198 current_style
.SelectionBackColorChanged
-= new EventHandler (TableStyleChanged
);
2199 current_style
.SelectionForeColorChanged
-= new EventHandler (TableStyleChanged
);
2202 void ConnectTableStyleEvents ()
2204 current_style
.AllowSortingChanged
+= new EventHandler (TableStyleChanged
);
2205 current_style
.AlternatingBackColorChanged
+= new EventHandler (TableStyleChanged
);
2206 current_style
.BackColorChanged
+= new EventHandler (TableStyleChanged
);
2207 current_style
.ColumnHeadersVisibleChanged
+= new EventHandler (TableStyleChanged
);
2208 current_style
.ForeColorChanged
+= new EventHandler (TableStyleChanged
);
2209 current_style
.GridLineColorChanged
+= new EventHandler (TableStyleChanged
);
2210 current_style
.GridLineStyleChanged
+= new EventHandler (TableStyleChanged
);
2211 current_style
.HeaderBackColorChanged
+= new EventHandler (TableStyleChanged
);
2212 current_style
.HeaderFontChanged
+= new EventHandler (TableStyleChanged
);
2213 current_style
.HeaderForeColorChanged
+= new EventHandler (TableStyleChanged
);
2214 current_style
.LinkColorChanged
+= new EventHandler (TableStyleChanged
);
2215 current_style
.LinkHoverColorChanged
+= new EventHandler (TableStyleChanged
);
2216 current_style
.MappingNameChanged
+= new EventHandler (TableStyleChanged
);
2217 current_style
.PreferredColumnWidthChanged
+= new EventHandler (TableStyleChanged
);
2218 current_style
.PreferredRowHeightChanged
+= new EventHandler (TableStyleChanged
);
2219 current_style
.ReadOnlyChanged
+= new EventHandler (TableStyleChanged
);
2220 current_style
.RowHeadersVisibleChanged
+= new EventHandler (TableStyleChanged
);
2221 current_style
.RowHeaderWidthChanged
+= new EventHandler (TableStyleChanged
);
2222 current_style
.SelectionBackColorChanged
+= new EventHandler (TableStyleChanged
);
2223 current_style
.SelectionForeColorChanged
+= new EventHandler (TableStyleChanged
);
2226 void TableStyleChanged (object sender
, EventArgs args
)
2229 CalcAreasAndInvalidate ();
2233 private void EnsureCellVisibility (DataGridCell cell
)
2235 if (cell
.ColumnNumber
<= first_visiblecolumn
||
2236 cell
.ColumnNumber
+ 1 >= first_visiblecolumn
+ visiblecolumn_count
) {
2238 first_visiblecolumn
= GetFirstColumnForColumnVisibility (first_visiblecolumn
, cell
.ColumnNumber
);
2239 int pixel
= GetColumnStartingPixel (first_visiblecolumn
);
2240 ScrollToColumnInPixels (pixel
);
2241 horiz_scrollbar
.Value
= pixel
;
2245 if (cell
.RowNumber
< first_visiblerow
||
2246 cell
.RowNumber
+ 1 >= first_visiblerow
+ visiblerow_count
) {
2248 if (cell
.RowNumber
+ 1 >= first_visiblerow
+ visiblerow_count
) {
2249 int old_first_visiblerow
= first_visiblerow
;
2250 first_visiblerow
= 1 + cell
.RowNumber
- visiblerow_count
;
2251 UpdateVisibleRowCount ();
2252 ScrollToRow (old_first_visiblerow
, first_visiblerow
);
2254 int old_first_visiblerow
= first_visiblerow
;
2255 first_visiblerow
= cell
.RowNumber
;
2256 UpdateVisibleRowCount ();
2257 ScrollToRow (old_first_visiblerow
, first_visiblerow
);
2260 vert_scrollbar
.Value
= first_visiblerow
;
2264 private void SetDataSource (object source
, string member
)
2266 SetDataSource (source
, member
, true);
2269 bool in_setdatasource
;
2270 private void SetDataSource (object source
, string member
, bool recreate_rows
)
2272 CurrencyManager old_lm
= list_manager
;
2274 /* we need this bool flag to work around a
2275 * problem with OnBindingContextChanged. once
2276 * that stuff works properly, remove this
2278 if (in_setdatasource
)
2280 in_setdatasource
= true;
2283 if (datasource
== source
&& member
== datamember
)
2287 if (source
!= null && source
as IListSource
!= null && source
as IList
!= null)
2288 throw new Exception ("Wrong complex data binding source");
2290 datasource
= source
;
2291 datamember
= member
;
2296 current_cell
= new DataGridCell ();
2298 if (list_manager
!= null)
2299 DisconnectListManagerEvents ();
2301 list_manager
= null;
2303 /* create the new list manager */
2304 if (BindingContext
!= null && datasource
!= null)
2305 list_manager
= (CurrencyManager
) BindingContext
[datasource
, datamember
];
2307 if (list_manager
!= null)
2308 ConnectListManagerEvents ();
2310 if (list_manager
!= null) {
2311 string list_name
= list_manager
.GetListName (null);
2312 if (TableStyles
[list_name
] == null) {
2313 current_style
.GridColumnStyles
.Clear ();
2314 current_style
.CreateColumnsForTable (false);
2316 else if (CurrentTableStyle
.MappingName
!= list_name
) {
2317 // If the style has been defined by the user, use it
2318 CurrentTableStyle
= styles_collection
[list_name
];
2319 current_style
.CreateColumnsForTable (true);
2322 current_style
.CreateColumnsForTable (true);
2326 current_style
.CreateColumnsForTable (false);
2328 if (old_lm
!= list_manager
) {
2329 /* reset first_visiblerow to 0 here before
2330 * doing anything that'll requires us to
2331 * figure out if we need a scrollbar. */
2332 vert_scrollbar
.Value
= 0;
2333 horiz_scrollbar
.Value
= 0;
2334 first_visiblerow
= 0;
2337 RecreateDataGridRows (false);
2340 CalcAreasAndInvalidate ();
2342 in_setdatasource
= false;
2344 OnDataSourceChanged (EventArgs
.Empty
);
2347 private void OnListManagerPositionChanged (object sender
, EventArgs e
)
2349 from_positionchanged_handler
= true;
2350 CurrentRow
= list_manager
.Position
;
2351 from_positionchanged_handler
= false;
2354 void RecreateDataGridRows (bool recalc
)
2356 DataGridRelationshipRow
[] new_rows
= new DataGridRelationshipRow
[RowsCount
+ (ShowEditRow
? 1 : 0)];
2357 int start_index
= 0;
2359 start_index
= rows
.Length
;
2360 Array
.Copy (rows
, 0, new_rows
, 0, rows
.Length
< new_rows
.Length
? rows
.Length
: new_rows
.Length
);
2363 for (int i
= start_index
; i
< new_rows
.Length
; i
++) {
2364 new_rows
[i
] = new DataGridRelationshipRow (this);
2365 new_rows
[i
].height
= RowHeight
;
2367 new_rows
[i
].VerticalOffset
= new_rows
[i
-1].VerticalOffset
+ new_rows
[i
-1].Height
;
2373 CalcAreasAndInvalidate ();
2376 internal void UpdateRowsFrom (DataGridRelationshipRow row
)
2378 int start_index
= Array
.IndexOf (rows
, row
);
2379 if (start_index
== -1)
2382 for (int i
= start_index
+ 1; i
< rows
.Length
; i
++) {
2383 rows
[i
].VerticalOffset
= rows
[i
-1].VerticalOffset
+ rows
[i
-1].Height
;
2386 CalcAreasAndInvalidate ();
2389 private void OnListManagerItemChanged (object sender
, ItemChangedEventArgs e
)
2391 if (e
.Index
== -1) {
2393 if (rows
== null || RowsCount
!= rows
.Length
- (ShowEditRow
? 1 : 0))
2394 RecreateDataGridRows (true);
2397 InvalidateRow (e
.Index
);
2401 private void OnTableStylesCollectionChanged (object sender
, CollectionChangeEventArgs e
)
2403 if (ListManager
== null)
2406 string list_name
= ListManager
.GetListName (null);
2408 case CollectionChangeAction
.Add
: {
2409 if (e
.Element
!= null && String
.Compare (list_name
, ((DataGridTableStyle
)e
.Element
).MappingName
, true) == 0) {
2410 CurrentTableStyle
= (DataGridTableStyle
)e
.Element
;
2411 ((DataGridTableStyle
) e
.Element
).CreateColumnsForTable (false);
2416 case CollectionChangeAction
.Remove
: {
2417 if (e
.Element
!= null && String
.Compare (list_name
, ((DataGridTableStyle
)e
.Element
).MappingName
, true) == 0) {
2418 CurrentTableStyle
= default_style
;
2419 current_style
.GridColumnStyles
.Clear ();
2420 current_style
.CreateColumnsForTable (false);
2426 case CollectionChangeAction
.Refresh
: {
2427 if (CurrentTableStyle
== default_style
2428 || String
.Compare (list_name
, CurrentTableStyle
.MappingName
, true) != 0) {
2430 DataGridTableStyle style
= styles_collection
[list_name
];
2431 if (style
!= null) {
2432 CurrentTableStyle
= style
;
2433 current_style
.CreateColumnsForTable (false);
2436 CurrentTableStyle
= default_style
;
2437 current_style
.GridColumnStyles
.Clear ();
2438 current_style
.CreateColumnsForTable (false);
2445 CalcAreasAndInvalidate ();
2448 private void AddNewRow ()
2450 ListManager
.EndCurrentEdit ();
2451 ListManager
.AddNew ();
2454 private void Edit ()
2456 if (CurrentTableStyle
.GridColumnStyles
[current_cell
.ColumnNumber
].bound
== false)
2460 is_changing
= false;
2462 CurrentTableStyle
.GridColumnStyles
[current_cell
.ColumnNumber
].Edit (ListManager
,
2463 current_cell
.RowNumber
, GetCellBounds (current_cell
.RowNumber
, current_cell
.ColumnNumber
),
2464 _readonly
, "", true);
2467 private void EndEdit ()
2469 if (CurrentTableStyle
.GridColumnStyles
.Count
== 0)
2472 if (CurrentTableStyle
.GridColumnStyles
[current_cell
.ColumnNumber
].bound
== false)
2475 EndEdit (CurrentTableStyle
.GridColumnStyles
[current_cell
.ColumnNumber
],
2476 current_cell
.RowNumber
,
2480 private void ShiftSelection (int index
)
2482 // we have to save off selection_start
2483 // because ResetSelection clobbers it
2484 int saved_selection_start
= selection_start
;
2488 selection_start
= saved_selection_start
;
2490 if (index
>= selection_start
) {
2491 start
= selection_start
;
2496 end
= selection_start
;
2499 for (int idx
= start
; idx
<= end
; idx
++) {
2504 private void ScrollToColumnInPixels (int pixel
)
2508 if (pixel
> horiz_pixeloffset
) // ScrollRight
2509 pixels
= -1 * (pixel
- horiz_pixeloffset
);
2511 pixels
= horiz_pixeloffset
- pixel
;
2513 Rectangle area
= cells_area
;
2515 if (ColumnHeadersVisible
== true) {
2516 area
.Y
-= ColumnHeadersArea
.Height
;
2517 area
.Height
+= ColumnHeadersArea
.Height
;
2520 horiz_pixeloffset
= pixel
;
2521 UpdateVisibleColumn ();
2525 XplatUI
.ScrollWindow (Handle
, area
, pixels
, 0, false);
2527 int pixel_offset
= GetColumnStartingPixel (CurrentColumn
);
2528 int next_pixel_offset
= pixel_offset
+ CurrentTableStyle
.GridColumnStyles
[CurrentColumn
].Width
;
2530 if (pixel_offset
>= horiz_pixeloffset
2531 && next_pixel_offset
< horiz_pixeloffset
+ cells_area
.Width
)
2535 private void ScrollToRow (int old_row
, int new_row
)
2540 if (new_row
> old_row
) { // Scrolldown
2541 for (i
= old_row
; i
< new_row
; i
++)
2542 pixels
-= rows
[i
].Height
;
2545 for (i
= new_row
; i
< old_row
; i
++)
2546 pixels
+= rows
[i
].Height
;
2554 Rectangle rows_area
= cells_area
; // Cells area - partial rows space
2556 if (RowHeadersVisible
) {
2557 rows_area
.X
-= RowHeaderWidth
;
2558 rows_area
.Width
+= RowHeaderWidth
;
2561 /* scroll the window */
2562 XplatUI
.ScrollWindow (Handle
, rows_area
, 0, pixels
, false);
2564 /* if the row is still */
2565 if (CurrentRow
>= first_visiblerow
&& CurrentRow
< first_visiblerow
+ visiblerow_count
)
2569 #endregion Private Instance Methods
2573 static object AllowNavigationChangedEvent
= new object ();
2574 static object BackButtonClickEvent
= new object ();
2575 static object BackgroundColorChangedEvent
= new object ();
2576 static object BorderStyleChangedEvent
= new object ();
2577 static object CaptionVisibleChangedEvent
= new object ();
2578 static object CurrentCellChangedEvent
= new object ();
2579 static object DataSourceChangedEvent
= new object ();
2580 static object FlatModeChangedEvent
= new object ();
2581 static object NavigateEvent
= new object ();
2582 static object ParentRowsLabelStyleChangedEvent
= new object ();
2583 static object ParentRowsVisibleChangedEvent
= new object ();
2584 static object ReadOnlyChangedEvent
= new object ();
2585 static object RowHeaderClickEvent
= new object ();
2586 static object ScrollEvent
= new object ();
2587 static object ShowParentDetailsButtonClickEvent
= new object ();
2589 public event EventHandler AllowNavigationChanged
{
2590 add { Events.AddHandler (AllowNavigationChangedEvent, value); }
2591 remove { Events.RemoveHandler (AllowNavigationChangedEvent, value); }
2594 public event EventHandler BackButtonClick
{
2595 add { Events.AddHandler (BackButtonClickEvent, value); }
2596 remove { Events.RemoveHandler (BackButtonClickEvent, value); }
2599 public event EventHandler BackgroundColorChanged
{
2600 add { Events.AddHandler (BackgroundColorChangedEvent, value); }
2601 remove { Events.RemoveHandler (BackgroundColorChangedEvent, value); }
2605 [EditorBrowsable(EditorBrowsableState
.Never
)]
2606 public new event EventHandler BackgroundImageChanged
{
2607 add { base.BackgroundImageChanged += value; }
2608 remove { base.BackgroundImageChanged -= value; }
2612 [EditorBrowsable(EditorBrowsableState
.Never
)]
2613 public new event EventHandler TextChanged
{
2614 add { base.TextChanged += value; }
2615 remove { base.TextChanged -= value; }
2619 [EditorBrowsable(EditorBrowsableState
.Never
)]
2620 public new event EventHandler CursorChanged
{
2621 add { base.CursorChanged += value; }
2622 remove { base.CursorChanged -= value; }
2625 public event EventHandler BorderStyleChanged
{
2626 add { Events.AddHandler (BorderStyleChangedEvent, value); }
2627 remove { Events.RemoveHandler (BorderStyleChangedEvent, value); }
2630 public event EventHandler CaptionVisibleChanged
{
2631 add { Events.AddHandler (CaptionVisibleChangedEvent, value); }
2632 remove { Events.RemoveHandler (CaptionVisibleChangedEvent, value); }
2635 public event EventHandler CurrentCellChanged
{
2636 add { Events.AddHandler (CurrentCellChangedEvent, value); }
2637 remove { Events.RemoveHandler (CurrentCellChangedEvent, value); }
2640 public event EventHandler DataSourceChanged
{
2641 add { Events.AddHandler (DataSourceChangedEvent, value); }
2642 remove { Events.RemoveHandler (DataSourceChangedEvent, value); }
2645 public event EventHandler FlatModeChanged
{
2646 add { Events.AddHandler (FlatModeChangedEvent, value); }
2647 remove { Events.RemoveHandler (FlatModeChangedEvent, value); }
2650 public event NavigateEventHandler Navigate
{
2651 add { Events.AddHandler (NavigateEvent, value); }
2652 remove { Events.RemoveHandler (NavigateEvent, value); }
2655 public event EventHandler ParentRowsLabelStyleChanged
{
2656 add { Events.AddHandler (ParentRowsLabelStyleChangedEvent, value); }
2657 remove { Events.RemoveHandler (ParentRowsLabelStyleChangedEvent, value); }
2660 public event EventHandler ParentRowsVisibleChanged
{
2661 add { Events.AddHandler (ParentRowsVisibleChangedEvent, value); }
2662 remove { Events.RemoveHandler (ParentRowsVisibleChangedEvent, value); }
2665 public event EventHandler ReadOnlyChanged
{
2666 add { Events.AddHandler (ReadOnlyChangedEvent, value); }
2667 remove { Events.RemoveHandler (ReadOnlyChangedEvent, value); }
2670 protected event EventHandler RowHeaderClick
{
2671 add { Events.AddHandler (RowHeaderClickEvent, value); }
2672 remove { Events.RemoveHandler (RowHeaderClickEvent, value); }
2675 public event EventHandler Scroll
{
2676 add { Events.AddHandler (ScrollEvent, value); }
2677 remove { Events.RemoveHandler (ScrollEvent, value); }
2680 public event EventHandler ShowParentDetailsButtonClick
{
2681 add { Events.AddHandler (ShowParentDetailsButtonClickEvent, value); }
2682 remove { Events.RemoveHandler (ShowParentDetailsButtonClickEvent, value); }
2684 #endregion // Events
2689 #region Code originally in DataGridDrawingLogic.cs
2691 #region Local Variables
2694 Rectangle parent_rows
;
2695 int width_of_all_columns
;
2697 internal Rectangle caption_area
;
2698 internal Rectangle columnhdrs_area
; // Used columns header area
2699 internal int columnhdrs_maxwidth
; // Total width (max width) for columns headrs
2700 internal Rectangle rowhdrs_area
; // Used Headers rows area
2701 internal Rectangle cells_area
;
2702 #endregion // Local Variables
2705 #region Public Instance Methods
2707 // Calc the max with of all columns
2708 int CalcAllColumnsWidth ()
2711 int cnt
= CurrentTableStyle
.GridColumnStyles
.Count
;
2713 for (int col
= 0; col
< cnt
; col
++) {
2714 if (CurrentTableStyle
.GridColumnStyles
[col
].bound
== false) {
2717 width
+= CurrentTableStyle
.GridColumnStyles
[col
].Width
;
2722 // Gets a column from a pixel
2723 int FromPixelToColumn (int pixel
, out int column_x
)
2726 int cnt
= CurrentTableStyle
.GridColumnStyles
.Count
;
2732 if (CurrentTableStyle
.CurrentRowHeadersVisible
) {
2733 width
+= rowhdrs_area
.X
+ rowhdrs_area
.Width
;
2734 column_x
+= rowhdrs_area
.X
+ rowhdrs_area
.Width
;
2737 for (int col
= 0; col
< cnt
; col
++) {
2738 if (CurrentTableStyle
.GridColumnStyles
[col
].bound
== false)
2741 width
+= CurrentTableStyle
.GridColumnStyles
[col
].Width
;
2746 column_x
+= CurrentTableStyle
.GridColumnStyles
[col
].Width
;
2752 internal int GetColumnStartingPixel (int my_col
)
2755 int cnt
= CurrentTableStyle
.GridColumnStyles
.Count
;
2757 for (int col
= 0; col
< cnt
; col
++) {
2758 if (CurrentTableStyle
.GridColumnStyles
[col
].bound
== false) {
2765 width
+= CurrentTableStyle
.GridColumnStyles
[col
].Width
;
2771 // Which column has to be the first visible column to ensure a column visibility
2772 int GetFirstColumnForColumnVisibility (int current_first_visiblecolumn
, int column
)
2774 int new_col
= column
;
2777 if (column
> current_first_visiblecolumn
) { // Going forward
2778 for (new_col
= column
; new_col
>= 0; new_col
--){
2779 if (CurrentTableStyle
.GridColumnStyles
[new_col
].bound
== false)
2781 width
+= CurrentTableStyle
.GridColumnStyles
[new_col
].Width
;
2783 if (width
>= cells_area
.Width
)
2785 //return new_col < CurrentTableStyle.GridColumnStyles.Count ? new_col + 1 : CurrentTableStyle.GridColumnStyles.Count;
2793 bool in_calc_grid_areas
;
2794 void CalcGridAreas ()
2796 if (IsHandleCreated
== false) // Delay calculations until the handle is created
2799 /* make sure we don't happen to end up in this method again */
2800 if (in_calc_grid_areas
)
2803 in_calc_grid_areas
= true;
2805 /* Order is important. E.g. row headers max. height depends on caption */
2806 horiz_pixeloffset
= 0;
2809 CalcParentButtons ();
2810 UpdateVisibleRowCount ();
2812 width_of_all_columns
= CalcAllColumnsWidth ();
2813 CalcColumnHeaders ();
2816 bool needHoriz
= false;
2817 bool needVert
= false;
2819 /* figure out which scrollbars we need, and what the visible areas are */
2820 int visible_cells_width
= cells_area
.Width
;
2821 int visible_cells_height
= cells_area
.Height
;
2822 int allrows
= RowsCount
;
2824 if (ShowEditRow
&& RowsCount
> 0)
2827 /* use a loop to iteratively calculate whether
2828 * we need horiz/vert scrollbars. */
2829 for (int i
= 0; i
< 3; i
++) {
2831 visible_cells_width
= cells_area
.Width
- vert_scrollbar
.Width
;
2833 visible_cells_height
= cells_area
.Height
- horiz_scrollbar
.Height
;
2835 UpdateVisibleRowCount ();
2837 needHoriz
= (width_of_all_columns
> visible_cells_width
);
2838 needVert
= (allrows
> visiblerow_count
);
2841 int horiz_scrollbar_width
= ClientRectangle
.Width
;
2842 int horiz_scrollbar_maximum
= 0;
2843 int vert_scrollbar_height
= 0;
2844 int vert_scrollbar_maximum
= 0;
2847 SetUpVerticalScrollBar (out vert_scrollbar_height
, out vert_scrollbar_maximum
);
2850 SetUpHorizontalScrollBar (out horiz_scrollbar_maximum
);
2852 cells_area
.Width
= visible_cells_width
;
2853 cells_area
.Height
= visible_cells_height
;
2855 if (needVert
&& needHoriz
) {
2857 parent_rows
.Width
-= vert_scrollbar
.Width
;
2859 if (!ShowingColumnHeaders
) {
2860 if (columnhdrs_area
.X
+ columnhdrs_area
.Width
> vert_scrollbar
.Location
.X
) {
2861 columnhdrs_area
.Width
-= vert_scrollbar
.Width
;
2865 horiz_scrollbar_width
-= vert_scrollbar
.Width
;
2866 vert_scrollbar_height
-= horiz_scrollbar
.Height
;
2870 if (rowhdrs_area
.Y
+ rowhdrs_area
.Height
> ClientRectangle
.Y
+ ClientRectangle
.Height
) {
2871 rowhdrs_area
.Height
-= horiz_scrollbar
.Height
;
2874 vert_scrollbar
.Size
= new Size (vert_scrollbar
.Width
,
2875 vert_scrollbar_height
);
2877 vert_scrollbar
.Maximum
= vert_scrollbar_maximum
;
2878 Controls
.Add (vert_scrollbar
);
2879 vert_scrollbar
.Visible
= true;
2882 Controls
.Remove (vert_scrollbar
);
2883 vert_scrollbar
.Visible
= false;
2887 horiz_scrollbar
.Size
= new Size (horiz_scrollbar_width
,
2888 horiz_scrollbar
.Height
);
2890 horiz_scrollbar
.Maximum
= horiz_scrollbar_maximum
;
2891 Controls
.Add (horiz_scrollbar
);
2892 horiz_scrollbar
.Visible
= true;
2895 Controls
.Remove (horiz_scrollbar
);
2896 horiz_scrollbar
.Visible
= false;
2899 UpdateVisibleColumn ();
2900 UpdateVisibleRowCount ();
2902 in_calc_grid_areas
= false;
2907 caption_area
.X
= ClientRectangle
.X
;
2908 caption_area
.Y
= ClientRectangle
.Y
;
2909 caption_area
.Width
= ClientRectangle
.Width
;
2910 if (caption_visible
) {
2911 caption_area
.Height
= CaptionFont
.Height
;
2912 if (caption_area
.Height
< back_button_image
.Height
)
2913 caption_area
.Height
= back_button_image
.Height
;
2914 caption_area
.Height
+= 2;
2917 caption_area
.Height
= 0;
2920 void CalcCellsArea ()
2922 cells_area
.X
= ClientRectangle
.X
+ rowhdrs_area
.Width
;
2923 cells_area
.Y
= columnhdrs_area
.Y
+ columnhdrs_area
.Height
;
2924 cells_area
.Width
= ClientRectangle
.X
+ ClientRectangle
.Width
- cells_area
.X
;
2925 if (cells_area
.Width
< 0)
2926 cells_area
.Width
= 0;
2927 cells_area
.Height
= ClientRectangle
.Y
+ ClientRectangle
.Height
- cells_area
.Y
;
2928 if (cells_area
.Height
< 0)
2929 cells_area
.Height
= 0;
2932 void CalcColumnHeaders ()
2936 columnhdrs_area
.X
= ClientRectangle
.X
;
2937 columnhdrs_area
.Y
= parent_rows
.Y
+ parent_rows
.Height
;
2939 // TODO: take into account Scrollbars
2940 columnhdrs_maxwidth
= ClientRectangle
.X
+ ClientRectangle
.Width
- columnhdrs_area
.X
;
2941 max_width_cols
= columnhdrs_maxwidth
;
2943 if (CurrentTableStyle
.CurrentRowHeadersVisible
)
2944 max_width_cols
-= RowHeaderWidth
;
2946 if (width_of_all_columns
> max_width_cols
) {
2947 columnhdrs_area
.Width
= columnhdrs_maxwidth
;
2949 columnhdrs_area
.Width
= width_of_all_columns
;
2951 if (CurrentTableStyle
.CurrentRowHeadersVisible
)
2952 columnhdrs_area
.Width
+= RowHeaderWidth
;
2955 if (ShowingColumnHeaders
)
2956 columnhdrs_area
.Height
= CurrentTableStyle
.HeaderFont
.Height
+ 6;
2958 columnhdrs_area
.Height
= 0;
2961 void CalcParentRows ()
2963 parent_rows
.X
= ClientRectangle
.X
;
2964 parent_rows
.Y
= caption_area
.Y
+ caption_area
.Height
;
2965 parent_rows
.Width
= ClientRectangle
.Width
;
2967 parent_rows
.Height
= (CaptionFont
.Height
+ 3) * dataSourceStack
.Count
;
2969 parent_rows
.Height
= 0;
2972 void CalcParentButtons ()
2974 if (dataSourceStack
.Count
> 0 && CaptionVisible
) {
2975 back_button_rect
= new Rectangle (ClientRectangle
.X
+ ClientRectangle
.Width
- 2 * (caption_area
.Height
- 2) - 8,
2976 caption_area
.Height
/ 2 - back_button_image
.Height
/ 2,
2977 back_button_image
.Width
, back_button_image
.Height
);
2978 parent_rows_button_rect
= new Rectangle (ClientRectangle
.X
+ ClientRectangle
.Width
- (caption_area
.Height
- 2) - 4,
2979 caption_area
.Height
/ 2 - parent_rows_button_image
.Height
/ 2,
2980 parent_rows_button_image
.Width
, parent_rows_button_image
.Height
);
2983 back_button_rect
= parent_rows_button_rect
= Rectangle
.Empty
;
2987 void CalcRowHeaders ()
2989 rowhdrs_area
.X
= ClientRectangle
.X
;
2990 rowhdrs_area
.Y
= columnhdrs_area
.Y
+ columnhdrs_area
.Height
;
2991 rowhdrs_area
.Height
= ClientRectangle
.Height
+ ClientRectangle
.Y
- rowhdrs_area
.Y
;
2993 if (CurrentTableStyle
.CurrentRowHeadersVisible
)
2994 rowhdrs_area
.Width
= RowHeaderWidth
;
2996 rowhdrs_area
.Width
= 0;
2999 int GetVisibleRowCount (int visibleHeight
)
3001 int rows_height
= 0;
3003 for (r
= FirstVisibleRow
; r
< rows
.Length
; r
++) {
3004 if (rows_height
+ rows
[r
].Height
>= visibleHeight
)
3006 rows_height
+= rows
[r
].Height
;
3009 if (r
< rows
.Length
- 1)
3012 return r
- FirstVisibleRow
;
3015 void UpdateVisibleColumn ()
3017 if (CurrentTableStyle
.GridColumnStyles
.Count
== 0) {
3018 visiblecolumn_count
= 0;
3023 int max_pixel
= horiz_pixeloffset
+ cells_area
.Width
;
3026 first_visiblecolumn
= FromPixelToColumn (horiz_pixeloffset
, out unused
);
3028 col
= FromPixelToColumn (max_pixel
, out unused
);
3030 visiblecolumn_count
= 1 + col
- first_visiblecolumn
;
3032 visiblecolumn_count
= 0;
3033 for (int i
= first_visiblecolumn
; i
<= col
; i
++) {
3034 if (CurrentTableStyle
.GridColumnStyles
[i
].bound
)
3035 visiblecolumn_count
++;
3038 if (first_visiblecolumn
+ visiblecolumn_count
< CurrentTableStyle
.GridColumnStyles
.Count
) {
3039 visiblecolumn_count
++; // Partially visible column
3043 void UpdateVisibleRowCount ()
3045 visiblerow_count
= GetVisibleRowCount (cells_area
.Height
);
3047 CalcRowHeaders (); // Height depends on num of visible rows
3051 void InvalidateCaption ()
3053 if (caption_area
.IsEmpty
)
3056 Invalidate (caption_area
);
3059 void InvalidateRow (int row
)
3061 if (row
< FirstVisibleRow
|| row
> FirstVisibleRow
+ VisibleRowCount
)
3064 Rectangle rect_row
= new Rectangle ();
3066 rect_row
.X
= cells_area
.X
;
3067 rect_row
.Width
= width_of_all_columns
;
3068 if (rect_row
.Width
> cells_area
.Width
)
3069 rect_row
.Width
= cells_area
.Width
;
3070 rect_row
.Height
= rows
[row
].Height
;
3071 rect_row
.Y
= cells_area
.Y
+ rows
[row
].VerticalOffset
- rows
[FirstVisibleRow
].VerticalOffset
;
3072 Invalidate (rect_row
);
3075 void InvalidateRowHeader (int row
)
3077 Rectangle rect_rowhdr
= new Rectangle ();
3078 rect_rowhdr
.X
= rowhdrs_area
.X
;
3079 rect_rowhdr
.Width
= rowhdrs_area
.Width
;
3080 rect_rowhdr
.Height
= rows
[row
].Height
;
3081 rect_rowhdr
.Y
= rowhdrs_area
.Y
+ rows
[row
].VerticalOffset
- rows
[FirstVisibleRow
].VerticalOffset
;
3082 Invalidate (rect_rowhdr
);
3085 internal void InvalidateColumn (DataGridColumnStyle column
)
3087 Rectangle rect_col
= new Rectangle ();
3091 col
= CurrentTableStyle
.GridColumnStyles
.IndexOf (column
);
3096 rect_col
.Width
= column
.Width
;
3097 col_pixel
= GetColumnStartingPixel (col
);
3098 rect_col
.X
= cells_area
.X
+ col_pixel
- horiz_pixeloffset
;
3099 rect_col
.Y
= cells_area
.Y
;
3100 rect_col
.Height
= cells_area
.Height
;
3101 Invalidate (rect_col
);
3104 void DrawResizeLineVert (int x
)
3106 XplatUI
.DrawReversibleRectangle (Handle
,
3107 new Rectangle (x
, cells_area
.Y
, 1, cells_area
.Height
- 3),
3111 void DrawResizeLineHoriz (int y
)
3113 XplatUI
.DrawReversibleRectangle (Handle
,
3114 new Rectangle (cells_area
.X
, y
, cells_area
.Width
- 3, 1),
3118 void SetUpHorizontalScrollBar (out int maximum
)
3120 maximum
= width_of_all_columns
;
3122 horiz_scrollbar
.Location
= new Point (ClientRectangle
.X
, ClientRectangle
.Y
+
3123 ClientRectangle
.Height
- horiz_scrollbar
.Height
);
3125 horiz_scrollbar
.LargeChange
= cells_area
.Width
;
3129 void SetUpVerticalScrollBar (out int height
, out int maximum
)
3133 y
= ClientRectangle
.Y
+ parent_rows
.Y
+ parent_rows
.Height
;
3134 height
= ClientRectangle
.Height
- parent_rows
.Y
- parent_rows
.Height
;
3136 vert_scrollbar
.Location
= new Point (ClientRectangle
.X
+
3137 ClientRectangle
.Width
- vert_scrollbar
.Width
, y
);
3139 maximum
= RowsCount
;
3141 if (ShowEditRow
&& RowsCount
> 0) {
3145 vert_scrollbar
.LargeChange
= VLargeChange
;
3148 #endregion // Public Instance Methods
3150 #region Instance Properties
3151 // Returns the ColumnHeaders area excluding the rectangle shared with RowHeaders
3152 internal Rectangle ColumnHeadersArea
{
3154 Rectangle columns_area
= columnhdrs_area
;
3156 if (CurrentTableStyle
.CurrentRowHeadersVisible
) {
3157 columns_area
.X
+= RowHeaderWidth
;
3158 columns_area
.Width
-= RowHeaderWidth
;
3160 return columns_area
;
3164 bool ShowingColumnHeaders
{
3165 get { return ColumnHeadersVisible && CurrentTableStyle.GridColumnStyles.Count > 0; }
3168 internal Rectangle RowHeadersArea
{
3169 get { return rowhdrs_area; }
3172 internal Rectangle ParentRowsArea
{
3173 get { return parent_rows; }
3177 get { return VisibleRowCount; }
3180 #endregion Instance Properties
3182 #endregion // Code originally in DataGridDrawingLogic.cs