1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
23 // Pedro MartÃnez Juliá <pedromj@gmail.com>
29 using System.ComponentModel;
31 using System.Runtime.InteropServices;
32 using System.Collections;
34 namespace System.Windows.Forms {
36 [TypeConverter (typeof (DataGridRowConverter))]
37 public class DataGridViewRow : DataGridViewBand {
39 private AccessibleObject accessibilityObject;
40 private DataGridViewCellCollection cells;
41 private ContextMenuStrip contextMenuStrip;
42 private object dataBoundItem;
43 private int dividerHeight;
44 private string errorText;
45 private DataGridViewRowHeaderCell headerCell;
47 private int minimumHeight;
49 public DataGridViewRow ()
51 cells = new DataGridViewCellCollection(this);
54 headerCell = new DataGridViewRowHeaderCell();
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 {
91 get { return dataBoundItem; }
95 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
96 [NotifyParentProperty (true)]
97 public override DataGridViewCellStyle DefaultCellStyle {
98 get { return base.DefaultCellStyle; }
100 if (DefaultCellStyle != value) {
101 base.DefaultCellStyle = value;
102 if (DataGridView != null) {
103 DataGridView.OnRowDefaultCellStyleChanged(new DataGridViewRowEventArgs(this));
110 public override bool Displayed {
113 throw new InvalidOperationException ("Getting the Displayed property of a shared row is not a valid operation.");
115 return base.Displayed;
120 [NotifyParentProperty (true)]
121 public int DividerHeight {
122 get { return dividerHeight; }
123 set { dividerHeight = value; }
127 [NotifyParentProperty (true)]
128 public string ErrorText {
131 throw new InvalidOperationException ("Operation cannot be performed on a shared row.");
133 return errorText == null ? string.Empty : errorText;
136 if (errorText != value) {
138 if (DataGridView != null) {
139 DataGridView.OnRowErrorTextChanged(new DataGridViewRowEventArgs(this));
146 public override bool Frozen {
149 throw new InvalidOperationException ("Getting the Frozen property of a shared row is not a valid operation.");
153 set { base.Frozen = value; }
157 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
158 public DataGridViewRowHeaderCell HeaderCell {
159 get { return headerCell; }
161 if (headerCell != value) {
163 if (DataGridView != null) {
164 DataGridView.OnRowHeaderCellChanged(new DataGridViewRowEventArgs(this));
171 [NotifyParentProperty (true)]
175 if (DefaultCellStyle != null && DefaultCellStyle.Font != null) {
176 return DefaultCellStyle.Font.Height + 9;
178 if (Index >= 0 && InheritedStyle != null && InheritedStyle.Font != null) {
179 return InheritedStyle.Font.Height + 9;
181 return System.Windows.Forms.Control.DefaultFont.Height + 9;
186 if (height != value) {
187 if (value < minimumHeight) {
188 throw new ArgumentOutOfRangeException("Height can't be less than MinimumHeight.");
191 if (DataGridView != null) {
192 DataGridView.OnRowHeightChanged(new DataGridViewRowEventArgs(this));
198 public override DataGridViewCellStyle InheritedStyle {
201 throw new InvalidOperationException ("Getting the InheritedStyle property of a shared row is not a valid operation.");
203 if (DataGridView == null) {
204 return DefaultCellStyle;
207 if (DefaultCellStyle == null) {
208 return DataGridView.DefaultCellStyle;
211 DataGridViewCellStyle style = (DataGridViewCellStyle) DefaultCellStyle.Clone();
212 /////// Combination with dataGridView.DefaultCellStyle
220 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
221 public bool IsNewRow {
223 if (DataGridView != null && DataGridView.Rows[DataGridView.Rows.Count - 1] == this && DataGridView.NewRowIndex == Index) {
230 internal bool IsShared {
232 return Index == -1 && DataGridView != null;
237 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
238 public int MinimumHeight {
239 get { return minimumHeight; }
241 if (minimumHeight != value) {
242 if (value < 2 || value > Int32.MaxValue) {
243 throw new ArgumentOutOfRangeException("MinimumHeight should be between 2 and Int32.MaxValue.");
245 minimumHeight = value;
246 if (DataGridView != null) {
247 DataGridView.OnRowMinimumHeightChanged(new DataGridViewRowEventArgs(this));
254 [DefaultValue (false)]
255 [NotifyParentProperty (true)]
256 public override bool ReadOnly {
259 throw new InvalidOperationException ("Getting the ReadOnly property of a shared row is not a valid operation.");
261 if (DataGridView != null && DataGridView.ReadOnly)
264 return base.ReadOnly;
266 set { base.ReadOnly = value; }
269 [NotifyParentProperty (true)]
270 public override DataGridViewTriState Resizable {
273 throw new InvalidOperationException ("Getting the Resizable property of a shared row is not a valid operation.");
275 return base.Resizable;
277 set { base.Resizable = value; }
280 public override bool Selected {
283 throw new InvalidOperationException ("Getting the Selected property of a shared row is not a valid operation.");
285 return base.Selected;
289 throw new InvalidOperationException("The row is a shared row.");
291 if (DataGridView == null) {
292 throw new InvalidOperationException("The row has not been added to a DataGridView control.");
294 base.Selected = value;
298 public override DataGridViewElementStates State {
301 throw new InvalidOperationException ("Getting the State property of a shared row is not a valid operation.");
308 public override bool Visible {
311 throw new InvalidOperationException ("Getting the Visible property of a shared row is not a valid operation.");
316 if (IsNewRow && value == false) {
317 throw new InvalidOperationException("Cant make invisible a new row.");
319 base.Visible = value;
323 [EditorBrowsable (EditorBrowsableState.Advanced)]
324 public virtual DataGridViewAdvancedBorderStyle AdjustRowHeaderBorderStyle (DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStyleInput, DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedRow, bool isLastVisibleRow)
326 throw new NotImplementedException();
329 public override object Clone ()
331 DataGridViewRow row = (DataGridViewRow) MemberwiseClone();
332 row.cells = new DataGridViewCellCollection(row);
333 foreach (DataGridViewCell cell in cells) {
334 row.cells.Add(cell.Clone() as DataGridViewCell);
339 public void CreateCells (DataGridView dataGridView)
341 if (dataGridView == null) {
342 throw new ArgumentNullException("DataGridView is null.");
344 if (dataGridView.Rows.Contains(this)) {
345 throw new InvalidOperationException("The row already exists in the DataGridView.");
347 DataGridViewCellCollection newCellCollection = new DataGridViewCellCollection(this);
348 foreach (DataGridViewColumn column in dataGridView.Columns) {
349 if (column.CellTemplate == null) {
350 throw new InvalidOperationException("Cell template not set in column: " + column.Index.ToString() + ".");
352 newCellCollection.Add((DataGridViewCell) column.CellTemplate.Clone());
354 cells = newCellCollection;
357 public void CreateCells (DataGridView dataGridView, params object[] values)
359 if (values == null) {
360 throw new ArgumentNullException("values is null");
362 CreateCells(dataGridView);
363 for (int i = 0; i < values.Length; i++) {
364 cells[i].Value = values[i];
368 public ContextMenuStrip GetContextMenuStrip (int rowIndex)
370 if (rowIndex == -1) {
371 throw new InvalidOperationException("rowIndex is -1");
373 if (rowIndex < 0 || rowIndex >= DataGridView.Rows.Count) {
374 throw new ArgumentOutOfRangeException("rowIndex is out of range");
380 public string GetErrorText (int rowIndex)
385 public virtual int GetPreferredHeight (int rowIndex, DataGridViewAutoSizeRowMode autoSizeRowMode, bool fixedWidth)
387 throw new NotImplementedException();
390 [EditorBrowsable (EditorBrowsableState.Advanced)]
391 public virtual DataGridViewElementStates GetState (int rowIndex)
393 DataGridViewElementStates state = DataGridViewElementStates.None;
395 if (rowIndex == -1) {
396 state |= DataGridViewElementStates.Displayed;
398 if (DataGridView.ReadOnly)
399 state |= DataGridViewElementStates.ReadOnly;
400 if (DataGridView.AllowUserToResizeRows)
401 state |= DataGridViewElementStates.Resizable;
402 if (DataGridView.Visible)
403 state |= DataGridViewElementStates.Visible;
408 DataGridViewRow row = DataGridView.Rows[rowIndex];
411 state |= DataGridViewElementStates.Displayed;
413 state |= DataGridViewElementStates.Frozen;
415 state |= DataGridViewElementStates.ReadOnly;
416 if (row.Resizable == DataGridViewTriState.True || (row.Resizable == DataGridViewTriState.NotSet && DataGridView.AllowUserToResizeRows))
417 state |= DataGridViewElementStates.Resizable;
418 if (row.Resizable == DataGridViewTriState.True)
419 state |= DataGridViewElementStates.ResizableSet;
421 state |= DataGridViewElementStates.Selected;
423 state |= DataGridViewElementStates.Visible;
428 public bool SetValues (params object[] values)
430 if (values == null) {
431 throw new ArgumentNullException("vues is null");
433 if (DataGridView != null && DataGridView.VirtualMode) {
434 throw new InvalidOperationException("DataGridView is operating in virtual mode");
436 /////// COLUMNAS //////////
437 for (int i = 0; i < values.Length; i++) {
438 DataGridViewCell cell;
439 if (cells.Count > i) {
442 cell = new DataGridViewTextBoxCell ();
445 cell.Value = values[i];
452 public override string ToString ()
454 return this.GetType().Name + ", Band Index: " + base.Index.ToString();
457 protected virtual AccessibleObject CreateAccessibilityInstance ()
459 return new DataGridViewRowAccessibleObject(this);
462 [EditorBrowsable (EditorBrowsableState.Advanced)]
463 protected virtual DataGridViewCellCollection CreateCellsInstance ()
465 cells = new DataGridViewCellCollection(this);
469 [EditorBrowsable (EditorBrowsableState.Advanced)]
470 protected internal virtual void DrawFocus (Graphics graphics, Rectangle clipBounds, Rectangle bounds, int rowIndex, DataGridViewElementStates rowState, DataGridViewCellStyle cellStyle, bool cellsPaintSelectionBackground)
474 protected internal virtual void Paint (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow)
476 DataGridViewCellStyle style;
479 style = DataGridView.RowsDefaultCellStyle;
481 style = InheritedStyle;
483 DataGridViewRowPrePaintEventArgs pre = new DataGridViewRowPrePaintEventArgs (DataGridView, graphics, clipBounds, rowBounds, rowIndex, rowState, string.Empty, style, isFirstDisplayedRow, isLastVisibleRow);
484 pre.PaintParts = DataGridViewPaintParts.All;
486 DataGridView.OnRowPrePaint (pre);
488 // The user has elected for us to not do anything
492 if (DataGridView.RowHeadersVisible)
493 PaintHeader (graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, isFirstDisplayedRow, isLastVisibleRow, pre.PaintParts);
495 PaintCells (graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, isFirstDisplayedRow, isLastVisibleRow, pre.PaintParts);
497 DataGridViewRowPostPaintEventArgs post = new DataGridViewRowPostPaintEventArgs (DataGridView, graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, pre.ErrorText, style, isFirstDisplayedRow, isLastVisibleRow);
498 DataGridView.OnRowPostPaint (post);
501 [EditorBrowsable (EditorBrowsableState.Advanced)]
502 protected internal virtual void PaintCells (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow, DataGridViewPaintParts paintParts)
504 ArrayList sortedColumns = DataGridView.Columns.ColumnDisplayIndexSortedArrayList;
506 Rectangle bounds = rowBounds;
508 // If row headers are visible, adjust our starting point
509 if (DataGridView.RowHeadersVisible) {
510 bounds.X += DataGridView.RowHeadersWidth;
511 bounds.Width -= DataGridView.RowHeadersWidth;
514 for (int i = DataGridView.first_col_index; i < sortedColumns.Count; i++) {
515 DataGridViewColumn col = (DataGridViewColumn)sortedColumns[i];
516 bounds.Width = col.Width;
517 DataGridViewCell cell = Cells[col.Index];
519 graphics.FillRectangle (Brushes.White, bounds);
521 DataGridViewCellStyle style;
523 if (cell.RowIndex == -1)
524 style = DefaultCellStyle;
526 style = cell.InheritedStyle;
529 object formattedValue;
531 DataGridViewElementStates cellState;
533 if (cell.RowIndex == -1) {
534 // TODO: Look up value if databound.
536 formattedValue = null;
538 cellState = cell.State;
541 formattedValue = cell.FormattedValue;
542 errorText = cell.ErrorText;
543 cellState = cell.InheritedState;
546 DataGridViewAdvancedBorderStyle intermediateBorderStyle = (DataGridViewAdvancedBorderStyle)((ICloneable)DataGridView.AdvancedCellBorderStyle).Clone ();
547 DataGridViewAdvancedBorderStyle borderStyle = cell.AdjustCellBorderStyle (DataGridView.AdvancedCellBorderStyle, intermediateBorderStyle, true, true, cell.ColumnIndex == 0, cell.RowIndex == 0);
548 DataGridView.OnCellFormattingInternal (new DataGridViewCellFormattingEventArgs (cell.ColumnIndex, cell.RowIndex, value, cell.FormattedValueType, style));
551 cell.PaintWork (graphics, clipBounds, bounds, rowIndex, cellState, style, borderStyle, paintParts);
552 bounds.X += bounds.Width;
556 [EditorBrowsable (EditorBrowsableState.Advanced)]
557 protected internal virtual void PaintHeader (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow, DataGridViewPaintParts paintParts)
559 rowBounds.Width = DataGridView.RowHeadersWidth;
560 graphics.FillRectangle (Brushes.White, rowBounds);
562 HeaderCell.PaintWork (graphics, clipBounds, rowBounds, rowIndex, rowState, HeaderCell.InheritedStyle, DataGridView.AdvancedRowHeadersBorderStyle, paintParts);
565 internal override void SetDataGridView (DataGridView dataGridView)
567 base.SetDataGridView(dataGridView);
568 headerCell.SetDataGridView(dataGridView);
569 foreach (DataGridViewCell cell in cells)
570 cell.SetDataGridView (dataGridView);
573 internal override void SetState (DataGridViewElementStates state)
575 if (State != state) {
576 base.SetState(state);
577 if (DataGridView != null) {
578 DataGridView.OnRowStateChanged(this.Index, new DataGridViewRowStateChangedEventArgs(this, state));
583 [ComVisibleAttribute(true)]
584 protected class DataGridViewRowAccessibleObject : AccessibleObject {
586 private DataGridViewRow dataGridViewRow;
588 public DataGridViewRowAccessibleObject ()
592 public DataGridViewRowAccessibleObject (DataGridViewRow owner)
594 this.dataGridViewRow = owner;
597 public override Rectangle Bounds {
598 get { throw new NotImplementedException(); }
601 public override string Name {
602 get { return "Index: " + dataGridViewRow.Index.ToString(); }
605 public DataGridViewRow Owner {
606 get { return dataGridViewRow; }
607 set { dataGridViewRow = value; }
610 public override AccessibleObject Parent {
611 get { return dataGridViewRow.AccessibilityObject; }
614 public override AccessibleRole Role {
615 get { return AccessibleRole.Row; }
618 public override AccessibleStates State {
620 if (dataGridViewRow.Selected) {
621 return AccessibleStates.Selected;
624 return AccessibleStates.Focused;
629 public override string Value {
631 if (dataGridViewRow.Cells.Count == 0) {
632 return "(Create New)";
635 foreach (DataGridViewCell cell in dataGridViewRow.Cells) {
636 result += cell.AccessibilityObject.Value;
642 public override AccessibleObject GetChild (int index) {
643 throw new NotImplementedException();
646 public override int GetChildCount () {
647 throw new NotImplementedException();
650 public override AccessibleObject GetFocused () {
654 public override AccessibleObject GetSelected () {
658 public override AccessibleObject Navigate (AccessibleNavigation navigationDirection) {
659 switch (navigationDirection) {
660 case AccessibleNavigation.Right:
662 case AccessibleNavigation.Left:
664 case AccessibleNavigation.Next:
666 case AccessibleNavigation.Previous:
668 case AccessibleNavigation.Up:
670 case AccessibleNavigation.Down:
678 public override void Select (AccessibleSelection flags) {
680 case AccessibleSelection.TakeFocus:
681 dataGridViewRow.DataGridView.Focus();
683 case AccessibleSelection.TakeSelection:
684 //dataGridViewRow.Focus();
686 case AccessibleSelection.AddSelection:
687 dataGridViewRow.DataGridView.SelectedRows.InternalAdd(dataGridViewRow);
689 case AccessibleSelection.RemoveSelection:
690 dataGridViewRow.DataGridView.SelectedRows.InternalRemove(dataGridViewRow);
701 internal class DataGridRowConverter : TypeConverter