1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
22 // Pedro MartÃnez Juliá <pedromj@gmail.com>
28 using System.ComponentModel;
30 using System.Runtime.InteropServices;
31 using System.Collections;
32 using System.Collections.Generic;
34 namespace System.Windows.Forms
36 [TypeConverter (typeof (DataGridViewRowConverter))]
37 public class DataGridViewRow : DataGridViewBand
39 private AccessibleObject accessibilityObject;
40 private DataGridViewCellCollection cells;
41 private ContextMenuStrip contextMenuStrip;
42 private int dividerHeight;
43 private string errorText;
44 private DataGridViewRowHeaderCell headerCell;
46 private int minimumHeight;
47 private int explicit_height;
49 public DataGridViewRow ()
51 cells = new DataGridViewCellCollection(this);
55 headerCell = new DataGridViewRowHeaderCell();
56 headerCell.SetOwningRow (this);
57 accessibilityObject = new AccessibleObject ();
58 SetState (DataGridViewElementStates.Visible);
62 public AccessibleObject AccessibilityObject {
63 get { return accessibilityObject; }
67 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
68 public DataGridViewCellCollection Cells {
73 public override ContextMenuStrip ContextMenuStrip {
76 throw new InvalidOperationException ("Operation cannot be performed on a shared row.");
78 return contextMenuStrip;
81 if (contextMenuStrip != value) {
82 contextMenuStrip = value;
83 if (DataGridView != null) {
84 DataGridView.OnRowContextMenuStripChanged(new DataGridViewRowEventArgs(this));
91 [EditorBrowsable (EditorBrowsableState.Advanced)]
92 public object DataBoundItem {
94 if (base.DataGridView != null && DataGridView.DataManager != null) {
95 if (DataGridView.DataManager.Count > base.Index)
96 return DataGridView.DataManager[base.Index];
103 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
104 [NotifyParentProperty (true)]
105 public override DataGridViewCellStyle DefaultCellStyle {
106 get { return base.DefaultCellStyle; }
108 if (DefaultCellStyle != value) {
109 base.DefaultCellStyle = value;
110 if (DataGridView != null) {
111 DataGridView.OnRowDefaultCellStyleChanged(new DataGridViewRowEventArgs(this));
118 public override bool Displayed {
121 throw new InvalidOperationException ("Getting the Displayed property of a shared row is not a valid operation.");
123 return base.Displayed;
128 [NotifyParentProperty (true)]
129 public int DividerHeight {
130 get { return dividerHeight; }
131 set { dividerHeight = value; }
135 [NotifyParentProperty (true)]
136 public string ErrorText {
139 throw new InvalidOperationException ("Operation cannot be performed on a shared row.");
141 return errorText == null ? string.Empty : errorText;
144 if (errorText != value) {
146 if (DataGridView != null) {
147 DataGridView.OnRowErrorTextChanged(new DataGridViewRowEventArgs(this));
154 public override bool Frozen {
157 throw new InvalidOperationException ("Getting the Frozen property of a shared row is not a valid operation.");
161 set { base.Frozen = value; }
165 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
166 public DataGridViewRowHeaderCell HeaderCell {
167 get { return headerCell; }
169 if (headerCell != value) {
171 headerCell.SetOwningRow (this);
173 if (DataGridView != null) {
174 headerCell.SetDataGridView (DataGridView);
175 DataGridView.OnRowHeaderCellChanged(new DataGridViewRowEventArgs(this));
182 [NotifyParentProperty (true)]
186 if (DefaultCellStyle != null && DefaultCellStyle.Font != null) {
187 return DefaultCellStyle.Font.Height + 9;
189 if (Index >= 0 && InheritedStyle != null && InheritedStyle.Font != null) {
190 return InheritedStyle.Font.Height + 9;
192 return System.Windows.Forms.Control.DefaultFont.Height + 9;
197 explicit_height = value;
199 if (height != value) {
200 if (value < minimumHeight) {
201 throw new ArgumentOutOfRangeException("Height can't be less than MinimumHeight.");
204 if (DataGridView != null) {
205 DataGridView.Invalidate ();
206 DataGridView.OnRowHeightChanged(new DataGridViewRowEventArgs(this));
212 public override DataGridViewCellStyle InheritedStyle {
215 throw new InvalidOperationException ("Getting the InheritedStyle property of a shared row is not a valid operation.");
217 if (DataGridView == null) {
218 return DefaultCellStyle;
221 if (DefaultCellStyle == null) {
222 return DataGridView.DefaultCellStyle;
225 DataGridViewCellStyle style = (DataGridViewCellStyle) DefaultCellStyle.Clone();
226 /////// Combination with dataGridView.DefaultCellStyle
234 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
235 public bool IsNewRow {
237 if (DataGridView != null && DataGridView.Rows[DataGridView.Rows.Count - 1] == this && DataGridView.NewRowIndex == Index) {
244 internal bool IsShared {
246 return Index == -1 && DataGridView != null;
251 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
252 public int MinimumHeight {
253 get { return minimumHeight; }
255 if (minimumHeight != value) {
256 if (value < 2 || value > Int32.MaxValue) {
257 throw new ArgumentOutOfRangeException("MinimumHeight should be between 2 and Int32.MaxValue.");
259 minimumHeight = value;
260 if (DataGridView != null) {
261 DataGridView.OnRowMinimumHeightChanged(new DataGridViewRowEventArgs(this));
268 [DefaultValue (false)]
269 [NotifyParentProperty (true)]
270 public override bool ReadOnly {
273 throw new InvalidOperationException ("Getting the ReadOnly property of a shared row is not a valid operation.");
275 if (DataGridView != null && DataGridView.ReadOnly)
278 return base.ReadOnly;
280 set { base.ReadOnly = value; }
283 [NotifyParentProperty (true)]
284 public override DataGridViewTriState Resizable {
287 throw new InvalidOperationException ("Getting the Resizable property of a shared row is not a valid operation.");
289 return base.Resizable;
291 set { base.Resizable = value; }
294 public override bool Selected {
297 throw new InvalidOperationException ("Getting the Selected property of a shared row is not a valid operation.");
299 return base.Selected;
303 throw new InvalidOperationException("The row is a shared row.");
305 if (DataGridView == null) {
306 throw new InvalidOperationException("The row has not been added to a DataGridView control.");
308 base.Selected = value;
312 public override DataGridViewElementStates State {
315 throw new InvalidOperationException ("Getting the State property of a shared row is not a valid operation.");
322 public override bool Visible {
325 throw new InvalidOperationException ("Getting the Visible property of a shared row is not a valid operation.");
330 if (IsNewRow && value == false) {
331 throw new InvalidOperationException("Cant make invisible a new row.");
333 if (!value && DataGridView != null && DataGridView.DataManager != null &&
334 DataGridView.DataManager.Position == Index)
335 throw new InvalidOperationException("Row associated with the currency manager's position cannot be made invisible.");
337 base.Visible = value;
338 if (DataGridView != null)
339 DataGridView.Invalidate ();
343 [EditorBrowsable (EditorBrowsableState.Advanced)]
344 public virtual DataGridViewAdvancedBorderStyle AdjustRowHeaderBorderStyle (DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStyleInput, DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedRow, bool isLastVisibleRow)
346 throw new NotImplementedException();
349 public override object Clone ()
351 DataGridViewRow row = (DataGridViewRow)MemberwiseClone ();
353 row.HeaderCell = (DataGridViewRowHeaderCell)HeaderCell.Clone ();
356 row.cells = new DataGridViewCellCollection (row);
358 foreach (DataGridViewCell cell in cells)
359 row.cells.Add (cell.Clone () as DataGridViewCell);
361 row.SetDataGridView (null);
366 public void CreateCells (DataGridView dataGridView)
368 if (dataGridView == null) {
369 throw new ArgumentNullException("DataGridView is null.");
371 if (dataGridView.Rows.Contains(this)) {
372 throw new InvalidOperationException("The row already exists in the DataGridView.");
374 DataGridViewCellCollection newCellCollection = new DataGridViewCellCollection(this);
375 foreach (DataGridViewColumn column in dataGridView.Columns) {
376 if (column.CellTemplate == null) {
377 throw new InvalidOperationException("Cell template not set in column: " + column.Index.ToString() + ".");
379 newCellCollection.Add((DataGridViewCell) column.CellTemplate.Clone());
381 cells = newCellCollection;
384 public void CreateCells (DataGridView dataGridView, params object[] values)
386 if (values == null) {
387 throw new ArgumentNullException("values is null");
389 CreateCells(dataGridView);
390 for (int i = 0; i < values.Length; i++) {
391 cells[i].Value = values[i];
395 public ContextMenuStrip GetContextMenuStrip (int rowIndex)
397 if (rowIndex == -1) {
398 throw new InvalidOperationException("rowIndex is -1");
400 if (rowIndex < 0 || rowIndex >= DataGridView.Rows.Count) {
401 throw new ArgumentOutOfRangeException("rowIndex is out of range");
407 public string GetErrorText (int rowIndex)
412 public virtual int GetPreferredHeight (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth)
416 if (DataGridView != null)
417 row = DataGridView.Rows.SharedRow (rowIndex);
423 if (autoSizeRowMode == DataGridViewAutoSizeRowMode.AllCells || autoSizeRowMode == DataGridViewAutoSizeRowMode.RowHeader)
424 height = Math.Max (height, row.HeaderCell.PreferredSize.Height);
426 if (autoSizeRowMode == DataGridViewAutoSizeRowMode.AllCells || autoSizeRowMode == DataGridViewAutoSizeRowMode.AllCellsExceptHeader)
427 foreach (DataGridViewCell cell in row.Cells)
428 height = Math.Max (height, cell.PreferredSize.Height);
433 [EditorBrowsable (EditorBrowsableState.Advanced)]
434 public virtual DataGridViewElementStates GetState (int rowIndex)
436 DataGridViewElementStates state = DataGridViewElementStates.None;
438 if (rowIndex == -1) {
439 state |= DataGridViewElementStates.Displayed;
441 if (DataGridView.ReadOnly)
442 state |= DataGridViewElementStates.ReadOnly;
443 if (DataGridView.AllowUserToResizeRows)
444 state |= DataGridViewElementStates.Resizable;
445 if (DataGridView.Visible)
446 state |= DataGridViewElementStates.Visible;
451 DataGridViewRow row = DataGridView.Rows[rowIndex];
454 state |= DataGridViewElementStates.Displayed;
456 state |= DataGridViewElementStates.Frozen;
458 state |= DataGridViewElementStates.ReadOnly;
459 if (row.Resizable == DataGridViewTriState.True || (row.Resizable == DataGridViewTriState.NotSet && DataGridView.AllowUserToResizeRows))
460 state |= DataGridViewElementStates.Resizable;
461 if (row.Resizable == DataGridViewTriState.True)
462 state |= DataGridViewElementStates.ResizableSet;
464 state |= DataGridViewElementStates.Selected;
466 state |= DataGridViewElementStates.Visible;
471 public bool SetValues (params object[] values)
473 if (values == null) {
474 throw new ArgumentNullException("vues is null");
476 if (DataGridView != null && DataGridView.VirtualMode) {
477 throw new InvalidOperationException("DataGridView is operating in virtual mode");
479 /////// COLUMNAS //////////
480 for (int i = 0; i < values.Length; i++) {
481 DataGridViewCell cell;
482 if (cells.Count > i) {
485 cell = new DataGridViewTextBoxCell ();
488 cell.Value = values[i];
495 public override string ToString ()
497 return this.GetType().Name + ", Band Index: " + base.Index.ToString();
500 protected virtual AccessibleObject CreateAccessibilityInstance ()
502 return new DataGridViewRowAccessibleObject(this);
505 [EditorBrowsable (EditorBrowsableState.Advanced)]
506 protected virtual DataGridViewCellCollection CreateCellsInstance ()
508 cells = new DataGridViewCellCollection(this);
512 [EditorBrowsable (EditorBrowsableState.Advanced)]
513 protected internal virtual void DrawFocus (Graphics graphics, Rectangle clipBounds, Rectangle bounds, int rowIndex, DataGridViewElementStates rowState, DataGridViewCellStyle cellStyle, bool cellsPaintSelectionBackground)
517 protected internal virtual void Paint (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow)
519 DataGridViewCellStyle style;
522 style = DataGridView.RowsDefaultCellStyle;
524 style = InheritedStyle;
526 DataGridViewRowPrePaintEventArgs pre = new DataGridViewRowPrePaintEventArgs (DataGridView, graphics, clipBounds, rowBounds, rowIndex, rowState, string.Empty, style, isFirstDisplayedRow, isLastVisibleRow);
527 pre.PaintParts = DataGridViewPaintParts.All;
529 DataGridView.OnRowPrePaint (pre);
531 // The user has elected for us to not do anything
535 if (DataGridView.RowHeadersVisible)
536 PaintHeader (graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, isFirstDisplayedRow, isLastVisibleRow, pre.PaintParts);
538 PaintCells (graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, isFirstDisplayedRow, isLastVisibleRow, pre.PaintParts);
540 DataGridViewRowPostPaintEventArgs post = new DataGridViewRowPostPaintEventArgs (DataGridView, graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, pre.ErrorText, style, isFirstDisplayedRow, isLastVisibleRow);
541 DataGridView.OnRowPostPaint (post);
544 [EditorBrowsable (EditorBrowsableState.Advanced)]
545 protected internal virtual void PaintCells (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow, DataGridViewPaintParts paintParts)
547 List<DataGridViewColumn> sortedColumns = DataGridView.Columns.ColumnDisplayIndexSortedArrayList;
549 Rectangle bounds = rowBounds;
551 // If row headers are visible, adjust our starting point
552 if (DataGridView.RowHeadersVisible) {
553 bounds.X += DataGridView.RowHeadersWidth;
554 bounds.Width -= DataGridView.RowHeadersWidth;
557 for (int i = DataGridView.first_col_index; i < sortedColumns.Count; i++) {
558 DataGridViewColumn col = sortedColumns[i];
566 bounds.Width = col.Width;
567 DataGridViewCell cell = Cells[col.Index];
569 if ((paintParts & DataGridViewPaintParts.Background) == DataGridViewPaintParts.Background)
570 graphics.FillRectangle (Brushes.White, bounds);
572 DataGridViewCellStyle style;
574 if (cell.RowIndex == -1)
575 style = DefaultCellStyle;
577 style = cell.InheritedStyle;
580 object formattedValue;
582 DataGridViewElementStates cellState;
584 if (cell.RowIndex == -1) {
585 // TODO: Look up value if databound.
587 formattedValue = null;
589 cellState = cell.State;
592 formattedValue = cell.FormattedValue;
593 errorText = cell.ErrorText;
594 cellState = cell.InheritedState;
597 DataGridViewAdvancedBorderStyle intermediateBorderStyle = (DataGridViewAdvancedBorderStyle)((ICloneable)DataGridView.AdvancedCellBorderStyle).Clone ();
598 DataGridViewAdvancedBorderStyle borderStyle = cell.AdjustCellBorderStyle (DataGridView.AdvancedCellBorderStyle, intermediateBorderStyle, true, true, cell.ColumnIndex == 0, cell.RowIndex == 0);
599 DataGridView.OnCellFormattingInternal (new DataGridViewCellFormattingEventArgs (cell.ColumnIndex, cell.RowIndex, value, cell.FormattedValueType, style));
602 cell.PaintWork (graphics, clipBounds, bounds, rowIndex, cellState, style, borderStyle, paintParts);
603 bounds.X += bounds.Width;
607 [EditorBrowsable (EditorBrowsableState.Advanced)]
608 protected internal virtual void PaintHeader (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow, DataGridViewPaintParts paintParts)
610 rowBounds.Width = DataGridView.RowHeadersWidth;
611 graphics.FillRectangle (Brushes.White, rowBounds);
613 HeaderCell.PaintWork (graphics, clipBounds, rowBounds, rowIndex, rowState, HeaderCell.InheritedStyle, DataGridView.AdvancedRowHeadersBorderStyle, paintParts);
616 internal override void SetDataGridView (DataGridView dataGridView)
618 base.SetDataGridView(dataGridView);
619 headerCell.SetDataGridView(dataGridView);
620 foreach (DataGridViewCell cell in cells)
621 cell.SetDataGridView (dataGridView);
624 internal override void SetState (DataGridViewElementStates state)
626 if (State != state) {
627 base.SetState(state);
628 if (DataGridView != null) {
629 DataGridView.OnRowStateChanged(this.Index, new DataGridViewRowStateChangedEventArgs(this, state));
634 // Set the row's height without overwriting the explicit_height, so we
635 // can go back to the user's requested height when they turn off AutoSize
636 internal void SetAutoSizeHeight (int height)
638 this.height = height;
640 if (DataGridView != null) {
641 DataGridView.Invalidate ();
642 DataGridView.OnRowHeightChanged (new DataGridViewRowEventArgs (this));
646 // If the user sets AutoSizeRowMode to None, reset every row to its explicit height
647 internal void ResetToExplicitHeight ()
649 this.height = explicit_height;
651 if (DataGridView != null)
652 DataGridView.OnRowHeightChanged (new DataGridViewRowEventArgs (this));
655 [ComVisibleAttribute(true)]
656 protected class DataGridViewRowAccessibleObject : AccessibleObject {
658 private DataGridViewRow dataGridViewRow;
660 public DataGridViewRowAccessibleObject ()
664 public DataGridViewRowAccessibleObject (DataGridViewRow owner)
666 this.dataGridViewRow = owner;
669 public override Rectangle Bounds {
670 get { throw new NotImplementedException(); }
673 public override string Name {
674 get { return "Index: " + dataGridViewRow.Index.ToString(); }
677 public DataGridViewRow Owner {
678 get { return dataGridViewRow; }
679 set { dataGridViewRow = value; }
682 public override AccessibleObject Parent {
683 get { return dataGridViewRow.AccessibilityObject; }
686 public override AccessibleRole Role {
687 get { return AccessibleRole.Row; }
690 public override AccessibleStates State {
692 if (dataGridViewRow.Selected) {
693 return AccessibleStates.Selected;
696 return AccessibleStates.Focused;
701 public override string Value {
703 if (dataGridViewRow.Cells.Count == 0) {
704 return "(Create New)";
707 foreach (DataGridViewCell cell in dataGridViewRow.Cells) {
708 result += cell.AccessibilityObject.Value;
714 public override AccessibleObject GetChild (int index) {
715 throw new NotImplementedException();
718 public override int GetChildCount () {
719 throw new NotImplementedException();
722 public override AccessibleObject GetFocused () {
726 public override AccessibleObject GetSelected () {
730 public override AccessibleObject Navigate (AccessibleNavigation navigationDirection) {
731 switch (navigationDirection) {
732 case AccessibleNavigation.Right:
734 case AccessibleNavigation.Left:
736 case AccessibleNavigation.Next:
738 case AccessibleNavigation.Previous:
740 case AccessibleNavigation.Up:
742 case AccessibleNavigation.Down:
750 public override void Select (AccessibleSelection flags) {
752 case AccessibleSelection.TakeFocus:
753 dataGridViewRow.DataGridView.Focus();
755 case AccessibleSelection.TakeSelection:
756 //dataGridViewRow.Focus();
758 case AccessibleSelection.AddSelection:
759 dataGridViewRow.DataGridView.SelectedRows.InternalAdd(dataGridViewRow);
761 case AccessibleSelection.RemoveSelection:
762 dataGridViewRow.DataGridView.SelectedRows.InternalRemove(dataGridViewRow);
769 internal class DataGridViewRowConverter : TypeConverter