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;
394 DataGridViewRow row = DataGridView.Rows[rowIndex];
397 state |= DataGridViewElementStates.Displayed;
399 state |= DataGridViewElementStates.Frozen;
401 state |= DataGridViewElementStates.ReadOnly;
402 if (row.Resizable == DataGridViewTriState.True || (row.Resizable == DataGridViewTriState.NotSet && DataGridView.AllowUserToResizeRows))
403 state |= DataGridViewElementStates.Resizable;
404 if (row.Resizable == DataGridViewTriState.True)
405 state |= DataGridViewElementStates.ResizableSet;
407 state |= DataGridViewElementStates.Selected;
409 state |= DataGridViewElementStates.Visible;
414 public bool SetValues (params object[] values)
416 if (values == null) {
417 throw new ArgumentNullException("vues is null");
419 if (DataGridView != null && DataGridView.VirtualMode) {
420 throw new InvalidOperationException("DataGridView is operating in virtual mode");
422 /////// COLUMNAS //////////
423 for (int i = 0; i < values.Length; i++) {
424 DataGridViewCell cell;
425 if (cells.Count > i) {
428 cell = new DataGridViewTextBoxCell ();
431 cell.Value = values[i];
438 public override string ToString ()
440 return this.GetType().Name + ", Band Index: " + base.Index.ToString();
443 protected virtual AccessibleObject CreateAccessibilityInstance ()
445 return new DataGridViewRowAccessibleObject(this);
448 [EditorBrowsable (EditorBrowsableState.Advanced)]
449 protected virtual DataGridViewCellCollection CreateCellsInstance ()
451 cells = new DataGridViewCellCollection(this);
455 [EditorBrowsable (EditorBrowsableState.Advanced)]
456 protected internal virtual void DrawFocus (Graphics graphics, Rectangle clipBounds, Rectangle bounds, int rowIndex, DataGridViewElementStates rowState, DataGridViewCellStyle cellStyle, bool cellsPaintSelectionBackground)
460 protected internal virtual void Paint (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow)
462 DataGridViewRowPrePaintEventArgs pre = new DataGridViewRowPrePaintEventArgs (DataGridView, graphics, clipBounds, rowBounds, rowIndex, rowState, string.Empty, InheritedStyle, isFirstDisplayedRow, isLastVisibleRow);
463 pre.PaintParts = DataGridViewPaintParts.All;
465 DataGridView.OnRowPrePaint (pre);
467 // The user has elected for us to not do anything
471 if (DataGridView.RowHeadersVisible)
472 PaintHeader (graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, isFirstDisplayedRow, isLastVisibleRow, pre.PaintParts);
474 PaintCells (graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, isFirstDisplayedRow, isLastVisibleRow, pre.PaintParts);
476 DataGridViewRowPostPaintEventArgs post = new DataGridViewRowPostPaintEventArgs (DataGridView, graphics, pre.ClipBounds, rowBounds, rowIndex, rowState, pre.ErrorText, InheritedStyle, isFirstDisplayedRow, isLastVisibleRow);
477 DataGridView.OnRowPostPaint (post);
480 [EditorBrowsable (EditorBrowsableState.Advanced)]
481 protected internal virtual void PaintCells (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow, DataGridViewPaintParts paintParts)
483 ArrayList sortedColumns = DataGridView.Columns.ColumnDisplayIndexSortedArrayList;
485 Rectangle bounds = rowBounds;
487 // If row headers are visible, adjust our starting point
488 if (DataGridView.RowHeadersVisible) {
489 bounds.X += DataGridView.RowHeadersWidth;
490 bounds.Width -= DataGridView.RowHeadersWidth;
493 foreach (DataGridViewCell cell in Cells) {
494 bounds.Width = DataGridView.Columns[cell.ColumnIndex].Width;
496 graphics.FillRectangle (Brushes.White, bounds);
498 DataGridViewCellStyle style;
500 if (cell.RowIndex == -1)
501 style = DefaultCellStyle;
503 style = cell.InheritedStyle;
506 object formattedValue;
508 DataGridViewElementStates cellState;
510 if (cell.RowIndex == -1) {
511 // TODO: Look up value if databound.
513 formattedValue = null;
515 cellState = cell.State;
518 formattedValue = cell.FormattedValue;
519 errorText = cell.ErrorText;
520 cellState = cell.InheritedState;
523 DataGridViewAdvancedBorderStyle intermediateBorderStyle = (DataGridViewAdvancedBorderStyle)((ICloneable)DataGridView.AdvancedCellBorderStyle).Clone ();
524 DataGridViewAdvancedBorderStyle borderStyle = cell.AdjustCellBorderStyle (DataGridView.AdvancedCellBorderStyle, intermediateBorderStyle, true, true, cell.ColumnIndex == 0, cell.RowIndex == 0);
525 DataGridView.OnCellFormattingInternal (new DataGridViewCellFormattingEventArgs (cell.ColumnIndex, cell.RowIndex, value, cell.FormattedValueType, style));
527 cell.PaintWork (graphics, clipBounds, bounds, rowIndex, cellState, cell.InheritedStyle, borderStyle, paintParts);
528 bounds.X += bounds.Width;
532 [EditorBrowsable (EditorBrowsableState.Advanced)]
533 protected internal virtual void PaintHeader (Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, int rowIndex, DataGridViewElementStates rowState, bool isFirstDisplayedRow, bool isLastVisibleRow, DataGridViewPaintParts paintParts)
535 rowBounds.Width = DataGridView.RowHeadersWidth;
536 graphics.FillRectangle (Brushes.White, rowBounds);
538 HeaderCell.PaintWork (graphics, clipBounds, rowBounds, rowIndex, rowState, HeaderCell.InheritedStyle, DataGridView.AdvancedRowHeadersBorderStyle, paintParts);
541 internal override void SetDataGridView (DataGridView dataGridView)
543 base.SetDataGridView(dataGridView);
544 headerCell.SetDataGridView(dataGridView);
545 foreach (DataGridViewCell cell in cells)
546 cell.SetDataGridView (dataGridView);
549 internal override void SetState (DataGridViewElementStates state)
551 if (State != state) {
552 base.SetState(state);
553 if (DataGridView != null) {
554 DataGridView.OnRowStateChanged(this.Index, new DataGridViewRowStateChangedEventArgs(this, state));
559 [ComVisibleAttribute(true)]
560 protected class DataGridViewRowAccessibleObject : AccessibleObject {
562 private DataGridViewRow dataGridViewRow;
564 public DataGridViewRowAccessibleObject ()
568 public DataGridViewRowAccessibleObject (DataGridViewRow owner)
570 this.dataGridViewRow = owner;
573 public override Rectangle Bounds {
574 get { throw new NotImplementedException(); }
577 public override string Name {
578 get { return "Index: " + dataGridViewRow.Index.ToString(); }
581 public DataGridViewRow Owner {
582 get { return dataGridViewRow; }
583 set { dataGridViewRow = value; }
586 public override AccessibleObject Parent {
587 get { return dataGridViewRow.AccessibilityObject; }
590 public override AccessibleRole Role {
591 get { return AccessibleRole.Row; }
594 public override AccessibleStates State {
596 if (dataGridViewRow.Selected) {
597 return AccessibleStates.Selected;
600 return AccessibleStates.Focused;
605 public override string Value {
607 if (dataGridViewRow.Cells.Count == 0) {
608 return "(Create New)";
611 foreach (DataGridViewCell cell in dataGridViewRow.Cells) {
612 result += cell.AccessibilityObject.Value;
618 public override AccessibleObject GetChild (int index) {
619 throw new NotImplementedException();
622 public override int GetChildCount () {
623 throw new NotImplementedException();
626 public override AccessibleObject GetFocused () {
630 public override AccessibleObject GetSelected () {
634 public override AccessibleObject Navigate (AccessibleNavigation navigationDirection) {
635 switch (navigationDirection) {
636 case AccessibleNavigation.Right:
638 case AccessibleNavigation.Left:
640 case AccessibleNavigation.Next:
642 case AccessibleNavigation.Previous:
644 case AccessibleNavigation.Up:
646 case AccessibleNavigation.Down:
654 public override void Select (AccessibleSelection flags) {
656 case AccessibleSelection.TakeFocus:
657 dataGridViewRow.DataGridView.Focus();
659 case AccessibleSelection.TakeSelection:
660 //dataGridViewRow.Focus();
662 case AccessibleSelection.AddSelection:
663 dataGridViewRow.DataGridView.SelectedRows.InternalAdd(dataGridViewRow);
665 case AccessibleSelection.RemoveSelection:
666 dataGridViewRow.DataGridView.SelectedRows.InternalRemove(dataGridViewRow);
677 internal class DataGridRowConverter : TypeConverter