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>
26 using System.ComponentModel;
28 using System.Runtime.InteropServices;
29 using System.Collections;
30 using System.Collections.Generic;
32 namespace System.Windows.Forms
34 [TypeConverter (typeof (DataGridViewRowConverter))]
35 public class DataGridViewRow : DataGridViewBand
37 private AccessibleObject accessibilityObject;
38 private DataGridViewCellCollection cells;
39 private ContextMenuStrip contextMenuStrip;
40 private int dividerHeight;
41 private string errorText;
42 private DataGridViewRowHeaderCell headerCell;
44 private int minimumHeight;
45 private int explicit_height;
47 public DataGridViewRow ()
49 cells = new DataGridViewCellCollection(this);
53 headerCell = new DataGridViewRowHeaderCell();
54 headerCell.SetOwningRow (this);
55 accessibilityObject = new AccessibleObject ();
56 SetState (DataGridViewElementStates.Visible);
60 public AccessibleObject AccessibilityObject {
61 get { return accessibilityObject; }
65 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
66 public DataGridViewCellCollection Cells {
71 public override ContextMenuStrip ContextMenuStrip {
74 throw new InvalidOperationException ("Operation cannot be performed on a shared row.");
76 return contextMenuStrip;
79 if (contextMenuStrip != value) {
80 contextMenuStrip = value;
81 if (DataGridView != null) {
82 DataGridView.OnRowContextMenuStripChanged(new DataGridViewRowEventArgs(this));
89 [EditorBrowsable (EditorBrowsableState.Advanced)]
90 public object DataBoundItem {
92 if (base.DataGridView != null && DataGridView.DataManager != null) {
93 if (DataGridView.DataManager.Count > base.Index)
94 return DataGridView.DataManager[base.Index];
101 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
102 [NotifyParentProperty (true)]
103 public override DataGridViewCellStyle DefaultCellStyle {
104 get { return base.DefaultCellStyle; }
106 if (DefaultCellStyle != value) {
107 base.DefaultCellStyle = value;
108 if (DataGridView != null) {
109 DataGridView.OnRowDefaultCellStyleChanged(new DataGridViewRowEventArgs(this));
116 public override bool Displayed {
119 throw new InvalidOperationException ("Getting the Displayed property of a shared row is not a valid operation.");
121 return base.Displayed;
126 [NotifyParentProperty (true)]
127 public int DividerHeight {
128 get { return dividerHeight; }
129 set { dividerHeight = value; }
133 [NotifyParentProperty (true)]
134 public string ErrorText {
137 throw new InvalidOperationException ("Operation cannot be performed on a shared row.");
139 return errorText == null ? string.Empty : errorText;
142 if (errorText != value) {
144 if (DataGridView != null) {
145 DataGridView.OnRowErrorTextChanged(new DataGridViewRowEventArgs(this));
152 public override bool Frozen {
155 throw new InvalidOperationException ("Getting the Frozen property of a shared row is not a valid operation.");
159 set { base.Frozen = value; }
163 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
164 public DataGridViewRowHeaderCell HeaderCell {
165 get { return headerCell; }
167 if (headerCell != value) {
169 headerCell.SetOwningRow (this);
171 if (DataGridView != null) {
172 headerCell.SetDataGridView (DataGridView);
173 DataGridView.OnRowHeaderCellChanged(new DataGridViewRowEventArgs(this));
180 [NotifyParentProperty (true)]
184 if (DefaultCellStyle != null && DefaultCellStyle.Font != null) {
185 return DefaultCellStyle.Font.Height + 9;
187 if (Index >= 0 && InheritedStyle != null && InheritedStyle.Font != null) {
188 return InheritedStyle.Font.Height + 9;
190 return System.Windows.Forms.Control.DefaultFont.Height + 9;
195 explicit_height = value;
197 if (height != value) {
198 if (value < minimumHeight) {
199 throw new ArgumentOutOfRangeException("Height can't be less than MinimumHeight.");
202 if (DataGridView != null) {
203 DataGridView.Invalidate ();
204 DataGridView.OnRowHeightChanged(new DataGridViewRowEventArgs(this));
210 public override DataGridViewCellStyle InheritedStyle {
213 throw new InvalidOperationException ("Getting the InheritedStyle property of a shared row is not a valid operation.");
215 if (DataGridView == null) {
216 return DefaultCellStyle;
219 if (DefaultCellStyle == null) {
220 return DataGridView.DefaultCellStyle;
223 DataGridViewCellStyle style = (DataGridViewCellStyle) DefaultCellStyle.Clone();
224 /////// Combination with dataGridView.DefaultCellStyle
232 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
233 public bool IsNewRow {
235 if (DataGridView != null && DataGridView.Rows[DataGridView.Rows.Count - 1] == this && DataGridView.NewRowIndex == Index) {
242 internal bool IsShared {
244 return Index == -1 && DataGridView != null;
249 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
250 public int MinimumHeight {
251 get { return minimumHeight; }
253 if (minimumHeight != value) {
254 if (value < 2 || value > Int32.MaxValue) {
255 throw new ArgumentOutOfRangeException("MinimumHeight should be between 2 and Int32.MaxValue.");
257 minimumHeight = value;
258 if (DataGridView != null) {
259 DataGridView.OnRowMinimumHeightChanged(new DataGridViewRowEventArgs(this));
266 [DefaultValue (false)]
267 [NotifyParentProperty (true)]
268 public override bool ReadOnly {
271 throw new InvalidOperationException ("Getting the ReadOnly property of a shared row is not a valid operation.");
273 if (DataGridView != null && DataGridView.ReadOnly)
276 return base.ReadOnly;
278 set { base.ReadOnly = value; }
281 [NotifyParentProperty (true)]
282 public override DataGridViewTriState Resizable {
285 throw new InvalidOperationException ("Getting the Resizable property of a shared row is not a valid operation.");
287 return base.Resizable;
289 set { base.Resizable = value; }
292 public override bool Selected {
295 throw new InvalidOperationException ("Getting the Selected property of a shared row is not a valid operation.");
297 return base.Selected;
301 throw new InvalidOperationException("The row is a shared row.");
303 if (DataGridView == null) {
304 throw new InvalidOperationException("The row has not been added to a DataGridView control.");
306 base.Selected = value;
310 public override DataGridViewElementStates State {
313 throw new InvalidOperationException ("Getting the State property of a shared row is not a valid operation.");
320 public override bool Visible {
323 throw new InvalidOperationException ("Getting the Visible property of a shared row is not a valid operation.");
328 if (IsNewRow && value == false) {
329 throw new InvalidOperationException("Cant make invisible a new row.");
331 if (!value && DataGridView != null && DataGridView.DataManager != null &&
332 DataGridView.DataManager.Position == Index)
333 throw new InvalidOperationException("Row associated with the currency manager's position cannot be made invisible.");
335 base.Visible = value;
336 if (DataGridView != null)
337 DataGridView.Invalidate ();
341 [EditorBrowsable (EditorBrowsableState.Advanced)]
342 public virtual DataGridViewAdvancedBorderStyle AdjustRowHeaderBorderStyle (DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStyleInput, DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedRow, bool isLastVisibleRow)
344 throw new NotImplementedException();
347 public override object Clone ()
349 DataGridViewRow row = (DataGridViewRow)MemberwiseClone ();
351 row.HeaderCell = (DataGridViewRowHeaderCell)HeaderCell.Clone ();
354 row.cells = new DataGridViewCellCollection (row);
356 foreach (DataGridViewCell cell in cells)
357 row.cells.Add (cell.Clone () as DataGridViewCell);
359 row.SetDataGridView (null);
364 public void CreateCells (DataGridView dataGridView)
366 if (dataGridView == null) {
367 throw new ArgumentNullException("DataGridView is null.");
369 if (dataGridView.Rows.Contains(this)) {
370 throw new InvalidOperationException("The row already exists in the DataGridView.");
372 DataGridViewCellCollection newCellCollection = new DataGridViewCellCollection(this);
373 foreach (DataGridViewColumn column in dataGridView.Columns) {
374 if (column.CellTemplate == null) {
375 throw new InvalidOperationException("Cell template not set in column: " + column.Index.ToString() + ".");
377 newCellCollection.Add((DataGridViewCell) column.CellTemplate.Clone());
379 cells = newCellCollection;
382 public void CreateCells (DataGridView dataGridView, params object[] values)
384 if (values == null) {
385 throw new ArgumentNullException("values is null");
387 CreateCells(dataGridView);
388 for (int i = 0; i < values.Length; i++) {
389 cells[i].Value = values[i];
393 public ContextMenuStrip GetContextMenuStrip (int rowIndex)
395 if (rowIndex == -1) {
396 throw new InvalidOperationException("rowIndex is -1");
398 if (rowIndex < 0 || rowIndex >= DataGridView.Rows.Count) {
399 throw new ArgumentOutOfRangeException("rowIndex is out of range");
405 public string GetErrorText (int rowIndex)
410 public virtual int GetPreferredHeight (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth)
414 if (DataGridView != null)
415 row = DataGridView.Rows.SharedRow (rowIndex);
421 if (autoSizeRowMode == DataGridViewAutoSizeRowMode.AllCells || autoSizeRowMode == DataGridViewAutoSizeRowMode.RowHeader)
422 height = Math.Max (height, row.HeaderCell.PreferredSize.Height);
424 if (autoSizeRowMode == DataGridViewAutoSizeRowMode.AllCells || autoSizeRowMode == DataGridViewAutoSizeRowMode.AllCellsExceptHeader)
425 foreach (DataGridViewCell cell in row.Cells)
426 height = Math.Max (height, cell.PreferredSize.Height);
431 [EditorBrowsable (EditorBrowsableState.Advanced)]
432 public virtual DataGridViewElementStates GetState (int rowIndex)
434 DataGridViewElementStates state = DataGridViewElementStates.None;
436 if (rowIndex == -1) {
437 state |= DataGridViewElementStates.Displayed;
439 if (DataGridView.ReadOnly)
440 state |= DataGridViewElementStates.ReadOnly;
441 if (DataGridView.AllowUserToResizeRows)
442 state |= DataGridViewElementStates.Resizable;
443 if (DataGridView.Visible)
444 state |= DataGridViewElementStates.Visible;
449 DataGridViewRow row = DataGridView.Rows[rowIndex];
452 state |= DataGridViewElementStates.Displayed;
454 state |= DataGridViewElementStates.Frozen;
456 state |= DataGridViewElementStates.ReadOnly;
457 if (row.Resizable == DataGridViewTriState.True || (row.Resizable == DataGridViewTriState.NotSet && DataGridView.AllowUserToResizeRows))
458 state |= DataGridViewElementStates.Resizable;
459 if (row.Resizable == DataGridViewTriState.True)
460 state |= DataGridViewElementStates.ResizableSet;
462 state |= DataGridViewElementStates.Selected;
464 state |= DataGridViewElementStates.Visible;
469 public bool SetValues (params object[] values)
471 if (values == null) {
472 throw new ArgumentNullException("vues is null");
474 if (DataGridView != null && DataGridView.VirtualMode) {
475 throw new InvalidOperationException("DataGridView is operating in virtual mode");
477 /////// COLUMNAS //////////
478 for (int i = 0; i < values.Length; i++) {
479 DataGridViewCell cell;
480 if (cells.Count > i) {
483 cell = new DataGridViewTextBoxCell ();
486 cell.Value = values[i];
493 public override string ToString ()
495 return this.GetType().Name + ", Band Index: " + base.Index.ToString();
498 protected virtual AccessibleObject CreateAccessibilityInstance ()
500 return new DataGridViewRowAccessibleObject(this);
503 [EditorBrowsable (EditorBrowsableState.Advanced)]
504 protected virtual DataGridViewCellCollection CreateCellsInstance ()
506 cells = new DataGridViewCellCollection(this);
510 [EditorBrowsable (EditorBrowsableState.Advanced)]
511 protected internal virtual void DrawFocus (Graphics graphics, Rectangle clipBounds, Rectangle bounds, int rowIndex, DataGridViewElementStates rowState, DataGridViewCellStyle cellStyle, bool cellsPaintSelectionBackground)
515 protected internal virtual void Paint (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow)
517 DataGridViewCellStyle style;
520 style = DataGridView.RowsDefaultCellStyle;
522 style = InheritedStyle;
524 DataGridViewRowPrePaintEventArgs pre = new DataGridViewRowPrePaintEventArgs (DataGridView, graphics, clipBounds, rowBounds, rowIndex, rowState, string.Empty, style, isFirstDisplayedRow, isLastVisibleRow);
525 pre.PaintParts = DataGridViewPaintParts.All;
527 DataGridView.OnRowPrePaint (pre);
529 // The user has elected for us to not do anything
533 if (DataGridView.RowHeadersVisible)
534 PaintHeader (graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, isFirstDisplayedRow, isLastVisibleRow, pre.PaintParts);
536 PaintCells (graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, isFirstDisplayedRow, isLastVisibleRow, pre.PaintParts);
538 DataGridViewRowPostPaintEventArgs post = new DataGridViewRowPostPaintEventArgs (DataGridView, graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, pre.ErrorText, style, isFirstDisplayedRow, isLastVisibleRow);
539 DataGridView.OnRowPostPaint (post);
542 [EditorBrowsable (EditorBrowsableState.Advanced)]
543 protected internal virtual void PaintCells (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow, DataGridViewPaintParts paintParts)
545 List<DataGridViewColumn> sortedColumns = DataGridView.Columns.ColumnDisplayIndexSortedArrayList;
547 Rectangle bounds = rowBounds;
549 // If row headers are visible, adjust our starting point
550 if (DataGridView.RowHeadersVisible) {
551 bounds.X += DataGridView.RowHeadersWidth;
552 bounds.Width -= DataGridView.RowHeadersWidth;
555 for (int i = DataGridView.first_col_index; i < sortedColumns.Count; i++) {
556 DataGridViewColumn col = sortedColumns[i];
564 bounds.Width = col.Width;
565 DataGridViewCell cell = Cells[col.Index];
567 if ((paintParts & DataGridViewPaintParts.Background) == DataGridViewPaintParts.Background)
568 graphics.FillRectangle (Brushes.White, bounds);
570 DataGridViewCellStyle style;
572 if (cell.RowIndex == -1)
573 style = DefaultCellStyle;
575 style = cell.InheritedStyle;
578 DataGridViewElementStates cellState;
580 if (cell.RowIndex == -1) {
581 // TODO: Look up value if databound.
583 cellState = cell.State;
586 cellState = cell.InheritedState;
589 DataGridViewAdvancedBorderStyle intermediateBorderStyle = (DataGridViewAdvancedBorderStyle)((ICloneable)DataGridView.AdvancedCellBorderStyle).Clone ();
590 DataGridViewAdvancedBorderStyle borderStyle = cell.AdjustCellBorderStyle (DataGridView.AdvancedCellBorderStyle, intermediateBorderStyle, true, true, cell.ColumnIndex == 0, cell.RowIndex == 0);
591 DataGridView.OnCellFormattingInternal (new DataGridViewCellFormattingEventArgs (cell.ColumnIndex, cell.RowIndex, value, cell.FormattedValueType, style));
594 cell.PaintWork (graphics, clipBounds, bounds, rowIndex, cellState, style, borderStyle, paintParts);
595 bounds.X += bounds.Width;
599 [EditorBrowsable (EditorBrowsableState.Advanced)]
600 protected internal virtual void PaintHeader (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow, DataGridViewPaintParts paintParts)
602 rowBounds.Width = DataGridView.RowHeadersWidth;
603 graphics.FillRectangle (Brushes.White, rowBounds);
605 HeaderCell.PaintWork (graphics, clipBounds, rowBounds, rowIndex, rowState, HeaderCell.InheritedStyle, DataGridView.AdvancedRowHeadersBorderStyle, paintParts);
608 internal override void SetDataGridView (DataGridView dataGridView)
610 base.SetDataGridView(dataGridView);
611 headerCell.SetDataGridView(dataGridView);
612 foreach (DataGridViewCell cell in cells)
613 cell.SetDataGridView (dataGridView);
616 internal override void SetState (DataGridViewElementStates state)
618 if (State != state) {
619 base.SetState(state);
620 if (DataGridView != null) {
621 DataGridView.OnRowStateChanged(this.Index, new DataGridViewRowStateChangedEventArgs(this, state));
626 // Set the row's height without overwriting the explicit_height, so we
627 // can go back to the user's requested height when they turn off AutoSize
628 internal void SetAutoSizeHeight (int height)
630 this.height = height;
632 if (DataGridView != null) {
633 DataGridView.Invalidate ();
634 DataGridView.OnRowHeightChanged (new DataGridViewRowEventArgs (this));
638 // If the user sets AutoSizeRowMode to None, reset every row to its explicit height
639 internal void ResetToExplicitHeight ()
641 this.height = explicit_height;
643 if (DataGridView != null)
644 DataGridView.OnRowHeightChanged (new DataGridViewRowEventArgs (this));
647 [ComVisibleAttribute(true)]
648 protected class DataGridViewRowAccessibleObject : AccessibleObject {
650 private DataGridViewRow dataGridViewRow;
652 public DataGridViewRowAccessibleObject ()
656 public DataGridViewRowAccessibleObject (DataGridViewRow owner)
658 this.dataGridViewRow = owner;
661 public override Rectangle Bounds {
662 get { throw new NotImplementedException(); }
665 public override string Name {
666 get { return "Index: " + dataGridViewRow.Index.ToString(); }
669 public DataGridViewRow Owner {
670 get { return dataGridViewRow; }
671 set { dataGridViewRow = value; }
674 public override AccessibleObject Parent {
675 get { return dataGridViewRow.AccessibilityObject; }
678 public override AccessibleRole Role {
679 get { return AccessibleRole.Row; }
682 public override AccessibleStates State {
684 if (dataGridViewRow.Selected) {
685 return AccessibleStates.Selected;
688 return AccessibleStates.Focused;
693 public override string Value {
695 if (dataGridViewRow.Cells.Count == 0) {
696 return "(Create New)";
699 foreach (DataGridViewCell cell in dataGridViewRow.Cells) {
700 result += cell.AccessibilityObject.Value;
706 public override AccessibleObject GetChild (int index) {
707 throw new NotImplementedException();
710 public override int GetChildCount () {
711 throw new NotImplementedException();
714 public override AccessibleObject GetFocused () {
718 public override AccessibleObject GetSelected () {
722 public override AccessibleObject Navigate (AccessibleNavigation navigationDirection) {
723 switch (navigationDirection) {
724 case AccessibleNavigation.Right:
726 case AccessibleNavigation.Left:
728 case AccessibleNavigation.Next:
730 case AccessibleNavigation.Previous:
732 case AccessibleNavigation.Up:
734 case AccessibleNavigation.Down:
742 public override void Select (AccessibleSelection flags) {
744 case AccessibleSelection.TakeFocus:
745 dataGridViewRow.DataGridView.Focus();
747 case AccessibleSelection.TakeSelection:
748 //dataGridViewRow.Focus();
750 case AccessibleSelection.AddSelection:
751 dataGridViewRow.DataGridView.SelectedRows.InternalAdd(dataGridViewRow);
753 case AccessibleSelection.RemoveSelection:
754 dataGridViewRow.DataGridView.SelectedRows.InternalRemove(dataGridViewRow);
761 internal class DataGridViewRowConverter : TypeConverter