1 // Permission is hereby granted, free of charge, to any person obtaining 2 // a copy of this software and associated documentation files (the 3 // "Software"), to deal in the Software without restriction, including 4 // without limitation the rights to use, copy, modify, merge, publish, 5 // distribute, sublicense, and/or sell copies of the Software, and to 6 // permit persons to whom the Software is furnished to do so, subject to 7 // the following conditions: 8 // 9 // The above copyright notice and this permission notice shall be 10 // included in all copies or substantial portions of the Software. 11 // 12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 // 20 // Copyright (c) 2005,2006 Novell, Inc. (http://www.novell.com) 21 // 22 // Authors: 23 // Jordi Mas i Hernandez <jordi@ximian.com> 24 // Chris Toshok <toshok@ximian.com> 25 // 26 // 27 28 using System; 29 using System.ComponentModel; 30 using System.Data; 31 using System.Drawing; 32 using System.Runtime.InteropServices; 33 using System.Collections; 34 using System.Text; 35 36 namespace System.Windows.Forms 37 { 38 internal class DataGridRelationshipRow { 39 DataGrid owner; 40 DataGridRelationshipRow(DataGrid owner)41 public DataGridRelationshipRow (DataGrid owner) 42 { 43 this.owner = owner; 44 IsSelected = false; 45 IsExpanded = false; 46 height = 0; 47 VerticalOffset = 0; 48 RelationHeight = 0; 49 relation_area = Rectangle.Empty; 50 } 51 52 public int height; 53 54 /* this needs to be a property so that the Autosize 55 * example from the Windows.Forms FAQ will work */ 56 public int Height { 57 get { return height; } 58 set { 59 if (height != value) { 60 height = value; 61 owner.UpdateRowsFrom (this); 62 } 63 } 64 } 65 66 public bool IsSelected; 67 public bool IsExpanded; 68 public int VerticalOffset; 69 public int RelationHeight; 70 public Rectangle relation_area; /* the Y coordinate of this rectangle is updated as needed */ 71 } 72 73 internal class DataGridDataSource 74 { 75 public DataGrid owner; 76 public CurrencyManager list_manager; 77 public object view; 78 public string data_member; 79 public object data_source; 80 public DataGridCell current; 81 DataGridDataSource(DataGrid owner, CurrencyManager list_manager, object data_source, string data_member, object view_data, DataGridCell current)82 public DataGridDataSource (DataGrid owner, CurrencyManager list_manager, object data_source, string data_member, object view_data, DataGridCell current) 83 { 84 this.owner = owner; 85 this.list_manager = list_manager; 86 this.view = view_data; 87 this.data_source = data_source; 88 this.data_member = data_member; 89 this.current = current; 90 } 91 92 DataGridRelationshipRow[] rows; 93 public DataGridRelationshipRow[] Rows { 94 get { return rows; } 95 set { rows = value; } 96 } 97 98 Hashtable selected_rows; 99 public Hashtable SelectedRows { 100 get { return selected_rows; } 101 set { selected_rows = value; } 102 } 103 104 int selection_start; 105 public int SelectionStart { 106 get { return selection_start; } 107 set { selection_start = value; } 108 } 109 } 110 111 [DefaultEvent("Navigate")] 112 [DefaultProperty("DataSource")] 113 [Designer("System.Windows.Forms.Design.DataGridDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")] 114 [ComplexBindingProperties ("DataSource", "DataMember")] 115 [ClassInterface (ClassInterfaceType.AutoDispatch)] 116 [ComVisible (true)] 117 public class DataGrid : Control, ISupportInitialize, IDataGridEditingService 118 { 119 [Flags] 120 public enum HitTestType 121 { 122 None = 0, 123 Cell = 1, 124 ColumnHeader = 2, 125 RowHeader = 4, 126 ColumnResize = 8, 127 RowResize = 16, 128 Caption = 32, 129 ParentRows = 64 130 } 131 132 public sealed class HitTestInfo 133 { 134 public static readonly HitTestInfo Nowhere = null; 135 136 int row; 137 int column; 138 DataGrid.HitTestType type; 139 140 #region Private Constructors HitTestInfo()141 internal HitTestInfo () : this (-1, -1, HitTestType.None) 142 { 143 } 144 HitTestInfo(int row, int column, DataGrid.HitTestType type)145 internal HitTestInfo (int row, int column, DataGrid.HitTestType type) 146 { 147 this.row = row; 148 this.column = column; 149 this.type = type; 150 } 151 #endregion 152 153 154 #region Public Instance Properties 155 public int Column { 156 get { return column; } 157 } 158 159 public int Row { 160 get { return row; } 161 } 162 public DataGrid.HitTestType Type { 163 get { return type; } 164 } 165 #endregion //Public Instance Properties 166 Equals(object value)167 public override bool Equals (object value) 168 { 169 if (!(value is HitTestInfo)) 170 return false; 171 172 HitTestInfo obj = (HitTestInfo) value; 173 return (obj.Column == column && obj.Row == row && obj.Type ==type); 174 } 175 GetHashCode()176 public override int GetHashCode () 177 { 178 return row ^ column; 179 } 180 ToString()181 public override string ToString () 182 { 183 return "{ " + type + "," + row + "," + column + "}"; 184 } 185 } 186 187 #region Local Variables 188 /* cached theme defaults */ 189 static readonly Color def_background_color = ThemeEngine.Current.DataGridBackgroundColor; 190 static readonly Color def_caption_backcolor = ThemeEngine.Current.DataGridCaptionBackColor; 191 static readonly Color def_caption_forecolor = ThemeEngine.Current.DataGridCaptionForeColor; 192 static readonly Color def_parent_rows_backcolor = ThemeEngine.Current.DataGridParentRowsBackColor; 193 static readonly Color def_parent_rows_forecolor = ThemeEngine.Current.DataGridParentRowsForeColor; 194 195 /* colors */ 196 // XXX this needs addressing. Control.background_color should not be internal. 197 new Color background_color; 198 Color caption_backcolor; 199 Color caption_forecolor; 200 Color parent_rows_backcolor; 201 Color parent_rows_forecolor; 202 203 /* flags to determine which areas of the datagrid are shown */ 204 bool caption_visible; 205 bool parent_rows_visible; 206 207 GridTableStylesCollection styles_collection; 208 DataGridParentRowsLabelStyle parent_rows_label_style; 209 DataGridTableStyle default_style; 210 DataGridTableStyle grid_style; 211 DataGridTableStyle current_style; 212 213 /* selection */ 214 DataGridCell current_cell; 215 Hashtable selected_rows; 216 int selection_start; // used for range selection 217 218 /* layout/rendering */ 219 bool allow_navigation; 220 int first_visible_row; 221 int first_visible_column; 222 int visible_row_count; 223 int visible_column_count; 224 Font caption_font; 225 string caption_text; 226 bool flatmode; 227 HScrollBar horiz_scrollbar; 228 VScrollBar vert_scrollbar; 229 int horiz_pixeloffset; 230 231 internal Bitmap back_button_image; 232 internal Rectangle back_button_rect; 233 internal bool back_button_mouseover; 234 internal bool back_button_active; 235 internal Bitmap parent_rows_button_image; 236 internal Rectangle parent_rows_button_rect; 237 internal bool parent_rows_button_mouseover; 238 internal bool parent_rows_button_active; 239 240 /* databinding */ 241 object datasource; 242 string datamember; 243 CurrencyManager list_manager; 244 bool refetch_list_manager = true; 245 bool _readonly; 246 DataGridRelationshipRow[] rows; 247 248 /* column resize fields */ 249 bool column_resize_active; 250 int resize_column_x; 251 int resize_column_width_delta; 252 int resize_column; 253 254 /* row resize fields */ 255 bool row_resize_active; 256 int resize_row_y; 257 int resize_row_height_delta; 258 int resize_row; 259 260 /* used to make sure we don't endlessly recurse calling set_CurrentCell and OnListManagerPositionChanged */ 261 bool from_positionchanged_handler; 262 263 /* editing state */ 264 bool cursor_in_add_row; 265 bool add_row_changed; 266 internal bool is_editing; // Current cell is edit mode 267 bool is_changing; 268 bool commit_row_changes = true; // Whether to commit current edit or cancel it 269 bool adding_new_row; // Used to temporary ignore the new row added by CurrencyManager.AddNew in CurrentCell 270 271 internal Stack data_source_stack; 272 internal Stack data_grid_table_style_stack; 273 internal Stack grid_style_stack; 274 275 #endregion // Local Variables 276 277 #region Public Constructors DataGrid()278 public DataGrid () 279 { 280 allow_navigation = true; 281 background_color = def_background_color; 282 border_style = BorderStyle.Fixed3D; 283 caption_backcolor = def_caption_backcolor; 284 caption_forecolor = def_caption_forecolor; 285 caption_text = string.Empty; 286 caption_visible = true; 287 datamember = string.Empty; 288 parent_rows_backcolor = def_parent_rows_backcolor; 289 parent_rows_forecolor = def_parent_rows_forecolor; 290 parent_rows_visible = true; 291 current_cell = new DataGridCell (); 292 parent_rows_label_style = DataGridParentRowsLabelStyle.Both; 293 selected_rows = new Hashtable (); 294 selection_start = -1; 295 rows = new DataGridRelationshipRow [0]; 296 297 grid_style_stack = new Stack (); 298 data_grid_table_style_stack = new Stack (); 299 default_style = new DataGridTableStyle (true); 300 grid_style = new DataGridTableStyle (); 301 302 styles_collection = new GridTableStylesCollection (this); 303 styles_collection.CollectionChanged += new CollectionChangeEventHandler (OnTableStylesCollectionChanged); 304 305 CurrentTableStyle = grid_style; 306 307 horiz_scrollbar = new ImplicitHScrollBar (); 308 horiz_scrollbar.Scroll += new ScrollEventHandler (GridHScrolled); 309 vert_scrollbar = new ImplicitVScrollBar (); 310 vert_scrollbar.Scroll += new ScrollEventHandler (GridVScrolled); 311 312 SetStyle (ControlStyles.UserMouse, true); 313 314 data_source_stack = new Stack (); 315 316 back_button_image = ResourceImageLoader.Get ("go-previous.png"); 317 back_button_image.MakeTransparent (Color.Transparent); 318 parent_rows_button_image = ResourceImageLoader.Get ("go-top.png"); 319 parent_rows_button_image.MakeTransparent (Color.Transparent); 320 } 321 322 #endregion // Public Constructor 323 324 #region Public Instance Properties 325 326 [DefaultValue(true)] 327 public bool AllowNavigation { 328 get { return allow_navigation; } 329 set { 330 if (allow_navigation != value) { 331 allow_navigation = value; 332 OnAllowNavigationChanged (EventArgs.Empty); 333 } 334 } 335 } 336 337 [DefaultValue(true)] 338 public bool AllowSorting { 339 get { return grid_style.AllowSorting; } 340 set { grid_style.AllowSorting = value; } 341 } 342 343 public Color AlternatingBackColor { 344 get { return grid_style.AlternatingBackColor; } 345 set { grid_style.AlternatingBackColor = value; } 346 } 347 348 public override Color BackColor { 349 get { return grid_style.BackColor; } 350 set { grid_style.BackColor = value; } 351 } 352 353 public Color BackgroundColor { 354 get { return background_color; } 355 set { 356 if (background_color != value) { 357 background_color = value; 358 OnBackgroundColorChanged (EventArgs.Empty); 359 Invalidate (); 360 } 361 } 362 } 363 364 [Browsable(false)] 365 [EditorBrowsable(EditorBrowsableState.Never)] 366 public override Image BackgroundImage { 367 get { return base.BackgroundImage; } 368 set { 369 if (base.BackgroundImage == value) 370 return; 371 372 base.BackgroundImage = value; 373 Invalidate (); 374 } 375 } 376 377 [Browsable (false)] 378 [EditorBrowsable (EditorBrowsableState.Never)] 379 public override ImageLayout BackgroundImageLayout { 380 get { return base.BackgroundImageLayout; } 381 set { base.BackgroundImageLayout = value; } 382 } 383 384 [DispId(-504)] 385 [DefaultValue(BorderStyle.Fixed3D)] 386 public BorderStyle BorderStyle { 387 get { return InternalBorderStyle; } 388 set { 389 InternalBorderStyle = value; 390 CalcAreasAndInvalidate (); 391 OnBorderStyleChanged (EventArgs.Empty); 392 } 393 } 394 395 public Color CaptionBackColor { 396 get { return caption_backcolor; } 397 set { 398 if (caption_backcolor != value) { 399 caption_backcolor = value; 400 InvalidateCaption (); 401 } 402 } 403 } 404 405 [Localizable(true)] 406 [AmbientValue(null)] 407 public Font CaptionFont { 408 get { 409 if (caption_font == null) 410 return new Font (Font, FontStyle.Bold); 411 412 return caption_font; 413 } 414 set { 415 if (caption_font != null && caption_font.Equals (value)) 416 return; 417 418 caption_font = value; 419 CalcAreasAndInvalidate (); 420 } 421 } 422 423 public Color CaptionForeColor { 424 get { return caption_forecolor; } 425 set { 426 if (caption_forecolor != value) { 427 caption_forecolor = value; 428 InvalidateCaption (); 429 } 430 } 431 } 432 433 [Localizable(true)] 434 [DefaultValue("")] 435 public string CaptionText { 436 get { return caption_text; } 437 set { 438 if (caption_text != value) { 439 caption_text = value; 440 InvalidateCaption (); 441 } 442 } 443 } 444 445 [DefaultValue(true)] 446 public bool CaptionVisible { 447 get { return caption_visible; } 448 set { 449 if (caption_visible != value) { 450 EndEdit (); 451 caption_visible = value; 452 CalcAreasAndInvalidate (); 453 OnCaptionVisibleChanged (EventArgs.Empty); 454 } 455 } 456 } 457 458 [DefaultValue(true)] 459 public bool ColumnHeadersVisible { 460 get { return grid_style.ColumnHeadersVisible; } 461 set { 462 if (grid_style.ColumnHeadersVisible != value) { 463 grid_style.ColumnHeadersVisible = value; 464 465 // UIA Framework: To keep track of header 466 OnUIAColumnHeadersVisibleChanged (); 467 } 468 } 469 } 470 471 bool setting_current_cell; 472 473 [Browsable(false)] 474 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 475 public DataGridCell CurrentCell { 476 get { return current_cell; } 477 set { 478 if (setting_current_cell) 479 return; 480 setting_current_cell = true; 481 482 if (!IsHandleCreated) { 483 setting_current_cell = false; 484 throw new Exception ("CurrentCell cannot be set at this time."); 485 } 486 487 /* Even if we are on the same cell, we could need to actually start edition */ 488 if (current_cell.Equals (value) && is_editing) { 489 setting_current_cell = false; 490 return; 491 } 492 493 /* make sure the new cell fits in the correct bounds for [row,column] */ 494 if (ReadOnly && value.RowNumber > RowsCount - 1) 495 value.RowNumber = RowsCount - 1; 496 else if (value.RowNumber > RowsCount) 497 value.RowNumber = RowsCount; 498 if (value.ColumnNumber >= CurrentTableStyle.GridColumnStyles.Count) 499 value.ColumnNumber = CurrentTableStyle.GridColumnStyles.Count == 0 ? 0 : CurrentTableStyle.GridColumnStyles.Count - 1; 500 501 502 /* now make sure we don't go negative */ 503 if (value.RowNumber < 0) value.RowNumber = 0; 504 if (value.ColumnNumber < 0) value.ColumnNumber = 0; 505 506 bool was_changing = is_changing; 507 508 add_row_changed = add_row_changed || was_changing; 509 510 EndEdit (); 511 if (value.RowNumber != current_cell.RowNumber) { 512 if (!from_positionchanged_handler) { 513 try { 514 if (commit_row_changes) 515 ListManager.EndCurrentEdit (); 516 else 517 ListManager.CancelCurrentEdit (); 518 } 519 catch (Exception e) { 520 DialogResult r = MessageBox.Show (String.Format ("{0} Do you wish to correct the value?", e.Message), 521 "Error when committing the row to the original data source", 522 MessageBoxButtons.YesNo); 523 if (r == DialogResult.Yes) { 524 InvalidateRowHeader (value.RowNumber); 525 InvalidateRowHeader (current_cell.RowNumber); 526 setting_current_cell = false; 527 Edit (); 528 return; 529 } 530 else 531 ListManager.CancelCurrentEdit (); 532 } 533 } 534 535 if (value.RowNumber == RowsCount && !ListManager.AllowNew) 536 value.RowNumber --; 537 } 538 539 int old_row = current_cell.RowNumber; 540 541 current_cell = value; 542 543 EnsureCellVisibility (value); 544 545 // by default, edition in existing rows is commited, and for new ones is discarded, unless 546 // we receive actual input data from the user 547 if (CurrentRow == RowsCount && ListManager.AllowNew) { 548 commit_row_changes = false; 549 cursor_in_add_row = true; 550 add_row_changed = false; 551 552 adding_new_row = true; 553 AddNewRow (); 554 adding_new_row = false; 555 } 556 else { 557 cursor_in_add_row = false; 558 commit_row_changes = true; 559 } 560 561 InvalidateRowHeader (old_row); 562 InvalidateRowHeader (current_cell.RowNumber); 563 564 list_manager.Position = current_cell.RowNumber; 565 566 OnCurrentCellChanged (EventArgs.Empty); 567 568 if (!from_positionchanged_handler) 569 Edit (); 570 571 setting_current_cell = false; 572 } 573 } 574 EditRowChanged(DataGridColumnStyle column_style)575 internal void EditRowChanged (DataGridColumnStyle column_style) 576 { 577 if (cursor_in_add_row) { 578 if (!commit_row_changes) { // first change in add row, time to show another row in the ui 579 commit_row_changes = true; 580 RecreateDataGridRows (true); 581 } 582 } 583 } 584 585 int CurrentRow { 586 get { return current_cell.RowNumber; } 587 set { CurrentCell = new DataGridCell (value, current_cell.ColumnNumber); } 588 } 589 590 int CurrentColumn { 591 get { return current_cell.ColumnNumber; } 592 set { CurrentCell = new DataGridCell (current_cell.RowNumber, value); } 593 } 594 595 [Browsable(false)] 596 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 597 public int CurrentRowIndex { 598 get { 599 if (ListManager == null) 600 return -1; 601 602 return CurrentRow; 603 } 604 set { CurrentRow = value; } 605 } 606 607 [Browsable(false)] 608 [EditorBrowsable(EditorBrowsableState.Never)] 609 public override Cursor Cursor { 610 get { return base.Cursor; } 611 set { base.Cursor = value; } 612 } 613 614 [DefaultValue(null)] 615 [Editor ("System.Windows.Forms.Design.DataMemberListEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)] 616 public string DataMember { 617 get { return datamember; } 618 set { 619 if (BindingContext != null) { 620 SetDataSource (datasource, value); 621 } 622 else { 623 if (list_manager != null) 624 list_manager = null; 625 datamember = value; 626 refetch_list_manager = true; 627 } 628 } 629 } 630 631 [DefaultValue(null)] 632 [RefreshProperties(RefreshProperties.Repaint)] 633 [AttributeProvider (typeof (IListSource))] 634 public object DataSource { 635 get { return datasource; } 636 set { 637 if (BindingContext != null) { 638 SetDataSource (value, ListManager == null ? datamember : string.Empty); 639 } 640 else { 641 datasource = value; 642 if (list_manager != null) 643 datamember = string.Empty; 644 645 if (list_manager != null) 646 list_manager = null; 647 refetch_list_manager = true; 648 } 649 } 650 } 651 652 protected override Size DefaultSize { 653 get { return new Size (130, 80); } 654 } 655 656 [Browsable(false)] 657 public int FirstVisibleColumn { 658 get { return first_visible_column; } 659 } 660 661 [DefaultValue(false)] 662 public bool FlatMode { 663 get { return flatmode; } 664 set { 665 if (flatmode != value) { 666 flatmode = value; 667 OnFlatModeChanged (EventArgs.Empty); 668 Refresh (); 669 } 670 } 671 } 672 673 public override Color ForeColor { 674 get { return grid_style.ForeColor; } 675 set { grid_style.ForeColor = value; } 676 } 677 678 public Color GridLineColor { 679 get { return grid_style.GridLineColor; } 680 set { 681 if (value == Color.Empty) 682 throw new ArgumentException ("Color.Empty value is invalid."); 683 684 grid_style.GridLineColor = value; 685 } 686 } 687 688 [DefaultValue(DataGridLineStyle.Solid)] 689 public DataGridLineStyle GridLineStyle { 690 get { return grid_style.GridLineStyle; } 691 set { grid_style.GridLineStyle = value; } 692 } 693 694 public Color HeaderBackColor { 695 get { return grid_style.HeaderBackColor; } 696 set { 697 if (value == Color.Empty) 698 throw new ArgumentException ("Color.Empty value is invalid."); 699 700 grid_style.HeaderBackColor = value; 701 } 702 } 703 704 public Font HeaderFont { 705 get { return grid_style.HeaderFont; } 706 set { grid_style.HeaderFont = value; } 707 } 708 709 public Color HeaderForeColor { 710 get { return grid_style.HeaderForeColor; } 711 set { grid_style.HeaderForeColor = value; } 712 } 713 714 protected ScrollBar HorizScrollBar { 715 get { return horiz_scrollbar; } 716 } 717 internal ScrollBar HScrollBar { 718 get { return horiz_scrollbar; } 719 } 720 721 internal int HorizPixelOffset { 722 get { return horiz_pixeloffset; } 723 } 724 725 internal bool IsChanging { 726 get { return is_changing; } 727 } 728 729 public object this [DataGridCell cell] { 730 get { return this [cell.RowNumber, cell.ColumnNumber]; } 731 set { this [cell.RowNumber, cell.ColumnNumber] = value; } 732 } 733 734 public object this [int rowIndex, int columnIndex] { 735 get { return CurrentTableStyle.GridColumnStyles[columnIndex].GetColumnValueAtRow (ListManager, 736 rowIndex); } 737 set { 738 CurrentTableStyle.GridColumnStyles[columnIndex].SetColumnValueAtRow (ListManager, 739 rowIndex, value); 740 741 // UIA Framework: Raising changes in datasource. 742 OnUIAGridCellChanged (new CollectionChangeEventArgs (CollectionChangeAction.Refresh, 743 new DataGridCell (rowIndex, 744 columnIndex))); 745 } 746 } 747 748 public Color LinkColor { 749 get { return grid_style.LinkColor; } 750 set { grid_style.LinkColor = value; } 751 } 752 753 internal Font LinkFont { 754 get { return new Font (Font, FontStyle.Underline); } 755 } 756 757 [Browsable(false)] 758 [EditorBrowsable(EditorBrowsableState.Never)] 759 public Color LinkHoverColor { 760 get { return grid_style.LinkHoverColor; } 761 set { grid_style.LinkHoverColor = value; } 762 } 763 764 [Browsable(false)] 765 [EditorBrowsable(EditorBrowsableState.Advanced)] 766 protected internal CurrencyManager ListManager { 767 get { 768 if (list_manager == null && refetch_list_manager) { 769 SetDataSource (datasource, datamember); 770 refetch_list_manager = false; 771 } 772 773 return list_manager; 774 } 775 set { throw new NotSupportedException ("Operation is not supported."); } 776 } 777 778 public Color ParentRowsBackColor { 779 get { return parent_rows_backcolor; } 780 set { 781 if (parent_rows_backcolor != value) { 782 parent_rows_backcolor = value; 783 if (parent_rows_visible) { 784 Refresh (); 785 } 786 } 787 } 788 } 789 790 public Color ParentRowsForeColor { 791 get { return parent_rows_forecolor; } 792 set { 793 if (parent_rows_forecolor != value) { 794 parent_rows_forecolor = value; 795 if (parent_rows_visible) { 796 Refresh (); 797 } 798 } 799 } 800 } 801 802 [DefaultValue(DataGridParentRowsLabelStyle.Both)] 803 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 804 public DataGridParentRowsLabelStyle ParentRowsLabelStyle { 805 get { return parent_rows_label_style; } 806 set { 807 if (parent_rows_label_style != value) { 808 parent_rows_label_style = value; 809 if (parent_rows_visible) { 810 Refresh (); 811 } 812 813 OnParentRowsLabelStyleChanged (EventArgs.Empty); 814 } 815 } 816 } 817 818 [DefaultValue(true)] 819 public bool ParentRowsVisible { 820 get { return parent_rows_visible; } 821 set { 822 if (parent_rows_visible != value) { 823 parent_rows_visible = value; 824 CalcAreasAndInvalidate (); 825 OnParentRowsVisibleChanged (EventArgs.Empty); 826 } 827 } 828 } 829 830 // Settting this property seems to have no effect. 831 [DefaultValue(75)] 832 [TypeConverter(typeof(DataGridPreferredColumnWidthTypeConverter))] 833 public int PreferredColumnWidth { 834 get { return grid_style.PreferredColumnWidth; } 835 set { grid_style.PreferredColumnWidth = value; } 836 } 837 838 public int PreferredRowHeight { 839 get { return grid_style.PreferredRowHeight; } 840 set { grid_style.PreferredRowHeight = value; } 841 } 842 843 [DefaultValue(false)] 844 public bool ReadOnly { 845 get { return _readonly; } 846 set { 847 if (_readonly != value) { 848 _readonly = value; 849 OnReadOnlyChanged (EventArgs.Empty); 850 CalcAreasAndInvalidate (); 851 } 852 } 853 } 854 855 [DefaultValue(true)] 856 public bool RowHeadersVisible { 857 get { return grid_style.RowHeadersVisible; } 858 set { grid_style.RowHeadersVisible = value; } 859 } 860 861 [DefaultValue(35)] 862 public int RowHeaderWidth { 863 get { return grid_style.RowHeaderWidth; } 864 set { grid_style.RowHeaderWidth = value; } 865 } 866 867 internal DataGridRelationshipRow[] DataGridRows { 868 get { return rows; } 869 } 870 871 872 public Color SelectionBackColor { 873 get { return grid_style.SelectionBackColor; } 874 set { grid_style.SelectionBackColor = value; } 875 } 876 877 public Color SelectionForeColor { 878 get { return grid_style.SelectionForeColor; } 879 set { grid_style.SelectionForeColor = value; } 880 } 881 882 public override ISite Site { 883 get { return base.Site; } 884 set { base.Site = value; } 885 } 886 887 [Localizable(true)] 888 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 889 public GridTableStylesCollection TableStyles { 890 get { return styles_collection; } 891 } 892 893 [Bindable(false)] 894 [Browsable(false)] 895 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 896 [EditorBrowsable(EditorBrowsableState.Never)] 897 public override string Text { 898 get { return base.Text; } 899 set { base.Text = value; } 900 } 901 902 [Browsable(false)] 903 [EditorBrowsable(EditorBrowsableState.Advanced)] 904 protected ScrollBar VertScrollBar { 905 get { return vert_scrollbar; } 906 } 907 internal ScrollBar VScrollBar { 908 get { return vert_scrollbar; } 909 } 910 911 [Browsable(false)] 912 public int VisibleColumnCount { 913 get { return visible_column_count; } 914 } 915 916 [Browsable(false)] 917 public int VisibleRowCount { 918 get { return visible_row_count; } 919 } 920 921 #endregion // Public Instance Properties 922 923 #region Private Instance Properties 924 internal DataGridTableStyle CurrentTableStyle { 925 get { return current_style; } 926 set { 927 if (current_style != value) { 928 if (current_style != null) 929 DisconnectTableStyleEvents (); 930 931 current_style = value; 932 933 if (current_style != null) { 934 current_style.DataGrid = this; 935 ConnectTableStyleEvents (); 936 } 937 CalcAreasAndInvalidate (); 938 } 939 } 940 } 941 942 internal int FirstVisibleRow { 943 get { return first_visible_row; } 944 } 945 946 // As opposed to VisibleRowCount, this value is the maximum 947 // *possible* number of visible rows given our area. 948 internal int MaxVisibleRowCount { 949 get { 950 return cells_area.Height / RowHeight; 951 } 952 } 953 954 internal int RowsCount { 955 get { return ListManager != null ? ListManager.Count : 0; } 956 } 957 958 internal int RowHeight { 959 get { 960 if (CurrentTableStyle.CurrentPreferredRowHeight > Font.Height + 3 + 1 /* line */) 961 return CurrentTableStyle.CurrentPreferredRowHeight; 962 else 963 return Font.Height + 3 + 1 /* line */; 964 } 965 } 966 967 internal override bool ScaleChildrenInternal { 968 get { return false; } 969 } 970 971 internal bool ShowEditRow { 972 get { 973 if (ListManager != null && !ListManager.AllowNew) 974 return false; 975 976 return !_readonly; 977 } 978 } 979 980 internal bool ShowParentRows { 981 get { return ParentRowsVisible && data_source_stack.Count > 0; } 982 } 983 984 #endregion Private Instance Properties 985 986 #region Public Instance Methods 987 AbortEditing()988 void AbortEditing () 989 { 990 if (is_changing) { 991 CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].Abort (current_cell.RowNumber); 992 is_changing = false; 993 InvalidateRowHeader (current_cell.RowNumber); 994 } 995 } 996 BeginEdit(DataGridColumnStyle gridColumn, int rowNumber)997 public bool BeginEdit (DataGridColumnStyle gridColumn, int rowNumber) 998 { 999 if (is_changing) 1000 return false; 1001 1002 int column = CurrentTableStyle.GridColumnStyles.IndexOf (gridColumn); 1003 if (column < 0) 1004 return false; 1005 1006 CurrentCell = new DataGridCell (rowNumber, column); 1007 1008 /* force editing of CurrentCell if we aren't already editing */ 1009 Edit (); 1010 1011 return true; 1012 } 1013 BeginInit()1014 public void BeginInit () 1015 { 1016 } 1017 CancelEditing()1018 protected virtual void CancelEditing () 1019 { 1020 if (CurrentTableStyle.GridColumnStyles.Count == 0) 1021 return; 1022 1023 CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].ConcedeFocus (); 1024 1025 if (is_changing) { 1026 if (current_cell.ColumnNumber < CurrentTableStyle.GridColumnStyles.Count) 1027 CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].Abort (current_cell.RowNumber); 1028 InvalidateRowHeader (current_cell.RowNumber); 1029 } 1030 1031 if (cursor_in_add_row && !is_changing) { 1032 ListManager.CancelCurrentEdit (); 1033 } 1034 1035 is_changing = false; 1036 is_editing = false; 1037 } 1038 Collapse(int row)1039 public void Collapse (int row) 1040 { 1041 if (!rows[row].IsExpanded) 1042 return; 1043 1044 SuspendLayout (); 1045 rows[row].IsExpanded = false; 1046 for (int i = 1; i < rows.Length - row; i ++) 1047 rows[row + i].VerticalOffset -= rows[row].RelationHeight; 1048 1049 rows[row].height -= rows[row].RelationHeight; 1050 rows[row].RelationHeight = 0; 1051 ResumeLayout (false); 1052 1053 /* XX need to redraw from @row down */ 1054 CalcAreasAndInvalidate (); 1055 } 1056 ColumnStartedEditing(Control editingControl)1057 protected internal virtual void ColumnStartedEditing (Control editingControl) 1058 { 1059 ColumnStartedEditing (editingControl.Bounds); 1060 } 1061 ColumnStartedEditing(Rectangle bounds)1062 protected internal virtual void ColumnStartedEditing (Rectangle bounds) 1063 { 1064 bool need_invalidate = is_changing == false; 1065 // XXX calculate the row header to invalidate 1066 // instead of using CurrentRow 1067 is_changing = true; 1068 1069 if (cursor_in_add_row && need_invalidate) 1070 RecreateDataGridRows (true); 1071 1072 if (need_invalidate) 1073 InvalidateRowHeader (CurrentRow); 1074 } 1075 CreateAccessibilityInstance()1076 protected override AccessibleObject CreateAccessibilityInstance () 1077 { 1078 return base.CreateAccessibilityInstance (); 1079 } 1080 CreateGridColumn(PropertyDescriptor prop)1081 protected virtual DataGridColumnStyle CreateGridColumn (PropertyDescriptor prop) 1082 { 1083 return CreateGridColumn (prop, false); 1084 } 1085 1086 [MonoTODO ("Not implemented, will throw NotImplementedException")] CreateGridColumn(PropertyDescriptor prop, bool isDefault)1087 protected virtual DataGridColumnStyle CreateGridColumn (PropertyDescriptor prop, bool isDefault) 1088 { 1089 throw new NotImplementedException(); 1090 } 1091 Dispose(bool disposing)1092 protected override void Dispose (bool disposing) 1093 { 1094 base.Dispose (disposing); 1095 } 1096 EndEdit(DataGridColumnStyle gridColumn, int rowNumber, bool shouldAbort)1097 public bool EndEdit (DataGridColumnStyle gridColumn, int rowNumber, bool shouldAbort) 1098 { 1099 if (shouldAbort || (_readonly || gridColumn.TableStyleReadOnly || gridColumn.ReadOnly)) 1100 gridColumn.Abort (rowNumber); 1101 else { 1102 gridColumn.Commit (ListManager, rowNumber); 1103 gridColumn.ConcedeFocus (); 1104 } 1105 1106 if (is_editing || is_changing) { 1107 is_editing = false; 1108 is_changing = false; 1109 InvalidateRowHeader (rowNumber); 1110 } 1111 return true; 1112 } 1113 EndInit()1114 public void EndInit () 1115 { 1116 if (grid_style != null) 1117 grid_style.DataGrid = this; 1118 } 1119 Expand(int row)1120 public void Expand (int row) 1121 { 1122 if (rows[row].IsExpanded) 1123 return; 1124 1125 rows[row].IsExpanded = true; 1126 1127 int i; 1128 1129 string[] relations = CurrentTableStyle.Relations; 1130 StringBuilder relation_builder = new StringBuilder (""); 1131 1132 for (i = 0; i < relations.Length; i ++) { 1133 if (i > 0) 1134 relation_builder.Append ("\n"); 1135 1136 relation_builder.Append (relations[i]); 1137 } 1138 string relation_text = relation_builder.ToString (); 1139 1140 SizeF measured_area = TextRenderer.MeasureString (relation_text, LinkFont); 1141 1142 rows[row].relation_area = new Rectangle (cells_area.X + 1, 1143 0, /* updated as needed at the usage sites for relation_area */ 1144 (int)measured_area.Width + 4, 1145 Font.Height * relations.Length); 1146 1147 for (i = 1; i < rows.Length - row; i ++) 1148 rows[row + i].VerticalOffset += rows[row].relation_area.Height; 1149 rows[row].height += rows[row].relation_area.Height; 1150 rows[row].RelationHeight = rows[row].relation_area.Height; 1151 1152 /* XX need to redraw from @row down */ 1153 CalcAreasAndInvalidate (); 1154 } 1155 GetCellBounds(DataGridCell dgc)1156 public Rectangle GetCellBounds (DataGridCell dgc) 1157 { 1158 return GetCellBounds (dgc.RowNumber, dgc.ColumnNumber); 1159 } 1160 GetCellBounds(int row, int col)1161 public Rectangle GetCellBounds (int row, int col) 1162 { 1163 Rectangle bounds = new Rectangle (); 1164 int col_pixel; 1165 1166 bounds.Width = CurrentTableStyle.GridColumnStyles[col].Width; 1167 bounds.Height = rows[row].Height - rows[row].RelationHeight; 1168 bounds.Y = cells_area.Y + rows[row].VerticalOffset - rows[FirstVisibleRow].VerticalOffset; 1169 col_pixel = GetColumnStartingPixel (col); 1170 bounds.X = cells_area.X + col_pixel - horiz_pixeloffset; 1171 return bounds; 1172 } 1173 GetCurrentCellBounds()1174 public Rectangle GetCurrentCellBounds () 1175 { 1176 return GetCellBounds (current_cell.RowNumber, current_cell.ColumnNumber); 1177 } 1178 GetOutputTextDelimiter()1179 protected virtual string GetOutputTextDelimiter () 1180 { 1181 return string.Empty; 1182 } 1183 GridHScrolled(object sender, ScrollEventArgs se)1184 protected virtual void GridHScrolled (object sender, ScrollEventArgs se) 1185 { 1186 if (se.NewValue == horiz_pixeloffset || 1187 se.Type == ScrollEventType.EndScroll) { 1188 return; 1189 } 1190 1191 ScrollToColumnInPixels (se.NewValue); 1192 } 1193 GridVScrolled(object sender, ScrollEventArgs se)1194 protected virtual void GridVScrolled (object sender, ScrollEventArgs se) 1195 { 1196 int old_first_visible_row = first_visible_row; 1197 first_visible_row = se.NewValue; 1198 1199 if (first_visible_row == old_first_visible_row) 1200 return; 1201 1202 UpdateVisibleRowCount (); 1203 1204 if (first_visible_row == old_first_visible_row) 1205 return; 1206 1207 ScrollToRow (old_first_visible_row, first_visible_row); 1208 } 1209 HitTest(Point position)1210 public HitTestInfo HitTest (Point position) 1211 { 1212 return HitTest (position.X, position.Y); 1213 } 1214 1215 const int RESIZE_HANDLE_HORIZ_SIZE = 5; 1216 const int RESIZE_HANDLE_VERT_SIZE = 3; 1217 1218 // From Point to Cell HitTest(int x, int y)1219 public HitTestInfo HitTest (int x, int y) 1220 { 1221 if (column_headers_area.Contains (x, y)) { 1222 int offset_x = x + horiz_pixeloffset; 1223 int column_x; 1224 int column_under_mouse = FromPixelToColumn (offset_x, out column_x); 1225 1226 if (column_under_mouse == -1) 1227 return new HitTestInfo (-1, -1, HitTestType.None); 1228 1229 if ((column_x + CurrentTableStyle.GridColumnStyles[column_under_mouse].Width - offset_x < RESIZE_HANDLE_HORIZ_SIZE) 1230 && column_under_mouse < CurrentTableStyle.GridColumnStyles.Count) { 1231 1232 return new HitTestInfo (-1, column_under_mouse, HitTestType.ColumnResize); 1233 } 1234 else { 1235 return new HitTestInfo (-1, column_under_mouse, HitTestType.ColumnHeader); 1236 } 1237 } 1238 1239 if (row_headers_area.Contains (x, y)) { 1240 int posy; 1241 int rcnt = FirstVisibleRow + VisibleRowCount; 1242 for (int r = FirstVisibleRow; r < rcnt; r++) { 1243 posy = cells_area.Y + rows[r].VerticalOffset - rows[FirstVisibleRow].VerticalOffset; 1244 if (y <= posy + rows[r].Height) { 1245 if ((posy + rows[r].Height) - y < RESIZE_HANDLE_VERT_SIZE) { 1246 return new HitTestInfo (r, -1, HitTestType.RowResize); 1247 } 1248 else { 1249 return new HitTestInfo (r, -1, HitTestType.RowHeader); 1250 } 1251 } 1252 } 1253 } 1254 1255 if (caption_area.Contains (x, y)) { 1256 return new HitTestInfo (-1, -1, HitTestType.Caption); 1257 } 1258 1259 if (parent_rows.Contains (x, y)) { 1260 return new HitTestInfo (-1, -1, HitTestType.ParentRows); 1261 } 1262 1263 int pos_y, pos_x, width; 1264 int rowcnt = FirstVisibleRow + VisibleRowCount; 1265 for (int row = FirstVisibleRow; row < rowcnt; row++) { 1266 1267 pos_y = cells_area.Y + rows[row].VerticalOffset - rows[FirstVisibleRow].VerticalOffset; 1268 if (y <= pos_y + rows[row].Height) { 1269 int col_pixel; 1270 int column_cnt = first_visible_column + visible_column_count; 1271 if (column_cnt > 0) { 1272 for (int column = first_visible_column; column < column_cnt; column++) { 1273 if (CurrentTableStyle.GridColumnStyles[column].bound == false) 1274 continue; 1275 col_pixel = GetColumnStartingPixel (column); 1276 pos_x = cells_area.X + col_pixel - horiz_pixeloffset; 1277 width = CurrentTableStyle.GridColumnStyles[column].Width; 1278 1279 if (x <= pos_x + width) { // Column found 1280 return new HitTestInfo (row, column, HitTestType.Cell); 1281 } 1282 } 1283 } 1284 else if (CurrentTableStyle.HasRelations) { 1285 /* XXX this needs checking against MS somehow... */ 1286 if (x < rows[row].relation_area.X + rows[row].relation_area.Width) 1287 return new HitTestInfo (row, 0/*XXX?*/, HitTestType.Cell); 1288 } 1289 1290 break; 1291 } 1292 } 1293 1294 return new HitTestInfo (); 1295 } 1296 IsExpanded(int rowNumber)1297 public bool IsExpanded (int rowNumber) 1298 { 1299 return (rows[rowNumber].IsExpanded); 1300 } 1301 IsSelected(int row)1302 public bool IsSelected (int row) 1303 { 1304 return rows[row].IsSelected; 1305 } 1306 NavigateBack()1307 public void NavigateBack () 1308 { 1309 if (data_source_stack.Count == 0) 1310 return; 1311 1312 EndEdit (); 1313 1314 DataGridDataSource source = (DataGridDataSource)data_source_stack.Pop (); 1315 CurrentTableStyle= (DataGridTableStyle)data_grid_table_style_stack.Pop (); 1316 grid_style = (DataGridTableStyle) grid_style_stack.Pop (); 1317 1318 list_manager = source.list_manager; 1319 rows = source.Rows; 1320 selected_rows = source.SelectedRows; 1321 selection_start = source.SelectionStart; 1322 SetDataSource (source.data_source, source.data_member); 1323 1324 CurrentCell = source.current; 1325 } 1326 NavigateTo(int rowNumber, string relationName)1327 public void NavigateTo (int rowNumber, string relationName) 1328 { 1329 if (allow_navigation == false) 1330 return; 1331 1332 EndEdit (); 1333 1334 DataGridDataSource previous_source = new DataGridDataSource (this, list_manager, datasource, datamember, list_manager.Current, CurrentCell); 1335 previous_source.Rows = rows; 1336 previous_source.SelectedRows = selected_rows; 1337 previous_source.SelectionStart = selection_start; 1338 1339 data_source_stack.Push (previous_source); 1340 1341 data_grid_table_style_stack.Push (CurrentTableStyle); 1342 grid_style_stack.Push (grid_style); 1343 grid_style = new DataGridTableStyle (); 1344 CurrentTableStyle = grid_style; 1345 1346 rows = null; 1347 selected_rows = new Hashtable (); 1348 selection_start = -1; 1349 1350 DataMember = String.Format ("{0}.{1}", DataMember, relationName); 1351 OnDataSourceChanged (EventArgs.Empty); 1352 } 1353 OnAllowNavigationChanged(EventArgs e)1354 protected virtual void OnAllowNavigationChanged (EventArgs e) 1355 { 1356 EventHandler eh = (EventHandler)(Events [AllowNavigationChangedEvent]); 1357 if (eh != null) 1358 eh (this, e); 1359 } 1360 OnBackButtonClicked(object sender, EventArgs e)1361 protected void OnBackButtonClicked (object sender, EventArgs e) 1362 { 1363 EventHandler eh = (EventHandler)(Events [BackButtonClickEvent]); 1364 if (eh != null) 1365 eh (this, e); 1366 } 1367 OnBackColorChanged(EventArgs e)1368 protected override void OnBackColorChanged (EventArgs e) 1369 { 1370 base.OnBackColorChanged (e); 1371 } 1372 OnBackgroundColorChanged(EventArgs e)1373 protected virtual void OnBackgroundColorChanged (EventArgs e) 1374 { 1375 EventHandler eh = (EventHandler)(Events [BackgroundColorChangedEvent]); 1376 if (eh != null) 1377 eh (this, e); 1378 } 1379 OnBindingContextChanged(EventArgs e)1380 protected override void OnBindingContextChanged (EventArgs e) 1381 { 1382 base.OnBindingContextChanged (e); 1383 1384 SetDataSource (datasource, datamember); 1385 } 1386 OnBorderStyleChanged(EventArgs e)1387 protected virtual void OnBorderStyleChanged (EventArgs e) 1388 { 1389 EventHandler eh = (EventHandler)(Events [BorderStyleChangedEvent]); 1390 if (eh != null) 1391 eh (this, e); 1392 } 1393 OnCaptionVisibleChanged(EventArgs e)1394 protected virtual void OnCaptionVisibleChanged (EventArgs e) 1395 { 1396 EventHandler eh = (EventHandler)(Events [CaptionVisibleChangedEvent]); 1397 if (eh != null) 1398 eh (this, e); 1399 } 1400 OnCurrentCellChanged(EventArgs e)1401 protected virtual void OnCurrentCellChanged (EventArgs e) 1402 { 1403 EventHandler eh = (EventHandler)(Events [CurrentCellChangedEvent]); 1404 if (eh != null) 1405 eh (this, e); 1406 } 1407 OnDataSourceChanged(EventArgs e)1408 protected virtual void OnDataSourceChanged (EventArgs e) 1409 { 1410 EventHandler eh = (EventHandler)(Events [DataSourceChangedEvent]); 1411 if (eh != null) 1412 eh (this, e); 1413 } 1414 OnEnter(EventArgs e)1415 protected override void OnEnter (EventArgs e) 1416 { 1417 base.OnEnter (e); 1418 Edit (); 1419 } 1420 OnFlatModeChanged(EventArgs e)1421 protected virtual void OnFlatModeChanged (EventArgs e) 1422 { 1423 EventHandler eh = (EventHandler)(Events [FlatModeChangedEvent]); 1424 if (eh != null) 1425 eh (this, e); 1426 } 1427 OnFontChanged(EventArgs e)1428 protected override void OnFontChanged (EventArgs e) 1429 { 1430 CalcGridAreas (); 1431 base.OnFontChanged (e); 1432 } 1433 OnForeColorChanged(EventArgs e)1434 protected override void OnForeColorChanged (EventArgs e) 1435 { 1436 base.OnForeColorChanged (e); 1437 } 1438 OnHandleCreated(EventArgs e)1439 protected override void OnHandleCreated (EventArgs e) 1440 { 1441 base.OnHandleCreated (e); 1442 SetDataSource (datasource, datamember); 1443 } 1444 OnHandleDestroyed(EventArgs e)1445 protected override void OnHandleDestroyed (EventArgs e) 1446 { 1447 base.OnHandleDestroyed (e); 1448 } 1449 1450 // It seems we have repeated code with ProcessKeyPreview, specifically 1451 // the call to ProcessGridKey. In practice it seems this event is *never* fired 1452 // since the key events are handled by the current column's textbox. 1453 // We are keeping commented anyway, in case we need to actually call it. OnKeyDown(KeyEventArgs ke)1454 protected override void OnKeyDown (KeyEventArgs ke) 1455 { 1456 base.OnKeyDown (ke); 1457 1458 /*if (ProcessGridKey (ke) == true) 1459 ke.Handled = true; 1460 1461 // TODO: we probably don't need this check, 1462 // since current_cell wouldn't have been set 1463 // to something invalid 1464 if (CurrentTableStyle.GridColumnStyles.Count > 0) { 1465 CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].OnKeyDown 1466 (ke, current_cell.RowNumber, current_cell.ColumnNumber); 1467 }*/ 1468 } 1469 OnKeyPress(KeyPressEventArgs kpe)1470 protected override void OnKeyPress (KeyPressEventArgs kpe) 1471 { 1472 base.OnKeyPress (kpe); 1473 } 1474 OnLayout(LayoutEventArgs levent)1475 protected override void OnLayout (LayoutEventArgs levent) 1476 { 1477 base.OnLayout (levent); 1478 CalcAreasAndInvalidate (); 1479 } 1480 OnLeave(EventArgs e)1481 protected override void OnLeave (EventArgs e) 1482 { 1483 base.OnLeave (e); 1484 1485 EndEdit (); 1486 if (commit_row_changes) 1487 ListManager.EndCurrentEdit (); 1488 else 1489 ListManager.CancelCurrentEdit (); 1490 } 1491 OnMouseDown(MouseEventArgs e)1492 protected override void OnMouseDown (MouseEventArgs e) 1493 { 1494 base.OnMouseDown (e); 1495 1496 bool ctrl_pressed = ((Control.ModifierKeys & Keys.Control) != 0); 1497 bool shift_pressed = ((Control.ModifierKeys & Keys.Shift) != 0); 1498 1499 HitTestInfo testinfo; 1500 testinfo = HitTest (e.X, e.Y); 1501 1502 switch (testinfo.Type) { 1503 case HitTestType.Cell: 1504 if (testinfo.Row < 0 || testinfo.Column < 0) 1505 break; 1506 1507 if (rows[testinfo.Row].IsExpanded) { 1508 Rectangle relation_area = rows[testinfo.Row].relation_area; 1509 relation_area.Y = rows[testinfo.Row].VerticalOffset + cells_area.Y + rows[testinfo.Row].Height - rows[testinfo.Row].RelationHeight; 1510 if (relation_area.Contains (e.X, e.Y)) { 1511 /* the click happened in the relation area, navigate to the new table */ 1512 int relative = e.Y - relation_area.Y; 1513 NavigateTo (testinfo.Row, CurrentTableStyle.Relations[relative / LinkFont.Height]); 1514 return; 1515 } 1516 } 1517 1518 DataGridCell new_cell = new DataGridCell (testinfo.Row, testinfo.Column); 1519 1520 if ((new_cell.Equals (current_cell) == false) || (!is_editing)) { 1521 ResetSelection (); 1522 CurrentCell = new_cell; 1523 Edit (); 1524 } else { 1525 CurrentTableStyle.GridColumnStyles[testinfo.Column].OnMouseDown (e, testinfo.Row, testinfo.Column); 1526 } 1527 1528 break; 1529 1530 case HitTestType.RowHeader: 1531 bool expansion_click = false; 1532 if (CurrentTableStyle.HasRelations) { 1533 if (e.X > row_headers_area.X + row_headers_area.Width / 2) { 1534 /* it's in the +/- space */ 1535 if (IsExpanded (testinfo.Row)) 1536 Collapse (testinfo.Row); 1537 else 1538 Expand (testinfo.Row); 1539 1540 expansion_click = true; 1541 } 1542 } 1543 1544 CancelEditing (); 1545 CurrentRow = testinfo.Row; 1546 1547 if (!ctrl_pressed && !shift_pressed && !expansion_click) { 1548 ResetSelection (); // Invalidates selected rows 1549 } 1550 1551 if ((shift_pressed || expansion_click) && selection_start != -1) { 1552 ShiftSelection (testinfo.Row); 1553 } else { // ctrl_pressed or single item 1554 selection_start = testinfo.Row; 1555 Select (testinfo.Row); 1556 } 1557 1558 OnRowHeaderClick (EventArgs.Empty); 1559 1560 break; 1561 1562 case HitTestType.ColumnHeader: 1563 if (CurrentTableStyle.GridColumnStyles.Count == 0) 1564 break; 1565 1566 if (AllowSorting == false) 1567 break; 1568 1569 if (ListManager.List is IBindingList == false) 1570 break; 1571 1572 // Don't do any sort if we are empty, as .net does 1573 if (ListManager.Count == 0) 1574 return; 1575 1576 ListSortDirection direction = ListSortDirection.Ascending; 1577 PropertyDescriptor prop = CurrentTableStyle.GridColumnStyles[testinfo.Column].PropertyDescriptor; 1578 IBindingList list = (IBindingList) ListManager.List; 1579 1580 if (list.SortProperty != null) { 1581 CurrentTableStyle.GridColumnStyles[list.SortProperty].ArrowDrawingMode 1582 = DataGridColumnStyle.ArrowDrawing.No; 1583 } 1584 1585 if (prop == list.SortProperty && list.SortDirection == ListSortDirection.Ascending) { 1586 direction = ListSortDirection.Descending; 1587 } 1588 1589 CurrentTableStyle.GridColumnStyles[testinfo.Column].ArrowDrawingMode = 1590 direction == ListSortDirection.Ascending ? 1591 DataGridColumnStyle.ArrowDrawing.Ascending : DataGridColumnStyle.ArrowDrawing.Descending; 1592 1593 list.ApplySort (prop, direction); 1594 Refresh (); 1595 if (this.is_editing) 1596 //CurrentTableStyle.GridColumnStyles[CurrentColumn].UpdateUI (); 1597 this.InvalidateColumn (CurrentTableStyle.GridColumnStyles[CurrentColumn]); 1598 1599 break; 1600 1601 case HitTestType.ColumnResize: 1602 if (e.Clicks == 2) { 1603 EndEdit (); 1604 ColumnResize (testinfo.Column); 1605 } else { 1606 resize_column = testinfo.Column; 1607 column_resize_active = true; 1608 resize_column_x = e.X; 1609 resize_column_width_delta = 0; 1610 EndEdit (); 1611 DrawResizeLineVert (resize_column_x); 1612 } 1613 break; 1614 1615 case HitTestType.RowResize: 1616 if (e.Clicks == 2) { 1617 EndEdit (); 1618 RowResize (testinfo.Row); 1619 } else { 1620 resize_row = testinfo.Row; 1621 row_resize_active = true; 1622 resize_row_y = e.Y; 1623 resize_row_height_delta = 0; 1624 EndEdit (); 1625 DrawResizeLineHoriz (resize_row_y); 1626 } 1627 break; 1628 1629 case HitTestType.Caption: 1630 if (back_button_rect.Contains (e.X, e.Y)) { 1631 back_button_active = true; 1632 Invalidate (back_button_rect); 1633 } 1634 if (parent_rows_button_rect.Contains (e.X, e.Y)) { 1635 parent_rows_button_active = true; 1636 Invalidate (parent_rows_button_rect); 1637 } 1638 break; 1639 1640 default: 1641 break; 1642 } 1643 } 1644 OnMouseLeave(EventArgs e)1645 protected override void OnMouseLeave (EventArgs e) 1646 { 1647 base.OnMouseLeave (e); 1648 } 1649 OnMouseMove(MouseEventArgs e)1650 protected override void OnMouseMove (MouseEventArgs e) 1651 { 1652 base.OnMouseMove (e); 1653 1654 if (column_resize_active) { 1655 /* erase the old line */ 1656 DrawResizeLineVert (resize_column_x + resize_column_width_delta); 1657 1658 resize_column_width_delta = e.X - resize_column_x; 1659 1660 /* draw the new line */ 1661 DrawResizeLineVert (resize_column_x + resize_column_width_delta); 1662 return; 1663 } 1664 else if (row_resize_active) { 1665 /* erase the old line */ 1666 DrawResizeLineHoriz (resize_row_y + resize_row_height_delta); 1667 1668 resize_row_height_delta = e.Y - resize_row_y; 1669 1670 /* draw the new line */ 1671 DrawResizeLineHoriz (resize_row_y + resize_row_height_delta); 1672 return; 1673 } 1674 else { 1675 /* determine the cursor to use */ 1676 HitTestInfo testinfo; 1677 testinfo = HitTest (e.X, e.Y); 1678 1679 switch (testinfo.Type) { 1680 case HitTestType.ColumnResize: 1681 Cursor = Cursors.VSplit; 1682 break; 1683 case HitTestType.RowResize: 1684 Cursor = Cursors.HSplit; 1685 break; 1686 case HitTestType.Caption: 1687 Cursor = Cursors.Default; 1688 if (back_button_rect.Contains (e.X, e.Y)) { 1689 if (!back_button_mouseover) 1690 Invalidate (back_button_rect); 1691 back_button_mouseover = true; 1692 } else if (back_button_mouseover) { 1693 Invalidate (back_button_rect); 1694 back_button_mouseover = false; 1695 } 1696 1697 if (parent_rows_button_rect.Contains (e.X, e.Y)) { 1698 if (parent_rows_button_mouseover) 1699 Invalidate (parent_rows_button_rect); 1700 parent_rows_button_mouseover = true; 1701 } else if (parent_rows_button_mouseover) { 1702 Invalidate (parent_rows_button_rect); 1703 parent_rows_button_mouseover = false; 1704 } 1705 break; 1706 case HitTestType.Cell: 1707 if (rows[testinfo.Row].IsExpanded) { 1708 Rectangle relation_area = rows[testinfo.Row].relation_area; 1709 relation_area.Y = rows[testinfo.Row].VerticalOffset + cells_area.Y + rows[testinfo.Row].Height - rows[testinfo.Row].RelationHeight; 1710 if (relation_area.Contains (e.X, e.Y)) { 1711 Cursor = Cursors.Hand; 1712 break; 1713 } 1714 } 1715 1716 Cursor = Cursors.Default; 1717 break; 1718 case HitTestType.RowHeader: 1719 if (e.Button == MouseButtons.Left) 1720 ShiftSelection (testinfo.Row); 1721 1722 Cursor = Cursors.Default; 1723 break; 1724 default: 1725 Cursor = Cursors.Default; 1726 break; 1727 } 1728 } 1729 } 1730 OnMouseUp(MouseEventArgs e)1731 protected override void OnMouseUp (MouseEventArgs e) 1732 { 1733 base.OnMouseUp (e); 1734 1735 if (column_resize_active) { 1736 column_resize_active = false; 1737 if (resize_column_width_delta + CurrentTableStyle.GridColumnStyles[resize_column].Width < 0) 1738 resize_column_width_delta = -CurrentTableStyle.GridColumnStyles[resize_column].Width; 1739 CurrentTableStyle.GridColumnStyles[resize_column].Width += resize_column_width_delta; 1740 width_of_all_columns += resize_column_width_delta; 1741 Edit (); 1742 Invalidate (); 1743 } else if (row_resize_active) { 1744 row_resize_active = false; 1745 1746 if (resize_row_height_delta + rows[resize_row].Height < 0) 1747 resize_row_height_delta = -rows[resize_row].Height; 1748 1749 rows[resize_row].height = rows[resize_row].Height + resize_row_height_delta; 1750 for (int i = resize_row + 1; i < rows.Length; i ++) 1751 rows[i].VerticalOffset += resize_row_height_delta; 1752 1753 Edit (); 1754 CalcAreasAndInvalidate (); 1755 } else if (back_button_active) { 1756 if (back_button_rect.Contains (e.X, e.Y)) { 1757 Invalidate (back_button_rect); 1758 NavigateBack (); 1759 OnBackButtonClicked (this, EventArgs.Empty); 1760 } 1761 back_button_active = false; 1762 } else if (parent_rows_button_active) { 1763 if (parent_rows_button_rect.Contains (e.X, e.Y)) { 1764 Invalidate (parent_rows_button_rect); 1765 ParentRowsVisible = !ParentRowsVisible; 1766 OnShowParentDetailsButtonClicked (this, EventArgs.Empty); 1767 } 1768 parent_rows_button_active = false; 1769 } 1770 } 1771 OnMouseWheel(MouseEventArgs e)1772 protected override void OnMouseWheel (MouseEventArgs e) 1773 { 1774 base.OnMouseWheel (e); 1775 1776 bool ctrl_pressed = ((Control.ModifierKeys & Keys.Control) != 0); 1777 int pixels; 1778 1779 if (ctrl_pressed) { // scroll horizontally 1780 if (!horiz_scrollbar.Visible) 1781 return; 1782 1783 if (e.Delta > 0) { 1784 /* left */ 1785 pixels = Math.Max (horiz_scrollbar.Minimum, 1786 horiz_scrollbar.Value - horiz_scrollbar.LargeChange); 1787 } else { 1788 /* right */ 1789 pixels = Math.Min (horiz_scrollbar.Maximum - horiz_scrollbar.LargeChange + 1, 1790 horiz_scrollbar.Value + horiz_scrollbar.LargeChange); 1791 } 1792 1793 GridHScrolled (this, new ScrollEventArgs (ScrollEventType.ThumbPosition, pixels)); 1794 horiz_scrollbar.Value = pixels; 1795 } else { 1796 if (!vert_scrollbar.Visible) 1797 return; 1798 1799 if (e.Delta > 0) { 1800 /* up */ 1801 pixels = Math.Max (vert_scrollbar.Minimum, 1802 vert_scrollbar.Value - vert_scrollbar.LargeChange); 1803 } else { 1804 /* down */ 1805 pixels = Math.Min (vert_scrollbar.Maximum - vert_scrollbar.LargeChange + 1, 1806 vert_scrollbar.Value + vert_scrollbar.LargeChange); 1807 } 1808 1809 GridVScrolled (this, new ScrollEventArgs (ScrollEventType.ThumbPosition, pixels)); 1810 vert_scrollbar.Value = pixels; 1811 } 1812 } 1813 OnNavigate(NavigateEventArgs e)1814 protected void OnNavigate (NavigateEventArgs e) 1815 { 1816 EventHandler eh = (EventHandler)(Events [NavigateEvent]); 1817 if (eh != null) 1818 eh (this, e); 1819 } 1820 OnPaint(PaintEventArgs pe)1821 protected override void OnPaint (PaintEventArgs pe) 1822 { 1823 ThemeEngine.Current.DataGridPaint (pe, this); 1824 } 1825 OnPaintBackground(PaintEventArgs ebe)1826 protected override void OnPaintBackground (PaintEventArgs ebe) 1827 { 1828 } 1829 OnParentRowsLabelStyleChanged(EventArgs e)1830 protected virtual void OnParentRowsLabelStyleChanged (EventArgs e) 1831 { 1832 EventHandler eh = (EventHandler)(Events [ParentRowsLabelStyleChangedEvent]); 1833 if (eh != null) 1834 eh (this, e); 1835 } 1836 OnParentRowsVisibleChanged(EventArgs e)1837 protected virtual void OnParentRowsVisibleChanged (EventArgs e) 1838 { 1839 EventHandler eh = (EventHandler)(Events [ParentRowsVisibleChangedEvent]); 1840 if (eh != null) 1841 eh (this, e); 1842 } 1843 OnReadOnlyChanged(EventArgs e)1844 protected virtual void OnReadOnlyChanged (EventArgs e) 1845 { 1846 EventHandler eh = (EventHandler)(Events [ReadOnlyChangedEvent]); 1847 if (eh != null) 1848 eh (this, e); 1849 } 1850 OnResize(EventArgs e)1851 protected override void OnResize (EventArgs e) 1852 { 1853 base.OnResize (e); 1854 } 1855 OnRowHeaderClick(EventArgs e)1856 protected void OnRowHeaderClick (EventArgs e) 1857 { 1858 EventHandler eh = (EventHandler)(Events [RowHeaderClickEvent]); 1859 if (eh != null) 1860 eh (this, e); 1861 } 1862 OnScroll(EventArgs e)1863 protected void OnScroll (EventArgs e) 1864 { 1865 EventHandler eh = (EventHandler)(Events [ScrollEvent]); 1866 if (eh != null) 1867 eh (this, e); 1868 } 1869 OnShowParentDetailsButtonClicked(object sender, EventArgs e)1870 protected void OnShowParentDetailsButtonClicked (object sender, EventArgs e) 1871 { 1872 EventHandler eh = (EventHandler)(Events [ShowParentDetailsButtonClickEvent]); 1873 if (eh != null) 1874 eh (this, e); 1875 } 1876 ProcessDialogKey(Keys keyData)1877 protected override bool ProcessDialogKey (Keys keyData) 1878 { 1879 return ProcessGridKey (new KeyEventArgs (keyData)); 1880 } 1881 UpdateSelectionAfterCursorMove(bool extend_selection)1882 void UpdateSelectionAfterCursorMove (bool extend_selection) 1883 { 1884 if (extend_selection) { 1885 CancelEditing (); 1886 ShiftSelection (CurrentRow); 1887 } else { 1888 ResetSelection (); 1889 selection_start = CurrentRow; 1890 } 1891 } 1892 ProcessGridKey(KeyEventArgs ke)1893 protected bool ProcessGridKey (KeyEventArgs ke) 1894 { 1895 bool ctrl_pressed = ((ke.Modifiers & Keys.Control) != 0); 1896 //bool alt_pressed = ((ke.Modifiers & Keys.Alt) != 0); 1897 bool shift_pressed = ((ke.Modifiers & Keys.Shift) != 0); 1898 1899 switch (ke.KeyCode) { 1900 case Keys.Escape: 1901 if (is_changing) 1902 AbortEditing (); 1903 else { 1904 CancelEditing (); 1905 1906 if (cursor_in_add_row && CurrentRow > 0) 1907 CurrentRow--; 1908 } 1909 1910 Edit (); 1911 return true; 1912 1913 case Keys.D0: 1914 if (ctrl_pressed) { 1915 if (is_editing) 1916 CurrentTableStyle.GridColumnStyles[CurrentColumn].EnterNullValue (); 1917 return true; 1918 } 1919 return false; 1920 1921 case Keys.Enter: 1922 if (is_changing) 1923 CurrentRow ++; 1924 return true; 1925 1926 case Keys.Tab: 1927 if (shift_pressed) { 1928 if (CurrentColumn > 0) 1929 CurrentColumn --; 1930 else if ((CurrentRow > 0) && (CurrentColumn == 0)) 1931 CurrentCell = new DataGridCell (CurrentRow - 1, CurrentTableStyle.GridColumnStyles.Count - 1); 1932 } else { 1933 if (CurrentColumn < CurrentTableStyle.GridColumnStyles.Count - 1) 1934 CurrentColumn ++; 1935 else if ((CurrentRow <= RowsCount) && (CurrentColumn == CurrentTableStyle.GridColumnStyles.Count - 1)) 1936 CurrentCell = new DataGridCell (CurrentRow + 1, 0); 1937 } 1938 1939 UpdateSelectionAfterCursorMove (false); 1940 1941 return true; 1942 1943 case Keys.Right: 1944 if (ctrl_pressed) { 1945 CurrentColumn = CurrentTableStyle.GridColumnStyles.Count - 1; 1946 } else { 1947 if (CurrentColumn < CurrentTableStyle.GridColumnStyles.Count - 1) { 1948 CurrentColumn ++; 1949 } else if (CurrentRow < RowsCount - 1 1950 || (CurrentRow == RowsCount - 1 1951 && !cursor_in_add_row)) { 1952 CurrentCell = new DataGridCell (CurrentRow + 1, 0); 1953 } 1954 } 1955 1956 UpdateSelectionAfterCursorMove (false); 1957 1958 return true; 1959 1960 case Keys.Left: 1961 if (ctrl_pressed) { 1962 CurrentColumn = 0; 1963 } else { 1964 if (current_cell.ColumnNumber > 0) 1965 CurrentColumn --; 1966 else if (CurrentRow > 0) 1967 CurrentCell = new DataGridCell (CurrentRow - 1, CurrentTableStyle.GridColumnStyles.Count - 1); 1968 } 1969 1970 UpdateSelectionAfterCursorMove (false); 1971 1972 return true; 1973 1974 case Keys.Up: 1975 if (ctrl_pressed) 1976 CurrentRow = 0; 1977 else if (CurrentRow > 0) 1978 CurrentRow --; 1979 1980 UpdateSelectionAfterCursorMove (shift_pressed); 1981 1982 return true; 1983 1984 case Keys.Down: 1985 if (ctrl_pressed) 1986 CurrentRow = RowsCount - 1; 1987 else if (CurrentRow < RowsCount - 1) 1988 CurrentRow ++; 1989 else if (CurrentRow == RowsCount - 1 && cursor_in_add_row && (add_row_changed || is_changing)) 1990 CurrentRow ++; 1991 else if (CurrentRow == RowsCount - 1 && !cursor_in_add_row && !shift_pressed) 1992 CurrentRow ++; 1993 1994 UpdateSelectionAfterCursorMove (shift_pressed); 1995 1996 return true; 1997 1998 case Keys.PageUp: 1999 if (CurrentRow > VLargeChange) 2000 CurrentRow -= VLargeChange; 2001 else 2002 CurrentRow = 0; 2003 2004 UpdateSelectionAfterCursorMove (shift_pressed); 2005 2006 return true; 2007 2008 case Keys.PageDown: 2009 if (CurrentRow < RowsCount - VLargeChange) 2010 CurrentRow += VLargeChange; 2011 else 2012 CurrentRow = RowsCount - 1; 2013 2014 UpdateSelectionAfterCursorMove (shift_pressed); 2015 2016 return true; 2017 2018 case Keys.Home: 2019 if (ctrl_pressed) 2020 CurrentCell = new DataGridCell (0, 0); 2021 else 2022 CurrentColumn = 0; 2023 2024 UpdateSelectionAfterCursorMove (ctrl_pressed && shift_pressed); 2025 2026 return true; 2027 2028 case Keys.End: 2029 if (ctrl_pressed) 2030 CurrentCell = new DataGridCell (RowsCount - 1, CurrentTableStyle.GridColumnStyles.Count - 1); 2031 else 2032 CurrentColumn = CurrentTableStyle.GridColumnStyles.Count - 1; 2033 2034 UpdateSelectionAfterCursorMove (ctrl_pressed && shift_pressed); 2035 2036 return true; 2037 2038 case Keys.Delete: 2039 if (is_editing) 2040 return false; 2041 else if (selected_rows.Keys.Count > 0) { 2042 // the removal of the items in the source will cause to 2043 // reset the selection, so we need a copy of it. 2044 int [] rows = new int [selected_rows.Keys.Count]; 2045 selected_rows.Keys.CopyTo (rows, 0); 2046 2047 // reverse order to keep index sanity 2048 int edit_row_index = ShowEditRow ? RowsCount : -1; // new cell is +1 2049 for (int i = rows.Length - 1; i >= 0; i--) 2050 if (rows [i] != edit_row_index) 2051 ListManager.RemoveAt (rows [i]); 2052 2053 CalcAreasAndInvalidate (); 2054 } 2055 2056 return true; 2057 } 2058 2059 return false; // message not processed 2060 } 2061 ProcessKeyPreview(ref Message m)2062 protected override bool ProcessKeyPreview (ref Message m) 2063 { 2064 if ((Msg) m.Msg == Msg.WM_KEYDOWN) { 2065 Keys key = (Keys) m.WParam.ToInt32 (); 2066 KeyEventArgs ke = new KeyEventArgs (key | XplatUI.State.ModifierKeys); 2067 if (ProcessGridKey (ke)) 2068 return true; 2069 2070 // if we receive a key event, make sure that input is actually 2071 // taken into account. 2072 if (!is_editing) { 2073 Edit (); 2074 InvalidateRow (current_cell.RowNumber); 2075 return true; 2076 } 2077 } 2078 2079 return base.ProcessKeyPreview (ref m); 2080 } 2081 ProcessTabKey(Keys keyData)2082 protected bool ProcessTabKey (Keys keyData) 2083 { 2084 return false; 2085 } 2086 ResetAlternatingBackColor()2087 public void ResetAlternatingBackColor () 2088 { 2089 grid_style.AlternatingBackColor = default_style.AlternatingBackColor; 2090 } 2091 ResetBackColor()2092 public override void ResetBackColor () 2093 { 2094 grid_style.BackColor = default_style.BackColor; 2095 } 2096 ResetForeColor()2097 public override void ResetForeColor () 2098 { 2099 grid_style.ForeColor = default_style.ForeColor; 2100 } 2101 ResetGridLineColor()2102 public void ResetGridLineColor () 2103 { 2104 grid_style.GridLineColor = default_style.GridLineColor; 2105 } 2106 ResetHeaderBackColor()2107 public void ResetHeaderBackColor () 2108 { 2109 grid_style.HeaderBackColor = default_style.HeaderBackColor; 2110 } 2111 ResetHeaderFont()2112 public void ResetHeaderFont () 2113 { 2114 grid_style.HeaderFont = null; 2115 } 2116 ResetHeaderForeColor()2117 public void ResetHeaderForeColor () 2118 { 2119 grid_style.HeaderForeColor = default_style.HeaderForeColor; 2120 } 2121 ResetLinkColor()2122 public void ResetLinkColor () 2123 { 2124 grid_style.LinkColor = default_style.LinkColor; 2125 } 2126 ResetLinkHoverColor()2127 public void ResetLinkHoverColor () 2128 { 2129 grid_style.LinkHoverColor = default_style.LinkHoverColor; 2130 } 2131 ResetSelection()2132 protected void ResetSelection () 2133 { 2134 InvalidateSelection (); 2135 selected_rows.Clear (); 2136 selection_start = -1; 2137 } 2138 InvalidateSelection()2139 void InvalidateSelection () 2140 { 2141 foreach (int row in selected_rows.Keys) { 2142 rows[row].IsSelected = false; 2143 InvalidateRow (row); 2144 } 2145 } 2146 ResetSelectionBackColor()2147 public void ResetSelectionBackColor () 2148 { 2149 grid_style.SelectionBackColor = default_style.SelectionBackColor; 2150 } 2151 ResetSelectionForeColor()2152 public void ResetSelectionForeColor () 2153 { 2154 grid_style.SelectionForeColor = default_style.SelectionForeColor; 2155 } 2156 Select(int row)2157 public void Select (int row) 2158 { 2159 EndEdit(); 2160 2161 if (selected_rows.Count == 0) 2162 selection_start = row; 2163 2164 // UIA Framework: To raise event only when selecting 2165 bool wasSelected = rows [row].IsSelected; 2166 2167 selected_rows[row] = true; 2168 rows[row].IsSelected = true; 2169 2170 InvalidateRow (row); 2171 2172 // UIA Framework: 2173 if (!wasSelected) 2174 OnUIASelectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Add, row)); 2175 2176 } 2177 SetDataBinding(object dataSource, string dataMember)2178 public void SetDataBinding (object dataSource, string dataMember) 2179 { 2180 SetDataSource (dataSource, dataMember); 2181 } 2182 ShouldSerializeAlternatingBackColor()2183 protected virtual bool ShouldSerializeAlternatingBackColor () 2184 { 2185 return (grid_style.AlternatingBackColor != default_style.AlternatingBackColor); 2186 } 2187 ShouldSerializeBackgroundColor()2188 protected virtual bool ShouldSerializeBackgroundColor () 2189 { 2190 return (background_color != def_background_color); 2191 } 2192 ShouldSerializeCaptionBackColor()2193 protected virtual bool ShouldSerializeCaptionBackColor () 2194 { 2195 return (caption_backcolor != def_caption_backcolor); 2196 } 2197 ShouldSerializeCaptionForeColor()2198 protected virtual bool ShouldSerializeCaptionForeColor () 2199 { 2200 return caption_forecolor != def_caption_forecolor; 2201 } 2202 ShouldSerializeGridLineColor()2203 protected virtual bool ShouldSerializeGridLineColor () 2204 { 2205 return grid_style.GridLineColor != default_style.GridLineColor; 2206 } 2207 ShouldSerializeHeaderBackColor()2208 protected virtual bool ShouldSerializeHeaderBackColor () 2209 { 2210 return grid_style.HeaderBackColor != default_style.HeaderBackColor; 2211 } 2212 ShouldSerializeHeaderFont()2213 protected bool ShouldSerializeHeaderFont () 2214 { 2215 return grid_style.HeaderFont != default_style.HeaderFont; 2216 } 2217 ShouldSerializeHeaderForeColor()2218 protected virtual bool ShouldSerializeHeaderForeColor () 2219 { 2220 return grid_style.HeaderForeColor != default_style.HeaderForeColor; 2221 } 2222 ShouldSerializeLinkHoverColor()2223 protected virtual bool ShouldSerializeLinkHoverColor () 2224 { 2225 return grid_style.LinkHoverColor != default_style.LinkHoverColor; 2226 } 2227 ShouldSerializeParentRowsBackColor()2228 protected virtual bool ShouldSerializeParentRowsBackColor () 2229 { 2230 return parent_rows_backcolor != def_parent_rows_backcolor; 2231 } 2232 ShouldSerializeParentRowsForeColor()2233 protected virtual bool ShouldSerializeParentRowsForeColor () 2234 { 2235 return parent_rows_backcolor != def_parent_rows_backcolor; 2236 } 2237 ShouldSerializePreferredRowHeight()2238 protected bool ShouldSerializePreferredRowHeight () 2239 { 2240 return grid_style.PreferredRowHeight != default_style.PreferredRowHeight; 2241 } 2242 ShouldSerializeSelectionBackColor()2243 protected bool ShouldSerializeSelectionBackColor () 2244 { 2245 return grid_style.SelectionBackColor != default_style.SelectionBackColor; 2246 } 2247 ShouldSerializeSelectionForeColor()2248 protected virtual bool ShouldSerializeSelectionForeColor () 2249 { 2250 return grid_style.SelectionForeColor != default_style.SelectionForeColor; 2251 } 2252 SubObjectsSiteChange(bool site)2253 public void SubObjectsSiteChange (bool site) 2254 { 2255 } 2256 UnSelect(int row)2257 public void UnSelect (int row) 2258 { 2259 // UIA Framework: To raise event only when unselecting 2260 bool wasSelected = rows [row].IsSelected; 2261 2262 rows[row].IsSelected = false; 2263 selected_rows.Remove (row); 2264 InvalidateRow (row); 2265 2266 // UIA Framework: Raises selection event 2267 if (!wasSelected) 2268 OnUIASelectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Remove, row)); 2269 } 2270 #endregion // Public Instance Methods 2271 2272 #region Private Instance Methods 2273 CalcAreasAndInvalidate()2274 internal void CalcAreasAndInvalidate () 2275 { 2276 CalcGridAreas (); 2277 Invalidate (); 2278 } 2279 ConnectListManagerEvents()2280 private void ConnectListManagerEvents () 2281 { 2282 list_manager.MetaDataChanged += new EventHandler (OnListManagerMetaDataChanged); 2283 list_manager.PositionChanged += new EventHandler (OnListManagerPositionChanged); 2284 list_manager.ItemChanged += new ItemChangedEventHandler (OnListManagerItemChanged); 2285 } 2286 DisconnectListManagerEvents()2287 private void DisconnectListManagerEvents () 2288 { 2289 list_manager.MetaDataChanged -= new EventHandler (OnListManagerMetaDataChanged); 2290 list_manager.PositionChanged -= new EventHandler (OnListManagerPositionChanged); 2291 list_manager.ItemChanged -= new ItemChangedEventHandler (OnListManagerItemChanged); 2292 } 2293 DisconnectTableStyleEvents()2294 void DisconnectTableStyleEvents () 2295 { 2296 current_style.AllowSortingChanged -= new EventHandler (TableStyleChanged); 2297 current_style.AlternatingBackColorChanged -= new EventHandler (TableStyleChanged); 2298 current_style.BackColorChanged -= new EventHandler (TableStyleChanged); 2299 current_style.ColumnHeadersVisibleChanged -= new EventHandler (TableStyleChanged); 2300 current_style.ForeColorChanged -= new EventHandler (TableStyleChanged); 2301 current_style.GridLineColorChanged -= new EventHandler (TableStyleChanged); 2302 current_style.GridLineStyleChanged -= new EventHandler (TableStyleChanged); 2303 current_style.HeaderBackColorChanged -= new EventHandler (TableStyleChanged); 2304 current_style.HeaderFontChanged -= new EventHandler (TableStyleChanged); 2305 current_style.HeaderForeColorChanged -= new EventHandler (TableStyleChanged); 2306 current_style.LinkColorChanged -= new EventHandler (TableStyleChanged); 2307 current_style.LinkHoverColorChanged -= new EventHandler (TableStyleChanged); 2308 current_style.MappingNameChanged -= new EventHandler (TableStyleChanged); 2309 current_style.PreferredColumnWidthChanged -= new EventHandler (TableStyleChanged); 2310 current_style.PreferredRowHeightChanged -= new EventHandler (TableStyleChanged); 2311 current_style.ReadOnlyChanged -= new EventHandler (TableStyleChanged); 2312 current_style.RowHeadersVisibleChanged -= new EventHandler (TableStyleChanged); 2313 current_style.RowHeaderWidthChanged -= new EventHandler (TableStyleChanged); 2314 current_style.SelectionBackColorChanged -= new EventHandler (TableStyleChanged); 2315 current_style.SelectionForeColorChanged -= new EventHandler (TableStyleChanged); 2316 } 2317 ConnectTableStyleEvents()2318 void ConnectTableStyleEvents () 2319 { 2320 current_style.AllowSortingChanged += new EventHandler (TableStyleChanged); 2321 current_style.AlternatingBackColorChanged += new EventHandler (TableStyleChanged); 2322 current_style.BackColorChanged += new EventHandler (TableStyleChanged); 2323 current_style.ColumnHeadersVisibleChanged += new EventHandler (TableStyleChanged); 2324 current_style.ForeColorChanged += new EventHandler (TableStyleChanged); 2325 current_style.GridLineColorChanged += new EventHandler (TableStyleChanged); 2326 current_style.GridLineStyleChanged += new EventHandler (TableStyleChanged); 2327 current_style.HeaderBackColorChanged += new EventHandler (TableStyleChanged); 2328 current_style.HeaderFontChanged += new EventHandler (TableStyleChanged); 2329 current_style.HeaderForeColorChanged += new EventHandler (TableStyleChanged); 2330 current_style.LinkColorChanged += new EventHandler (TableStyleChanged); 2331 current_style.LinkHoverColorChanged += new EventHandler (TableStyleChanged); 2332 current_style.MappingNameChanged += new EventHandler (TableStyleChanged); 2333 current_style.PreferredColumnWidthChanged += new EventHandler (TableStyleChanged); 2334 current_style.PreferredRowHeightChanged += new EventHandler (TableStyleChanged); 2335 current_style.ReadOnlyChanged += new EventHandler (TableStyleChanged); 2336 current_style.RowHeadersVisibleChanged += new EventHandler (TableStyleChanged); 2337 current_style.RowHeaderWidthChanged += new EventHandler (TableStyleChanged); 2338 current_style.SelectionBackColorChanged += new EventHandler (TableStyleChanged); 2339 current_style.SelectionForeColorChanged += new EventHandler (TableStyleChanged); 2340 } 2341 TableStyleChanged(object sender, EventArgs args)2342 void TableStyleChanged (object sender, EventArgs args) 2343 { 2344 EndEdit (); 2345 CalcAreasAndInvalidate (); 2346 } 2347 2348 EnsureCellVisibility(DataGridCell cell)2349 private void EnsureCellVisibility (DataGridCell cell) 2350 { 2351 if (cell.ColumnNumber <= first_visible_column || 2352 cell.ColumnNumber + 1 >= first_visible_column + visible_column_count) { 2353 2354 first_visible_column = GetFirstColumnForColumnVisibility (first_visible_column, cell.ColumnNumber); 2355 int pixel = GetColumnStartingPixel (first_visible_column); 2356 ScrollToColumnInPixels (pixel); 2357 horiz_scrollbar.Value = pixel; 2358 Update(); 2359 } 2360 2361 if (cell.RowNumber < first_visible_row || 2362 cell.RowNumber + 1 >= first_visible_row + visible_row_count) { 2363 2364 if (cell.RowNumber + 1 >= first_visible_row + visible_row_count) { 2365 int old_first_visible_row = first_visible_row; 2366 first_visible_row = 1 + cell.RowNumber - visible_row_count; 2367 UpdateVisibleRowCount (); 2368 ScrollToRow (old_first_visible_row, first_visible_row); 2369 } else { 2370 int old_first_visible_row = first_visible_row; 2371 first_visible_row = cell.RowNumber; 2372 UpdateVisibleRowCount (); 2373 ScrollToRow (old_first_visible_row, first_visible_row); 2374 } 2375 2376 vert_scrollbar.Value = first_visible_row; 2377 } 2378 } 2379 SetDataSource(object source, string member)2380 private void SetDataSource (object source, string member) 2381 { 2382 SetDataSource (source, member, true); 2383 } 2384 2385 bool in_setdatasource; SetDataSource(object source, string member, bool recreate_rows)2386 private void SetDataSource (object source, string member, bool recreate_rows) 2387 { 2388 CurrencyManager old_lm = list_manager; 2389 2390 /* we need this bool flag to work around a 2391 * problem with OnBindingContextChanged. once 2392 * that stuff works properly, remove this 2393 * hack */ 2394 if (in_setdatasource) 2395 return; 2396 in_setdatasource = true; 2397 2398 #if false 2399 if (datasource == source && member == datamember) 2400 return; 2401 #endif 2402 2403 if (source != null && source as IListSource != null && source as IList != null) 2404 throw new Exception ("Wrong complex data binding source"); 2405 2406 datasource = source; 2407 datamember = member; 2408 2409 if (is_editing) 2410 CancelEditing (); 2411 2412 current_cell = new DataGridCell (); 2413 2414 if (list_manager != null) 2415 DisconnectListManagerEvents (); 2416 2417 list_manager = null; 2418 2419 /* create the new list manager */ 2420 if (BindingContext != null && datasource != null) 2421 list_manager = (CurrencyManager) BindingContext [datasource, datamember]; 2422 2423 if (list_manager != null) 2424 ConnectListManagerEvents (); 2425 2426 if (old_lm != list_manager) { 2427 BindColumns (); 2428 2429 /* reset first_visible_row to 0 here before 2430 * doing anything that'll requires us to 2431 * figure out if we need a scrollbar. */ 2432 vert_scrollbar.Value = 0; 2433 horiz_scrollbar.Value = 0; 2434 first_visible_row = 0; 2435 2436 if (recreate_rows) 2437 RecreateDataGridRows (false); 2438 } 2439 2440 CalcAreasAndInvalidate (); 2441 2442 in_setdatasource = false; 2443 2444 OnDataSourceChanged (EventArgs.Empty); 2445 } 2446 RecreateDataGridRows(bool recalc)2447 void RecreateDataGridRows (bool recalc) 2448 { 2449 DataGridRelationshipRow[] new_rows = new DataGridRelationshipRow[RowsCount + (ShowEditRow ? 1 : 0)]; 2450 int start_index = 0; 2451 if (rows != null) { 2452 start_index = rows.Length; 2453 Array.Copy (rows, 0, new_rows, 0, rows.Length < new_rows.Length ? rows.Length : new_rows.Length); 2454 } 2455 2456 for (int i = start_index; i < new_rows.Length; i ++) { 2457 new_rows[i] = new DataGridRelationshipRow (this); 2458 new_rows[i].height = RowHeight; 2459 if (i > 0) 2460 new_rows[i].VerticalOffset = new_rows[i-1].VerticalOffset + new_rows[i-1].Height; 2461 } 2462 2463 // UIA Framework event: Updates collection list depending on binding 2464 CollectionChangeAction action = CollectionChangeAction.Refresh; 2465 if (rows != null) { 2466 if (new_rows.Length - rows.Length > 0) 2467 action = CollectionChangeAction.Add; 2468 else 2469 action = CollectionChangeAction.Remove; 2470 } 2471 rows = new_rows; 2472 2473 if (recalc) 2474 CalcAreasAndInvalidate (); 2475 // UIA Framework event: Row added/removed 2476 OnUIACollectionChangedEvent (new CollectionChangeEventArgs (action, -1)); 2477 } 2478 UpdateRowsFrom(DataGridRelationshipRow row)2479 internal void UpdateRowsFrom (DataGridRelationshipRow row) 2480 { 2481 int start_index = Array.IndexOf (rows, row); 2482 if (start_index == -1) 2483 return; 2484 2485 for (int i = start_index + 1; i < rows.Length; i ++) 2486 rows[i].VerticalOffset = rows[i-1].VerticalOffset + rows[i-1].Height; 2487 2488 CalcAreasAndInvalidate (); 2489 } 2490 BindColumns()2491 void BindColumns () 2492 { 2493 if (list_manager != null) { 2494 string list_name = list_manager.GetListName (null); 2495 if (TableStyles[list_name] == null) { 2496 // no style exists by the supplied name 2497 current_style.GridColumnStyles.Clear (); 2498 current_style.CreateColumnsForTable (false); 2499 } else if (CurrentTableStyle == grid_style || 2500 CurrentTableStyle.MappingName != list_name) { 2501 // If the style has been defined by the user, use it 2502 // Also, if the user provided style is empty, 2503 // force a bind for it 2504 CurrentTableStyle = styles_collection[list_name]; 2505 current_style.CreateColumnsForTable (current_style.GridColumnStyles.Count > 0); 2506 } else { 2507 current_style.CreateColumnsForTable (true); 2508 } 2509 } else 2510 current_style.CreateColumnsForTable (false); 2511 } 2512 OnListManagerMetaDataChanged(object sender, EventArgs e)2513 private void OnListManagerMetaDataChanged (object sender, EventArgs e) 2514 { 2515 BindColumns (); 2516 CalcAreasAndInvalidate (); 2517 } 2518 OnListManagerPositionChanged(object sender, EventArgs e)2519 private void OnListManagerPositionChanged (object sender, EventArgs e) 2520 { 2521 // Set the field directly, as we are empty now and using CurrentRow 2522 // directly would add a new row in this case. 2523 if (list_manager.Count == 0) { 2524 current_cell = new DataGridCell (0, 0); 2525 return; 2526 } 2527 2528 from_positionchanged_handler = true; 2529 CurrentRow = list_manager.Position; 2530 from_positionchanged_handler = false; 2531 } 2532 OnListManagerItemChanged(object sender, ItemChangedEventArgs e)2533 private void OnListManagerItemChanged (object sender, ItemChangedEventArgs e) 2534 { 2535 // if it was us who created the new row in CurrentCell, ignore it and don't recreate the rows yet. 2536 if (adding_new_row) 2537 return; 2538 2539 if (e.Index == -1) { 2540 ResetSelection (); 2541 if (rows == null || RowsCount != rows.Length - (ShowEditRow ? 1 : 0)) 2542 { 2543 if (is_editing) 2544 CancelEditing (); 2545 RecreateDataGridRows (true); 2546 } 2547 } else { 2548 InvalidateRow (e.Index); 2549 } 2550 } 2551 OnTableStylesCollectionChanged(object sender, CollectionChangeEventArgs e)2552 private void OnTableStylesCollectionChanged (object sender, CollectionChangeEventArgs e) 2553 { 2554 if (ListManager == null) 2555 return; 2556 2557 string list_name = ListManager.GetListName (null); 2558 switch (e.Action) { 2559 case CollectionChangeAction.Add: 2560 if (e.Element != null && String.Compare (list_name, ((DataGridTableStyle)e.Element).MappingName, true) == 0) { 2561 CurrentTableStyle = (DataGridTableStyle)e.Element; 2562 // force to auto detect columns in case the new style is completely empty 2563 ((DataGridTableStyle) e.Element).CreateColumnsForTable (CurrentTableStyle.GridColumnStyles.Count > 0); 2564 } 2565 break; 2566 case CollectionChangeAction.Remove: 2567 if (e.Element != null && String.Compare (list_name, ((DataGridTableStyle)e.Element).MappingName, true) == 0) { 2568 CurrentTableStyle = default_style; 2569 current_style.GridColumnStyles.Clear (); 2570 current_style.CreateColumnsForTable (false); 2571 } 2572 break; 2573 case CollectionChangeAction.Refresh: 2574 if (CurrentTableStyle == default_style 2575 || String.Compare (list_name, CurrentTableStyle.MappingName, true) != 0) { 2576 DataGridTableStyle style = styles_collection [list_name]; 2577 if (style != null) { 2578 CurrentTableStyle = style; 2579 current_style.CreateColumnsForTable (false); 2580 } else { 2581 CurrentTableStyle = default_style; 2582 current_style.GridColumnStyles.Clear (); 2583 current_style.CreateColumnsForTable (false); 2584 } 2585 } 2586 break; 2587 } 2588 CalcAreasAndInvalidate (); 2589 } 2590 AddNewRow()2591 private void AddNewRow () 2592 { 2593 ListManager.EndCurrentEdit (); 2594 ListManager.AddNew (); 2595 } 2596 Edit()2597 private void Edit () 2598 { 2599 if (CurrentTableStyle.GridColumnStyles.Count == 0) 2600 return; 2601 2602 if (!CurrentTableStyle.GridColumnStyles[CurrentColumn].bound) 2603 return; 2604 2605 // if we don't have any rows nor the "new" cell, there's nothing to do 2606 if (ListManager != null && (ListManager.Count == 0 && !ListManager.AllowNew)) 2607 return; 2608 2609 is_editing = true; 2610 is_changing = false; 2611 2612 CurrentTableStyle.GridColumnStyles[CurrentColumn].Edit (ListManager, 2613 CurrentRow, GetCellBounds (CurrentRow, CurrentColumn), 2614 _readonly, null, true); 2615 } 2616 EndEdit()2617 private void EndEdit () 2618 { 2619 if (CurrentTableStyle.GridColumnStyles.Count == 0) 2620 return; 2621 2622 if (!CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].bound) 2623 return; 2624 2625 EndEdit (CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber], 2626 current_cell.RowNumber, false); 2627 } 2628 ShiftSelection(int index)2629 private void ShiftSelection (int index) 2630 { 2631 // we have to save off selection_start 2632 // because ResetSelection clobbers it 2633 int saved_selection_start = selection_start; 2634 int start, end; 2635 2636 ResetSelection (); 2637 selection_start = saved_selection_start; 2638 2639 if (index >= selection_start) { 2640 start = selection_start; 2641 end = index; 2642 } else { 2643 start = index; 2644 end = selection_start; 2645 } 2646 2647 if (start == -1) start = 0; 2648 2649 for (int idx = start; idx <= end; idx ++) 2650 Select (idx); 2651 } 2652 ScrollToColumnInPixels(int pixel)2653 private void ScrollToColumnInPixels (int pixel) 2654 { 2655 int pixels; 2656 2657 if (pixel > horiz_pixeloffset) // ScrollRight 2658 pixels = -1 * (pixel - horiz_pixeloffset); 2659 else 2660 pixels = horiz_pixeloffset - pixel; 2661 2662 Rectangle area = cells_area; 2663 2664 if (ColumnHeadersVisible) { 2665 area.Y -= ColumnHeadersArea.Height; 2666 area.Height += ColumnHeadersArea.Height; 2667 } 2668 2669 horiz_pixeloffset = pixel; 2670 UpdateVisibleColumn (); 2671 2672 EndEdit (); 2673 2674 XplatUI.ScrollWindow (Handle, area, pixels, 0, false); 2675 2676 int pixel_offset = GetColumnStartingPixel (CurrentColumn); 2677 int next_pixel_offset = pixel_offset; 2678 2679 if (CurrentColumn < CurrentTableStyle.GridColumnStyles.Count) 2680 { 2681 next_pixel_offset += CurrentTableStyle.GridColumnStyles[CurrentColumn].Width; 2682 } 2683 2684 if (pixel_offset >= horiz_pixeloffset 2685 && next_pixel_offset < horiz_pixeloffset + cells_area.Width) 2686 Edit (); 2687 } 2688 ScrollToRow(int old_row, int new_row)2689 private void ScrollToRow (int old_row, int new_row) 2690 { 2691 int pixels = 0; 2692 int i; 2693 2694 if (new_row > old_row) { // Scrolldown 2695 for (i = old_row; i < new_row; i ++) 2696 pixels -= rows[i].Height; 2697 } else { 2698 for (i = new_row; i < old_row; i ++) 2699 pixels += rows[i].Height; 2700 } 2701 2702 if (pixels == 0) 2703 return; 2704 2705 Rectangle rows_area = cells_area; // Cells area - partial rows space 2706 2707 if (RowHeadersVisible) { 2708 rows_area.X -= RowHeaderWidth; 2709 rows_area.Width += RowHeaderWidth; 2710 } 2711 2712 /* scroll the window */ 2713 XplatUI.ScrollWindow (Handle, rows_area, 0, pixels, false); 2714 2715 /* if the row is still */ 2716 if (CurrentRow >= first_visible_row && CurrentRow < first_visible_row + visible_row_count) 2717 Edit (); 2718 } 2719 2720 ColumnResize(int column)2721 private void ColumnResize (int column) 2722 { 2723 CurrencyManager source = this.ListManager; 2724 DataGridColumnStyle style = CurrentTableStyle.GridColumnStyles[column]; 2725 string headerText = style.HeaderText; 2726 using (Graphics g = base.CreateGraphics ()) { 2727 int rows = source.Count; 2728 int width = (int)g.MeasureString (headerText, CurrentTableStyle.HeaderFont).Width + 4; 2729 2730 for (int i = 0; i < rows; i++) { 2731 int rowColWidth = (int)style.GetPreferredSize (g, style.GetColumnValueAtRow (source, i)).Width; 2732 if (rowColWidth > width) 2733 width = rowColWidth; 2734 } 2735 if (style.Width != width) 2736 style.Width = width; 2737 } 2738 } 2739 RowResize(int row)2740 private void RowResize (int row) 2741 { 2742 CurrencyManager source = this.ListManager; 2743 using (Graphics g = base.CreateGraphics ()) { 2744 GridColumnStylesCollection columns = CurrentTableStyle.GridColumnStyles; 2745 int colCount = columns.Count; 2746 //int rowCount = source.Count; 2747 int height = 0; 2748 for (int i = 0; i < colCount; i++) { 2749 object val = columns[i].GetColumnValueAtRow (source, row); 2750 height = Math.Max (columns[i].GetPreferredHeight (g, val), height); 2751 } 2752 if (this.DataGridRows[row].Height != height) 2753 this.DataGridRows[row].Height = height; 2754 } 2755 } 2756 #endregion Private Instance Methods 2757 2758 #region Events 2759 static object AllowNavigationChangedEvent = new object (); 2760 static object BackButtonClickEvent = new object (); 2761 static object BackgroundColorChangedEvent = new object (); 2762 static object BorderStyleChangedEvent = new object (); 2763 static object CaptionVisibleChangedEvent = new object (); 2764 static object CurrentCellChangedEvent = new object (); 2765 static object DataSourceChangedEvent = new object (); 2766 static object FlatModeChangedEvent = new object (); 2767 static object NavigateEvent = new object (); 2768 static object ParentRowsLabelStyleChangedEvent = new object (); 2769 static object ParentRowsVisibleChangedEvent = new object (); 2770 static object ReadOnlyChangedEvent = new object (); 2771 static object RowHeaderClickEvent = new object (); 2772 static object ScrollEvent = new object (); 2773 static object ShowParentDetailsButtonClickEvent = new object (); 2774 2775 public event EventHandler AllowNavigationChanged { 2776 add { Events.AddHandler (AllowNavigationChangedEvent, value); } 2777 remove { Events.RemoveHandler (AllowNavigationChangedEvent, value); } 2778 } 2779 2780 public event EventHandler BackButtonClick { 2781 add { Events.AddHandler (BackButtonClickEvent, value); } 2782 remove { Events.RemoveHandler (BackButtonClickEvent, value); } 2783 } 2784 2785 public event EventHandler BackgroundColorChanged { 2786 add { Events.AddHandler (BackgroundColorChangedEvent, value); } 2787 remove { Events.RemoveHandler (BackgroundColorChangedEvent, value); } 2788 } 2789 2790 [Browsable(false)] 2791 [EditorBrowsable(EditorBrowsableState.Never)] 2792 public new event EventHandler BackgroundImageChanged { 2793 add { base.BackgroundImageChanged += value; } 2794 remove { base.BackgroundImageChanged -= value; } 2795 } 2796 2797 [Browsable(false)] 2798 [EditorBrowsable(EditorBrowsableState.Never)] 2799 public new event EventHandler BackgroundImageLayoutChanged { 2800 add { base.BackgroundImageLayoutChanged += value; } 2801 remove { base.BackgroundImageLayoutChanged -= value; } 2802 } 2803 2804 [Browsable(false)] 2805 [EditorBrowsable(EditorBrowsableState.Never)] 2806 public new event EventHandler TextChanged { 2807 add { base.TextChanged += value; } 2808 remove { base.TextChanged -= value; } 2809 } 2810 2811 [Browsable(false)] 2812 [EditorBrowsable(EditorBrowsableState.Never)] 2813 public new event EventHandler CursorChanged { 2814 add { base.CursorChanged += value; } 2815 remove { base.CursorChanged -= value; } 2816 } 2817 2818 public event EventHandler BorderStyleChanged { 2819 add { Events.AddHandler (BorderStyleChangedEvent, value); } 2820 remove { Events.RemoveHandler (BorderStyleChangedEvent, value); } 2821 } 2822 2823 public event EventHandler CaptionVisibleChanged { 2824 add { Events.AddHandler (CaptionVisibleChangedEvent, value); } 2825 remove { Events.RemoveHandler (CaptionVisibleChangedEvent, value); } 2826 } 2827 2828 public event EventHandler CurrentCellChanged { 2829 add { Events.AddHandler (CurrentCellChangedEvent, value); } 2830 remove { Events.RemoveHandler (CurrentCellChangedEvent, value); } 2831 } 2832 2833 public event EventHandler DataSourceChanged { 2834 add { Events.AddHandler (DataSourceChangedEvent, value); } 2835 remove { Events.RemoveHandler (DataSourceChangedEvent, value); } 2836 } 2837 2838 public event EventHandler FlatModeChanged { 2839 add { Events.AddHandler (FlatModeChangedEvent, value); } 2840 remove { Events.RemoveHandler (FlatModeChangedEvent, value); } 2841 } 2842 2843 public event NavigateEventHandler Navigate { 2844 add { Events.AddHandler (NavigateEvent, value); } 2845 remove { Events.RemoveHandler (NavigateEvent, value); } 2846 } 2847 2848 public event EventHandler ParentRowsLabelStyleChanged { 2849 add { Events.AddHandler (ParentRowsLabelStyleChangedEvent, value); } 2850 remove { Events.RemoveHandler (ParentRowsLabelStyleChangedEvent, value); } 2851 } 2852 2853 public event EventHandler ParentRowsVisibleChanged { 2854 add { Events.AddHandler (ParentRowsVisibleChangedEvent, value); } 2855 remove { Events.RemoveHandler (ParentRowsVisibleChangedEvent, value); } 2856 } 2857 2858 public event EventHandler ReadOnlyChanged { 2859 add { Events.AddHandler (ReadOnlyChangedEvent, value); } 2860 remove { Events.RemoveHandler (ReadOnlyChangedEvent, value); } 2861 } 2862 2863 protected event EventHandler RowHeaderClick { 2864 add { Events.AddHandler (RowHeaderClickEvent, value); } 2865 remove { Events.RemoveHandler (RowHeaderClickEvent, value); } 2866 } 2867 2868 public event EventHandler Scroll { 2869 add { Events.AddHandler (ScrollEvent, value); } 2870 remove { Events.RemoveHandler (ScrollEvent, value); } 2871 } 2872 2873 public event EventHandler ShowParentDetailsButtonClick { 2874 add { Events.AddHandler (ShowParentDetailsButtonClickEvent, value); } 2875 remove { Events.RemoveHandler (ShowParentDetailsButtonClickEvent, value); } 2876 } 2877 #endregion // Events 2878 2879 #region Code originally in DataGridDrawingLogic.cs 2880 2881 #region Local Variables 2882 2883 // Areas 2884 Rectangle parent_rows; 2885 int width_of_all_columns; 2886 2887 internal Rectangle caption_area; 2888 internal Rectangle column_headers_area; // Used columns header area 2889 internal int column_headers_max_width; // Total width (max width) for columns headrs 2890 internal Rectangle row_headers_area; // Used Headers rows area 2891 internal Rectangle cells_area; 2892 #endregion // Local Variables 2893 2894 #region Public Instance Methods 2895 2896 // Calc the max with of all columns CalcAllColumnsWidth()2897 private int CalcAllColumnsWidth () 2898 { 2899 int width = 0; 2900 int cnt = CurrentTableStyle.GridColumnStyles.Count; 2901 2902 for (int col = 0; col < cnt; col++) { 2903 if (CurrentTableStyle.GridColumnStyles[col].bound == false) { 2904 continue; 2905 } 2906 width += CurrentTableStyle.GridColumnStyles[col].Width; 2907 } 2908 return width; 2909 } 2910 2911 // Gets a column from a pixel FromPixelToColumn(int pixel, out int column_x)2912 private int FromPixelToColumn (int pixel, out int column_x) 2913 { 2914 int width = 0; 2915 int cnt = CurrentTableStyle.GridColumnStyles.Count; 2916 column_x = 0; 2917 2918 if (cnt == 0) 2919 return -1; 2920 2921 if (CurrentTableStyle.CurrentRowHeadersVisible) { 2922 width += row_headers_area.X + row_headers_area.Width; 2923 column_x += row_headers_area.X + row_headers_area.Width; 2924 if (pixel < width) 2925 return -1; 2926 } 2927 2928 for (int col = 0; col < cnt; col++) { 2929 if (CurrentTableStyle.GridColumnStyles[col].bound == false) 2930 continue; 2931 2932 width += CurrentTableStyle.GridColumnStyles[col].Width; 2933 2934 if (pixel < width) 2935 return col; 2936 2937 column_x += CurrentTableStyle.GridColumnStyles[col].Width; 2938 } 2939 2940 return cnt - 1; 2941 } 2942 GetColumnStartingPixel(int my_col)2943 internal int GetColumnStartingPixel (int my_col) 2944 { 2945 int width = 0; 2946 int cnt = CurrentTableStyle.GridColumnStyles.Count; 2947 2948 for (int col = 0; col < cnt; col++) { 2949 if (CurrentTableStyle.GridColumnStyles[col].bound == false) { 2950 continue; 2951 } 2952 2953 if (my_col == col) 2954 return width; 2955 2956 width += CurrentTableStyle.GridColumnStyles[col].Width; 2957 } 2958 2959 return 0; 2960 } 2961 2962 // Which column has to be the first visible column to ensure a column visibility GetFirstColumnForColumnVisibility(int current_first_visible_column, int column)2963 int GetFirstColumnForColumnVisibility (int current_first_visible_column, int column) 2964 { 2965 int new_col = column; 2966 int width = 0; 2967 2968 if (column > current_first_visible_column) { // Going forward 2969 for (new_col = column; new_col >= 0; new_col--) { 2970 if (!CurrentTableStyle.GridColumnStyles[new_col].bound) 2971 continue; 2972 width += CurrentTableStyle.GridColumnStyles[new_col].Width; 2973 2974 if (width >= cells_area.Width) 2975 return new_col + 1; 2976 //return new_col < CurrentTableStyle.GridColumnStyles.Count ? new_col + 1 : CurrentTableStyle.GridColumnStyles.Count; 2977 } 2978 return 0; 2979 } else { 2980 return column; 2981 } 2982 } 2983 2984 bool in_calc_grid_areas; CalcGridAreas()2985 void CalcGridAreas () 2986 { 2987 if (!IsHandleCreated) // Delay calculations until the handle is created 2988 return; 2989 2990 /* make sure we don't happen to end up in this method again */ 2991 if (in_calc_grid_areas) 2992 return; 2993 2994 in_calc_grid_areas = true; 2995 2996 /* Order is important. E.g. row headers max. height depends on caption */ 2997 horiz_pixeloffset = 0; 2998 CalcCaption (); 2999 CalcParentRows (); 3000 CalcParentButtons (); 3001 UpdateVisibleRowCount (); 3002 CalcRowHeaders (); 3003 width_of_all_columns = CalcAllColumnsWidth (); 3004 CalcColumnHeaders (); 3005 CalcCellsArea (); 3006 3007 bool needHoriz = false; 3008 bool needVert = false; 3009 3010 /* figure out which scrollbars we need, and what the visible areas are */ 3011 int visible_cells_width = cells_area.Width; 3012 int visible_cells_height = cells_area.Height; 3013 int allrows = RowsCount; 3014 3015 if (ShowEditRow && RowsCount > 0) 3016 allrows++; 3017 3018 /* use a loop to iteratively calculate whether 3019 * we need horiz/vert scrollbars. */ 3020 for (int i = 0; i < 3; i++) { 3021 if (needVert) 3022 visible_cells_width = cells_area.Width - vert_scrollbar.Width; 3023 if (needHoriz) 3024 visible_cells_height = cells_area.Height - horiz_scrollbar.Height; 3025 3026 UpdateVisibleRowCount (); 3027 3028 needHoriz = (width_of_all_columns > visible_cells_width); 3029 needVert = (allrows > MaxVisibleRowCount); 3030 } 3031 3032 int horiz_scrollbar_width = ClientRectangle.Width; 3033 int horiz_scrollbar_maximum = 0; 3034 int vert_scrollbar_height = 0; 3035 int vert_scrollbar_maximum = 0; 3036 3037 if (needVert) 3038 SetUpVerticalScrollBar (out vert_scrollbar_height, out vert_scrollbar_maximum); 3039 3040 if (needHoriz) 3041 SetUpHorizontalScrollBar (out horiz_scrollbar_maximum); 3042 3043 cells_area.Width = visible_cells_width; 3044 cells_area.Height = visible_cells_height; 3045 3046 if (needVert && needHoriz) { 3047 if (ShowParentRows) 3048 parent_rows.Width -= vert_scrollbar.Width; 3049 3050 if (!ColumnHeadersVisible) { 3051 if (column_headers_area.X + column_headers_area.Width > vert_scrollbar.Location.X) { 3052 column_headers_area.Width -= vert_scrollbar.Width; 3053 } 3054 } 3055 3056 horiz_scrollbar_width -= vert_scrollbar.Width; 3057 vert_scrollbar_height -= horiz_scrollbar.Height; 3058 } 3059 3060 if (needVert) { 3061 if (row_headers_area.Y + row_headers_area.Height > ClientRectangle.Y + ClientRectangle.Height) { 3062 row_headers_area.Height -= horiz_scrollbar.Height; 3063 } 3064 3065 vert_scrollbar.Size = new Size (vert_scrollbar.Width, 3066 vert_scrollbar_height); 3067 3068 vert_scrollbar.Maximum = vert_scrollbar_maximum; 3069 Controls.Add (vert_scrollbar); 3070 vert_scrollbar.Visible = true; 3071 } else { 3072 Controls.Remove (vert_scrollbar); 3073 vert_scrollbar.Visible = false; 3074 } 3075 3076 if (needHoriz) { 3077 horiz_scrollbar.Size = new Size (horiz_scrollbar_width, 3078 horiz_scrollbar.Height); 3079 3080 horiz_scrollbar.Maximum = horiz_scrollbar_maximum; 3081 Controls.Add (horiz_scrollbar); 3082 horiz_scrollbar.Visible = true; 3083 } else { 3084 Controls.Remove (horiz_scrollbar); 3085 horiz_scrollbar.Visible = false; 3086 } 3087 3088 UpdateVisibleColumn (); 3089 UpdateVisibleRowCount (); 3090 3091 in_calc_grid_areas = false; 3092 } 3093 CalcCaption()3094 void CalcCaption () 3095 { 3096 caption_area.X = ClientRectangle.X; 3097 caption_area.Y = ClientRectangle.Y; 3098 caption_area.Width = ClientRectangle.Width; 3099 if (caption_visible) { 3100 caption_area.Height = CaptionFont.Height; 3101 if (caption_area.Height < back_button_image.Height) 3102 caption_area.Height = back_button_image.Height; 3103 caption_area.Height += 2; 3104 } else 3105 caption_area.Height = 0; 3106 } 3107 CalcCellsArea()3108 void CalcCellsArea () 3109 { 3110 cells_area.X = ClientRectangle.X + row_headers_area.Width; 3111 cells_area.Y = column_headers_area.Y + column_headers_area.Height; 3112 cells_area.Width = ClientRectangle.X + ClientRectangle.Width - cells_area.X; 3113 if (cells_area.Width < 0) 3114 cells_area.Width = 0; 3115 cells_area.Height = ClientRectangle.Y + ClientRectangle.Height - cells_area.Y; 3116 if (cells_area.Height < 0) 3117 cells_area.Height = 0; 3118 } 3119 CalcColumnHeaders()3120 void CalcColumnHeaders () 3121 { 3122 int max_width_cols; 3123 3124 column_headers_area.X = ClientRectangle.X; 3125 column_headers_area.Y = parent_rows.Y + parent_rows.Height; 3126 3127 // TODO: take into account Scrollbars 3128 column_headers_max_width = ClientRectangle.X + ClientRectangle.Width - column_headers_area.X; 3129 max_width_cols = column_headers_max_width; 3130 3131 if (CurrentTableStyle.CurrentRowHeadersVisible) 3132 max_width_cols -= RowHeaderWidth; 3133 3134 if (width_of_all_columns > max_width_cols) { 3135 column_headers_area.Width = column_headers_max_width; 3136 } else { 3137 column_headers_area.Width = width_of_all_columns; 3138 3139 if (CurrentTableStyle.CurrentRowHeadersVisible) 3140 column_headers_area.Width += RowHeaderWidth; 3141 } 3142 3143 if (ColumnHeadersVisible) 3144 column_headers_area.Height = CurrentTableStyle.HeaderFont.Height + 6; 3145 else 3146 column_headers_area.Height = 0; 3147 } 3148 CalcParentRows()3149 void CalcParentRows () 3150 { 3151 parent_rows.X = ClientRectangle.X; 3152 parent_rows.Y = caption_area.Y + caption_area.Height; 3153 parent_rows.Width = ClientRectangle.Width; 3154 if (ShowParentRows) 3155 parent_rows.Height = (CaptionFont.Height + 3) * data_source_stack.Count; 3156 else 3157 parent_rows.Height = 0; 3158 } 3159 CalcParentButtons()3160 void CalcParentButtons () 3161 { 3162 if (data_source_stack.Count > 0 && CaptionVisible) { 3163 back_button_rect = new Rectangle (ClientRectangle.X + ClientRectangle.Width - 2 * (caption_area.Height - 2) - 8, 3164 caption_area.Height / 2 - back_button_image.Height / 2, 3165 back_button_image.Width, back_button_image.Height); 3166 parent_rows_button_rect = new Rectangle (ClientRectangle.X + ClientRectangle.Width - (caption_area.Height - 2) - 4, 3167 caption_area.Height / 2 - parent_rows_button_image.Height / 2, 3168 parent_rows_button_image.Width, parent_rows_button_image.Height); 3169 } else { 3170 back_button_rect = parent_rows_button_rect = Rectangle.Empty; 3171 } 3172 } 3173 CalcRowHeaders()3174 void CalcRowHeaders () 3175 { 3176 row_headers_area.X = ClientRectangle.X; 3177 row_headers_area.Y = column_headers_area.Y + column_headers_area.Height; 3178 row_headers_area.Height = ClientRectangle.Height + ClientRectangle.Y - row_headers_area.Y; 3179 3180 if (CurrentTableStyle.CurrentRowHeadersVisible) 3181 row_headers_area.Width = RowHeaderWidth; 3182 else 3183 row_headers_area.Width = 0; 3184 } 3185 GetVisibleRowCount(int visibleHeight)3186 int GetVisibleRowCount (int visibleHeight) 3187 { 3188 int rows_height = 0; 3189 int r; 3190 for (r = FirstVisibleRow; r < rows.Length; r ++) { 3191 if (rows_height + rows[r].Height >= visibleHeight) 3192 break; 3193 rows_height += rows[r].Height; 3194 } 3195 3196 if (r <= rows.Length - 1) 3197 r ++; 3198 3199 return r - FirstVisibleRow; 3200 } 3201 UpdateVisibleColumn()3202 void UpdateVisibleColumn () 3203 { 3204 visible_column_count = 0; 3205 3206 if (CurrentTableStyle.GridColumnStyles.Count == 0) 3207 return; 3208 3209 int min_pixel; 3210 int max_pixel; 3211 int max_col; 3212 int unused; 3213 3214 min_pixel = horiz_pixeloffset; 3215 if (CurrentTableStyle.CurrentRowHeadersVisible) 3216 min_pixel += row_headers_area.X + row_headers_area.Width; 3217 max_pixel = min_pixel + cells_area.Width; 3218 3219 first_visible_column = FromPixelToColumn (min_pixel, out unused); 3220 max_col = FromPixelToColumn (max_pixel, out unused); 3221 3222 for (int i = first_visible_column; i <= max_col; i ++) { 3223 if (CurrentTableStyle.GridColumnStyles[i].bound) 3224 visible_column_count++; 3225 } 3226 3227 if (first_visible_column + visible_column_count < CurrentTableStyle.GridColumnStyles.Count) { 3228 visible_column_count++; // Partially visible column 3229 } 3230 } 3231 UpdateVisibleRowCount()3232 void UpdateVisibleRowCount () 3233 { 3234 visible_row_count = GetVisibleRowCount (cells_area.Height); 3235 3236 CalcRowHeaders (); // Height depends on num of visible rows 3237 } 3238 InvalidateCaption()3239 void InvalidateCaption () 3240 { 3241 if (caption_area.IsEmpty) 3242 return; 3243 3244 Invalidate (caption_area); 3245 } 3246 InvalidateRow(int row)3247 void InvalidateRow (int row) 3248 { 3249 if (row < FirstVisibleRow || row > FirstVisibleRow + VisibleRowCount) 3250 return; 3251 3252 Rectangle rect_row = new Rectangle (); 3253 3254 rect_row.X = cells_area.X; 3255 rect_row.Width = width_of_all_columns; 3256 if (rect_row.Width > cells_area.Width) 3257 rect_row.Width = cells_area.Width; 3258 rect_row.Height = rows[row].Height; 3259 rect_row.Y = cells_area.Y + rows[row].VerticalOffset - rows[FirstVisibleRow].VerticalOffset; 3260 Invalidate (rect_row); 3261 } 3262 InvalidateRowHeader(int row)3263 void InvalidateRowHeader (int row) 3264 { 3265 Rectangle rect_rowhdr = new Rectangle (); 3266 rect_rowhdr.X = row_headers_area.X; 3267 rect_rowhdr.Width = row_headers_area.Width; 3268 rect_rowhdr.Height = rows[row].Height; 3269 rect_rowhdr.Y = row_headers_area.Y + rows[row].VerticalOffset - rows[FirstVisibleRow].VerticalOffset; 3270 Invalidate (rect_rowhdr); 3271 } 3272 InvalidateColumn(DataGridColumnStyle column)3273 internal void InvalidateColumn (DataGridColumnStyle column) 3274 { 3275 Rectangle rect_col = new Rectangle (); 3276 int col_pixel; 3277 int col = -1; 3278 3279 col = CurrentTableStyle.GridColumnStyles.IndexOf (column); 3280 3281 if (col == -1) 3282 return; 3283 3284 rect_col.Width = column.Width; 3285 col_pixel = GetColumnStartingPixel (col); 3286 rect_col.X = cells_area.X + col_pixel - horiz_pixeloffset; 3287 rect_col.Y = cells_area.Y; 3288 rect_col.Height = cells_area.Height; 3289 Invalidate (rect_col); 3290 } 3291 DrawResizeLineVert(int x)3292 void DrawResizeLineVert (int x) 3293 { 3294 XplatUI.DrawReversibleRectangle (Handle, 3295 new Rectangle (x, cells_area.Y, 1, cells_area.Height - 3), 3296 2); 3297 } 3298 DrawResizeLineHoriz(int y)3299 void DrawResizeLineHoriz (int y) 3300 { 3301 XplatUI.DrawReversibleRectangle (Handle, 3302 new Rectangle (cells_area.X, y, cells_area.Width - 3, 1), 3303 2); 3304 } 3305 SetUpHorizontalScrollBar(out int maximum)3306 void SetUpHorizontalScrollBar (out int maximum) 3307 { 3308 maximum = width_of_all_columns; 3309 3310 horiz_scrollbar.Location = new Point (ClientRectangle.X, ClientRectangle.Y + 3311 ClientRectangle.Height - horiz_scrollbar.Height); 3312 3313 horiz_scrollbar.LargeChange = cells_area.Width; 3314 } 3315 SetUpVerticalScrollBar(out int height, out int maximum)3316 void SetUpVerticalScrollBar (out int height, out int maximum) 3317 { 3318 int y; 3319 3320 y = ClientRectangle.Y + parent_rows.Y + parent_rows.Height; 3321 height = ClientRectangle.Height - parent_rows.Y - parent_rows.Height; 3322 3323 vert_scrollbar.Location = new Point (ClientRectangle.X + 3324 ClientRectangle.Width - vert_scrollbar.Width, y); 3325 3326 maximum = RowsCount; 3327 3328 if (ShowEditRow && RowsCount > 0) { 3329 maximum++; 3330 } 3331 3332 vert_scrollbar.LargeChange = VLargeChange; 3333 } 3334 3335 #endregion // Public Instance Methods 3336 3337 #region Instance Properties 3338 // Returns the ColumnHeaders area excluding the rectangle shared with RowHeaders 3339 internal Rectangle ColumnHeadersArea { 3340 get { 3341 Rectangle columns_area = column_headers_area; 3342 3343 if (CurrentTableStyle.CurrentRowHeadersVisible) { 3344 columns_area.X += RowHeaderWidth; 3345 columns_area.Width -= RowHeaderWidth; 3346 } 3347 return columns_area; 3348 } 3349 } 3350 3351 internal Rectangle RowHeadersArea { 3352 get { return row_headers_area; } 3353 } 3354 3355 internal Rectangle ParentRowsArea { 3356 get { return parent_rows; } 3357 } 3358 3359 int VLargeChange { 3360 get { 3361 return MaxVisibleRowCount; 3362 } 3363 } 3364 3365 #endregion Instance Properties 3366 3367 #endregion // Code originally in DataGridDrawingLogic.cs 3368 3369 #region UIA Framework: Methods, Properties and Events 3370 3371 static object UIACollectionChangedEvent = new object (); 3372 static object UIASelectionChangedEvent = new object (); 3373 static object UIAColumnHeadersVisibleChangedEvent = new object (); 3374 static object UIAGridCellChangedEvent = new object (); 3375 3376 internal ScrollBar UIAHScrollBar { 3377 get { return horiz_scrollbar; } 3378 } 3379 3380 internal ScrollBar UIAVScrollBar { 3381 get { return vert_scrollbar; } 3382 } 3383 3384 internal DataGridTableStyle UIACurrentTableStyle { 3385 get { return current_style; } 3386 } 3387 3388 internal int UIASelectedRows { 3389 get { return selected_rows.Count; } 3390 } 3391 3392 internal Rectangle UIAColumnHeadersArea { 3393 get { return ColumnHeadersArea; } 3394 } 3395 3396 internal Rectangle UIACaptionArea { 3397 get { return caption_area; } 3398 } 3399 3400 internal Rectangle UIACellsArea { 3401 get { return cells_area; } 3402 } 3403 3404 internal int UIARowHeight { 3405 get { return RowHeight; } 3406 } 3407 3408 internal event CollectionChangeEventHandler UIACollectionChanged { 3409 add { Events.AddHandler (UIACollectionChangedEvent, value); } 3410 remove { Events.RemoveHandler (UIACollectionChangedEvent, value); } 3411 } 3412 3413 internal event CollectionChangeEventHandler UIASelectionChanged { 3414 add { Events.AddHandler (UIASelectionChangedEvent, value); } 3415 remove { Events.RemoveHandler (UIASelectionChangedEvent, value); } 3416 } 3417 3418 internal event EventHandler UIAColumnHeadersVisibleChanged { 3419 add { Events.AddHandler (UIAColumnHeadersVisibleChangedEvent, value); } 3420 remove { Events.RemoveHandler (UIAColumnHeadersVisibleChangedEvent, value); } 3421 } 3422 3423 internal event CollectionChangeEventHandler UIAGridCellChanged { 3424 add { Events.AddHandler (UIAGridCellChangedEvent, value); } 3425 remove { Events.RemoveHandler (UIAGridCellChangedEvent, value); } 3426 } 3427 OnUIACollectionChangedEvent(CollectionChangeEventArgs args)3428 internal void OnUIACollectionChangedEvent (CollectionChangeEventArgs args) 3429 { 3430 CollectionChangeEventHandler eh 3431 = (CollectionChangeEventHandler) Events [UIACollectionChangedEvent]; 3432 if (eh != null) 3433 eh (this, args); 3434 } 3435 OnUIASelectionChangedEvent(CollectionChangeEventArgs args)3436 internal void OnUIASelectionChangedEvent (CollectionChangeEventArgs args) 3437 { 3438 CollectionChangeEventHandler eh 3439 = (CollectionChangeEventHandler) Events [UIASelectionChangedEvent]; 3440 if (eh != null) 3441 eh (this, args); 3442 } 3443 OnUIAColumnHeadersVisibleChanged()3444 internal void OnUIAColumnHeadersVisibleChanged () 3445 { 3446 EventHandler eh = (EventHandler) Events [UIAColumnHeadersVisibleChangedEvent]; 3447 if (eh != null) 3448 eh (this, EventArgs.Empty); 3449 } 3450 OnUIAGridCellChanged(CollectionChangeEventArgs args)3451 internal void OnUIAGridCellChanged (CollectionChangeEventArgs args) 3452 { 3453 CollectionChangeEventHandler eh 3454 = (CollectionChangeEventHandler) Events [UIAGridCellChangedEvent]; 3455 if (eh != null) 3456 eh (this, args); 3457 } 3458 3459 #endregion // UIA Framework: Methods, Properties and Events 3460 3461 } 3462 } 3463