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 height = minimumHeight;
203 if (DataGridView != null) {
204 DataGridView.Invalidate ();
205 DataGridView.OnRowHeightChanged(new DataGridViewRowEventArgs(this));
211 public override DataGridViewCellStyle InheritedStyle {
214 throw new InvalidOperationException ("Getting the InheritedStyle property of a shared row is not a valid operation.");
216 if (DataGridView == null) {
217 return DefaultCellStyle;
220 if (DefaultCellStyle == null) {
221 return DataGridView.DefaultCellStyle;
224 DataGridViewCellStyle style = (DataGridViewCellStyle) DefaultCellStyle.Clone();
225 /////// Combination with dataGridView.DefaultCellStyle
233 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
234 public bool IsNewRow {
236 if (DataGridView != null && DataGridView.Rows[DataGridView.Rows.Count - 1] == this && DataGridView.NewRowIndex == Index) {
243 internal bool IsShared {
245 return Index == -1 && DataGridView != null;
250 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
251 public int MinimumHeight {
252 get { return minimumHeight; }
254 if (minimumHeight != value) {
255 if (value < 2 || value > Int32.MaxValue) {
256 throw new ArgumentOutOfRangeException("MinimumHeight should be between 2 and Int32.MaxValue.");
258 if (height < value) {
259 // don't let height get less than minimumHeight!
262 minimumHeight = value;
263 if (DataGridView != null) {
264 DataGridView.OnRowMinimumHeightChanged(new DataGridViewRowEventArgs(this));
271 [DefaultValue (false)]
272 [NotifyParentProperty (true)]
273 public override bool ReadOnly {
276 throw new InvalidOperationException ("Getting the ReadOnly property of a shared row is not a valid operation.");
278 if (DataGridView != null && DataGridView.ReadOnly)
281 return base.ReadOnly;
283 set { base.ReadOnly = value; }
286 [NotifyParentProperty (true)]
287 public override DataGridViewTriState Resizable {
290 throw new InvalidOperationException ("Getting the Resizable property of a shared row is not a valid operation.");
292 return base.Resizable;
294 set { base.Resizable = value; }
297 public override bool Selected {
300 throw new InvalidOperationException ("Getting the Selected property of a shared row is not a valid operation.");
302 return base.Selected;
306 throw new InvalidOperationException("The row is a shared row.");
308 if (DataGridView == null) {
309 throw new InvalidOperationException("The row has not been added to a DataGridView control.");
311 base.Selected = value;
315 public override DataGridViewElementStates State {
318 throw new InvalidOperationException ("Getting the State property of a shared row is not a valid operation.");
325 public override bool Visible {
328 throw new InvalidOperationException ("Getting the Visible property of a shared row is not a valid operation.");
333 if (IsNewRow && value == false) {
334 throw new InvalidOperationException("Cant make invisible a new row.");
336 if (!value && DataGridView != null && DataGridView.DataManager != null &&
337 DataGridView.DataManager.Position == Index)
338 throw new InvalidOperationException("Row associated with the currency manager's position cannot be made invisible.");
340 base.Visible = value;
341 if (DataGridView != null)
342 DataGridView.Invalidate ();
346 [EditorBrowsable (EditorBrowsableState.Advanced)]
347 public virtual DataGridViewAdvancedBorderStyle AdjustRowHeaderBorderStyle (DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStyleInput, DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedRow, bool isLastVisibleRow)
349 throw new NotImplementedException();
352 public override object Clone ()
354 DataGridViewRow row = (DataGridViewRow)MemberwiseClone ();
356 row.HeaderCell = (DataGridViewRowHeaderCell)HeaderCell.Clone ();
359 row.cells = new DataGridViewCellCollection (row);
361 foreach (DataGridViewCell cell in cells)
362 row.cells.Add (cell.Clone () as DataGridViewCell);
364 row.SetDataGridView (null);
369 public void CreateCells (DataGridView dataGridView)
371 if (dataGridView == null) {
372 throw new ArgumentNullException("DataGridView is null.");
374 if (dataGridView.Rows.Contains(this)) {
375 throw new InvalidOperationException("The row already exists in the DataGridView.");
377 DataGridViewCellCollection newCellCollection = new DataGridViewCellCollection(this);
378 foreach (DataGridViewColumn column in dataGridView.Columns) {
379 if (column.CellTemplate == null) {
380 throw new InvalidOperationException("Cell template not set in column: " + column.Index.ToString() + ".");
382 newCellCollection.Add((DataGridViewCell) column.CellTemplate.Clone());
384 cells = newCellCollection;
387 public void CreateCells (DataGridView dataGridView, params object[] values)
389 if (values == null) {
390 throw new ArgumentNullException("values is null");
392 CreateCells(dataGridView);
393 for (int i = 0; i < values.Length; i++) {
394 cells[i].Value = values[i];
398 public ContextMenuStrip GetContextMenuStrip (int rowIndex)
400 if (rowIndex == -1) {
401 throw new InvalidOperationException("rowIndex is -1");
403 if (rowIndex < 0 || rowIndex >= DataGridView.Rows.Count) {
404 throw new ArgumentOutOfRangeException("rowIndex is out of range");
410 public string GetErrorText (int rowIndex)
415 public virtual int GetPreferredHeight (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth)
419 if (DataGridView != null)
420 row = DataGridView.Rows.SharedRow (rowIndex);
426 if (autoSizeRowMode == DataGridViewAutoSizeRowMode.AllCells || autoSizeRowMode == DataGridViewAutoSizeRowMode.RowHeader)
427 height = Math.Max (height, row.HeaderCell.PreferredSize.Height);
429 if (autoSizeRowMode == DataGridViewAutoSizeRowMode.AllCells || autoSizeRowMode == DataGridViewAutoSizeRowMode.AllCellsExceptHeader)
430 foreach (DataGridViewCell cell in row.Cells)
431 height = Math.Max (height, cell.PreferredSize.Height);
436 [EditorBrowsable (EditorBrowsableState.Advanced)]
437 public virtual DataGridViewElementStates GetState (int rowIndex)
439 DataGridViewElementStates state = DataGridViewElementStates.None;
441 if (rowIndex == -1) {
442 state |= DataGridViewElementStates.Displayed;
444 if (DataGridView.ReadOnly)
445 state |= DataGridViewElementStates.ReadOnly;
446 if (DataGridView.AllowUserToResizeRows)
447 state |= DataGridViewElementStates.Resizable;
448 if (DataGridView.Visible)
449 state |= DataGridViewElementStates.Visible;
454 DataGridViewRow row = DataGridView.Rows[rowIndex];
457 state |= DataGridViewElementStates.Displayed;
459 state |= DataGridViewElementStates.Frozen;
461 state |= DataGridViewElementStates.ReadOnly;
462 if (row.Resizable == DataGridViewTriState.True || (row.Resizable == DataGridViewTriState.NotSet && DataGridView.AllowUserToResizeRows))
463 state |= DataGridViewElementStates.Resizable;
464 if (row.Resizable == DataGridViewTriState.True)
465 state |= DataGridViewElementStates.ResizableSet;
467 state |= DataGridViewElementStates.Selected;
469 state |= DataGridViewElementStates.Visible;
474 public bool SetValues (params object[] values)
476 if (values == null) {
477 throw new ArgumentNullException("vues is null");
479 if (DataGridView != null && DataGridView.VirtualMode) {
480 throw new InvalidOperationException("DataGridView is operating in virtual mode");
482 /////// COLUMNAS //////////
483 for (int i = 0; i < values.Length; i++) {
484 DataGridViewCell cell;
485 if (cells.Count > i) {
488 cell = new DataGridViewTextBoxCell ();
491 cell.Value = values[i];
498 public override string ToString ()
500 return this.GetType().Name + ", Band Index: " + base.Index.ToString();
503 protected virtual AccessibleObject CreateAccessibilityInstance ()
505 return new DataGridViewRowAccessibleObject(this);
508 [EditorBrowsable (EditorBrowsableState.Advanced)]
509 protected virtual DataGridViewCellCollection CreateCellsInstance ()
511 cells = new DataGridViewCellCollection(this);
515 [EditorBrowsable (EditorBrowsableState.Advanced)]
516 protected internal virtual void DrawFocus (Graphics graphics, Rectangle clipBounds, Rectangle bounds, int rowIndex, DataGridViewElementStates rowState, DataGridViewCellStyle cellStyle, bool cellsPaintSelectionBackground)
520 protected internal virtual void Paint (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow)
522 DataGridViewCellStyle style;
525 style = DataGridView.RowsDefaultCellStyle;
527 style = InheritedStyle;
529 DataGridViewRowPrePaintEventArgs pre = new DataGridViewRowPrePaintEventArgs (DataGridView, graphics, clipBounds, rowBounds, rowIndex, rowState, string.Empty, style, isFirstDisplayedRow, isLastVisibleRow);
530 pre.PaintParts = DataGridViewPaintParts.All;
532 DataGridView.OnRowPrePaint (pre);
534 // The user has elected for us to not do anything
538 if (DataGridView.RowHeadersVisible)
539 PaintHeader (graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, isFirstDisplayedRow, isLastVisibleRow, pre.PaintParts);
541 PaintCells (graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, isFirstDisplayedRow, isLastVisibleRow, pre.PaintParts);
543 DataGridViewRowPostPaintEventArgs post = new DataGridViewRowPostPaintEventArgs (DataGridView, graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, pre.ErrorText, style, isFirstDisplayedRow, isLastVisibleRow);
544 DataGridView.OnRowPostPaint (post);
547 [EditorBrowsable (EditorBrowsableState.Advanced)]
548 protected internal virtual void PaintCells (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow, DataGridViewPaintParts paintParts)
550 List<DataGridViewColumn> sortedColumns = DataGridView.Columns.ColumnDisplayIndexSortedArrayList;
552 Rectangle bounds = rowBounds;
554 // If row headers are visible, adjust our starting point
555 if (DataGridView.RowHeadersVisible) {
556 bounds.X += DataGridView.RowHeadersWidth;
557 bounds.Width -= DataGridView.RowHeadersWidth;
560 for (int i = DataGridView.first_col_index; i < sortedColumns.Count; i++) {
561 DataGridViewColumn col = sortedColumns[i];
569 bounds.Width = col.Width;
570 DataGridViewCell cell = Cells[col.Index];
572 if ((paintParts & DataGridViewPaintParts.Background) == DataGridViewPaintParts.Background)
573 graphics.FillRectangle (Brushes.White, bounds);
575 DataGridViewCellStyle style;
577 if (cell.RowIndex == -1)
578 style = DefaultCellStyle;
580 style = cell.InheritedStyle;
583 DataGridViewElementStates cellState;
585 if (cell.RowIndex == -1) {
586 // TODO: Look up value if databound.
588 cellState = cell.State;
591 cellState = cell.InheritedState;
594 DataGridViewAdvancedBorderStyle intermediateBorderStyle = (DataGridViewAdvancedBorderStyle)((ICloneable)DataGridView.AdvancedCellBorderStyle).Clone ();
595 DataGridViewAdvancedBorderStyle borderStyle = cell.AdjustCellBorderStyle (DataGridView.AdvancedCellBorderStyle, intermediateBorderStyle, true, true, cell.ColumnIndex == 0, cell.RowIndex == 0);
596 DataGridView.OnCellFormattingInternal (new DataGridViewCellFormattingEventArgs (cell.ColumnIndex, cell.RowIndex, value, cell.FormattedValueType, style));
599 cell.PaintWork (graphics, clipBounds, bounds, rowIndex, cellState, style, borderStyle, paintParts);
600 bounds.X += bounds.Width;
604 [EditorBrowsable (EditorBrowsableState.Advanced)]
605 protected internal virtual void PaintHeader (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow, DataGridViewPaintParts paintParts)
607 rowBounds.Width = DataGridView.RowHeadersWidth;
608 graphics.FillRectangle (Brushes.White, rowBounds);
610 HeaderCell.PaintWork (graphics, clipBounds, rowBounds, rowIndex, rowState, HeaderCell.InheritedStyle, DataGridView.AdvancedRowHeadersBorderStyle, paintParts);
613 internal override void SetDataGridView (DataGridView dataGridView)
615 base.SetDataGridView(dataGridView);
616 headerCell.SetDataGridView(dataGridView);
617 foreach (DataGridViewCell cell in cells)
618 cell.SetDataGridView (dataGridView);
621 internal override void SetState (DataGridViewElementStates state)
623 if (State != state) {
624 base.SetState(state);
625 if (DataGridView != null) {
626 DataGridView.OnRowStateChanged(this.Index, new DataGridViewRowStateChangedEventArgs(this, state));
631 // Set the row's height without overwriting the explicit_height, so we
632 // can go back to the user's requested height when they turn off AutoSize
633 internal void SetAutoSizeHeight (int height)
635 this.height = height;
637 if (DataGridView != null) {
638 DataGridView.Invalidate ();
639 DataGridView.OnRowHeightChanged (new DataGridViewRowEventArgs (this));
643 // If the user sets AutoSizeRowMode to None, reset every row to its explicit height
644 internal void ResetToExplicitHeight ()
646 this.height = explicit_height;
648 if (DataGridView != null)
649 DataGridView.OnRowHeightChanged (new DataGridViewRowEventArgs (this));
652 [ComVisibleAttribute(true)]
653 protected class DataGridViewRowAccessibleObject : AccessibleObject {
655 private DataGridViewRow dataGridViewRow;
657 public DataGridViewRowAccessibleObject ()
661 public DataGridViewRowAccessibleObject (DataGridViewRow owner)
663 this.dataGridViewRow = owner;
666 public override Rectangle Bounds {
667 get { throw new NotImplementedException(); }
670 public override string Name {
671 get { return "Index: " + dataGridViewRow.Index.ToString(); }
674 public DataGridViewRow Owner {
675 get { return dataGridViewRow; }
676 set { dataGridViewRow = value; }
679 public override AccessibleObject Parent {
680 get { return dataGridViewRow.AccessibilityObject; }
683 public override AccessibleRole Role {
684 get { return AccessibleRole.Row; }
687 public override AccessibleStates State {
689 if (dataGridViewRow.Selected) {
690 return AccessibleStates.Selected;
693 return AccessibleStates.Focused;
698 public override string Value {
700 if (dataGridViewRow.Cells.Count == 0) {
701 return "(Create New)";
704 foreach (DataGridViewCell cell in dataGridViewRow.Cells) {
705 result += cell.AccessibilityObject.Value;
711 public override AccessibleObject GetChild (int index) {
712 throw new NotImplementedException();
715 public override int GetChildCount () {
716 throw new NotImplementedException();
719 public override AccessibleObject GetFocused () {
723 public override AccessibleObject GetSelected () {
727 public override AccessibleObject Navigate (AccessibleNavigation navigationDirection) {
728 switch (navigationDirection) {
729 case AccessibleNavigation.Right:
731 case AccessibleNavigation.Left:
733 case AccessibleNavigation.Next:
735 case AccessibleNavigation.Previous:
737 case AccessibleNavigation.Up:
739 case AccessibleNavigation.Down:
747 public override void Select (AccessibleSelection flags) {
749 case AccessibleSelection.TakeFocus:
750 dataGridViewRow.DataGridView.Focus();
752 case AccessibleSelection.TakeSelection:
753 //dataGridViewRow.Focus();
755 case AccessibleSelection.AddSelection:
756 dataGridViewRow.DataGridView.SelectedRows.InternalAdd(dataGridViewRow);
758 case AccessibleSelection.RemoveSelection:
759 dataGridViewRow.DataGridView.SelectedRows.InternalRemove(dataGridViewRow);
766 internal class DataGridViewRowConverter : TypeConverter