Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / WinForms / DataGridRow.cs / 1305376 / DataGridRow.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System.Runtime.Remoting; using System.Runtime.Versioning; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System; using System.Runtime.InteropServices; using System.Windows.Forms; using System.ComponentModel; using System.Drawing; using System.Drawing.Imaging; using System.Security.Permissions; using Microsoft.Win32; using System.Collections; ////// /// internal abstract class DataGridRow : MarshalByRefObject { internal protected int number; // row number private bool selected; private int height; // protected DataRow dataRow; private IntPtr tooltipID = new IntPtr(-1); private string tooltip = String.Empty; AccessibleObject accessibleObject; // for accessibility... // // internal DataGrid dataGrid; // will need this for the painting information ( row header color ) // protected DataGridTableStyle dgTable; // we will be mapping only the black color to // the HeaderForeColor // private static ColorMap[] colorMap = new ColorMap[] {new ColorMap()}; // bitmaps // private static Bitmap rightArrow = null; private static Bitmap leftArrow = null; private static Bitmap errorBmp = null; private static Bitmap pencilBmp = null; private static Bitmap starBmp = null; protected const int xOffset = 3; protected const int yOffset = 2; ///Encapsulates the painting logic for a new row added to a /// ////// control. /// /// [ SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors") // This class and its derived classes are internal. // So this is not a security back door. ] public DataGridRow(DataGrid dataGrid, DataGridTableStyle dgTable, int rowNumber) { if (dataGrid == null || dgTable.DataGrid == null) throw new ArgumentNullException("dataGrid"); if (rowNumber < 0) throw new ArgumentException(SR.GetString(SR.DataGridRowRowNumber), "rowNumber"); // this.dataGrid = dataGrid; this.number = rowNumber; // map the black color in the pictures to the DataGrid's HeaderForeColor // colorMap[0].OldColor = Color.Black; colorMap[0].NewColor = dgTable.HeaderForeColor; this.dgTable = dgTable; height = MinimumRowHeight(dgTable); } public AccessibleObject AccessibleObject { get { if (accessibleObject == null) { accessibleObject = CreateAccessibleObject(); } return accessibleObject; } } protected virtual AccessibleObject CreateAccessibleObject() { return new DataGridRowAccessibleObject(this); } internal protected virtual int MinimumRowHeight(DataGridTableStyle dgTable) { return MinimumRowHeight(dgTable.GridColumnStyles); } internal protected virtual int MinimumRowHeight(GridColumnStylesCollection columns) { int h = dgTable.IsDefault ? this.DataGrid.PreferredRowHeight : dgTable.PreferredRowHeight; try { if (this.dgTable.DataGrid.DataSource != null) { int nCols = columns.Count; for (int i = 0; i < nCols; ++i) { // if (columns[i].Visible && columns[i].PropertyDescriptor != null) if (columns[i].PropertyDescriptor != null) h = Math.Max(h, columns[i].GetMinimumHeight()); } } } catch { } return h; } // =----------------------------------------------------------------- // = Properties // =----------------------------------------------------------------- ///Initializes a new instance of a ///. /// /// public DataGrid DataGrid { get { return this.dgTable.DataGrid; } } internal DataGridTableStyle DataGridTableStyle { get { return this.dgTable; } set { dgTable = value; } } /* public DataGridTable DataGridTable { get { return dgTable; } } */ /* public DataRow DataRow { get { return dataRow; } } */ ///Gets the ///control the row belongs to. /// /// public virtual int Height { get { return height; } set { // the height of the row should be at least 0. // this way, if the row has a relationship list and the user resizes the row such that // the new height does not accomodate the height of the relationship list // the row will at least show the relationship list ( and not paint on the portion of the row above this one ) height = Math.Max(0, value); // when we resize the row, or when we set the PreferredRowHeigth on the // DataGridTableStyle, we change the height of the Row, which will cause to invalidate, // then the grid itself will do another invalidate call. this.dgTable.DataGrid.OnRowHeightChanged(this); } } ///Gets or sets the height of the row. ////// /// public int RowNumber { get { return this.number; } } ///Gets the row's number. ////// /// public virtual bool Selected { get { return selected; } set { selected = value; InvalidateRow(); } } // =------------------------------------------------------------------ // = Methods // =----------------------------------------------------------------- ///Gets or sets a value indicating whether the row is selected. ////// /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected Bitmap GetBitmap(string bitmapName) { Bitmap b = null; try { b = new Bitmap(typeof(DataGridCaption), bitmapName); b.MakeTransparent(); } catch (Exception e) { Debug.Fail("Failed to load bitmap: " + bitmapName, e.ToString()); throw e; } return b; } ///Gets the bitmap associated with the row. ////// /// public virtual Rectangle GetCellBounds(int col) { int firstVisibleCol = this.dgTable.DataGrid.FirstVisibleColumn; int cx = 0; Rectangle cellBounds = new Rectangle(); GridColumnStylesCollection columns = this.dgTable.GridColumnStyles; if (columns != null) { for (int i = firstVisibleCol; i < col; i++) if (columns[i].PropertyDescriptor != null) cx += columns[i].Width; int borderWidth = this.dgTable.GridLineWidth; cellBounds = new Rectangle(cx, 0, columns[col].Width - borderWidth, Height - borderWidth); } return cellBounds; } ///When overridden in a derived class, gets the ////// where a cell's contents gets painted. /// /// public virtual Rectangle GetNonScrollableArea() { return Rectangle.Empty; } ///When overridden in a derived class, gets the ///of the non-scrollable area of /// the row. /// /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected Bitmap GetStarBitmap() { if (starBmp == null) starBmp = GetBitmap("DataGridRow.star.bmp"); return starBmp; } ///Gets or sets the bitmap displayed in the row header of a new row. ////// /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected Bitmap GetPencilBitmap() { if (pencilBmp == null) pencilBmp = GetBitmap("DataGridRow.pencil.bmp"); return pencilBmp; } ///Gets or sets the bitmap displayed in the row header that indicates a row can /// be edited. ////// /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected Bitmap GetErrorBitmap() { if (errorBmp == null) errorBmp = GetBitmap("DataGridRow.error.bmp"); errorBmp.MakeTransparent(); return errorBmp; } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected Bitmap GetLeftArrowBitmap() { if (leftArrow == null) leftArrow = GetBitmap("DataGridRow.left.bmp"); return leftArrow; } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected Bitmap GetRightArrowBitmap() { if (rightArrow == null) rightArrow = GetBitmap("DataGridRow.right.bmp"); return rightArrow; } public virtual void InvalidateRow() { this.dgTable.DataGrid.InvalidateRow(number); } public virtual void InvalidateRowRect(Rectangle r) { this.dgTable.DataGrid.InvalidateRowRect(number, r); } ///Gets or sets the bitmap displayed on a row with an error. ////// /// public virtual void OnEdit() { } ///When overridden in a derived class, notifies the grid that an edit will /// occur. ////// /// public virtual bool OnKeyPress(Keys keyData) { int currentColIndex = this.dgTable.DataGrid.CurrentCell.ColumnNumber; GridColumnStylesCollection columns = this.dgTable.GridColumnStyles; if (columns != null && currentColIndex >= 0 && currentColIndex < columns.Count) { DataGridColumnStyle currentColumn = columns[currentColIndex]; if (currentColumn.KeyPress(this.RowNumber, keyData)) { return true; } } return false; } ///When overridden in a derived class, called by the ///control when a key press occurs on a row with focus. /// /// public virtual bool OnMouseDown(int x, int y, Rectangle rowHeaders) { return OnMouseDown(x,y,rowHeaders, false); } ///Called by the ///when a click occurs in the row's client area /// specifed by the x and y coordinates and the specified /// . /// /// public virtual bool OnMouseDown(int x, int y, Rectangle rowHeaders, bool alignToRight) { // if we call base.OnMouseDown, then the row could not use this // mouse click at all. in that case LoseChildFocus, so the edit control // will become visible LoseChildFocus(rowHeaders, alignToRight); // we did not use this click at all. return false; } ///When overridden in a derived class, is called by the ///when a click occurs /// in the row's /// client area, specified by x and y coordinates. /// /// public virtual bool OnMouseMove(int x, int y, Rectangle rowHeaders) { return false; } ////// /// public virtual bool OnMouseMove(int x, int y, Rectangle rowHeaders, bool alignToRight) { return false; } ///When overridden in a derived class, is called by the ///when /// the mouse moves within the row's client area. /// /// public virtual void OnMouseLeft(Rectangle rowHeaders, bool alignToRight) { } public virtual void OnMouseLeft() { } ////// /// public virtual void OnRowEnter() {} public virtual void OnRowLeave() {} // processes the Tab Key // returns TRUE if the TAB key is processed internal abstract bool ProcessTabKey(Keys keyData, Rectangle rowHeaders, bool alignToRight); // tells the dataGridRow that it lost the focus internal abstract void LoseChildFocus(Rectangle rowHeaders, bool alignToRight); ///When overridden in a derived class, causes the RowEnter event to occur. ////// /// Paints the row. /// public abstract int Paint(Graphics g, Rectangle dataBounds, Rectangle rowBounds, int firstVisibleColumn, int numVisibleColumns); public abstract int Paint(Graphics g, Rectangle dataBounds, Rectangle rowBounds, int firstVisibleColumn, int numVisibleColumns, bool alignToRight); ////// /// Draws a border on the bottom DataGrid.GridLineWidth pixels /// of the bounding rectangle passed in. /// protected virtual void PaintBottomBorder(Graphics g, Rectangle bounds, int dataWidth) { PaintBottomBorder(g, bounds, dataWidth, this.dgTable.GridLineWidth, false); } protected virtual void PaintBottomBorder(Graphics g, Rectangle bounds, int dataWidth, int borderWidth, bool alignToRight) { // paint bottom border Rectangle bottomBorder = new Rectangle(alignToRight ? bounds.Right - dataWidth : bounds.X, bounds.Bottom - borderWidth, dataWidth, borderWidth); g.FillRectangle(this.dgTable.IsDefault ? this.DataGrid.GridLineBrush : this.dgTable.GridLineBrush, bottomBorder); // paint any exposed region to the right if (dataWidth < bounds.Width) { g.FillRectangle(this.dgTable.DataGrid.BackgroundBrush, alignToRight ? bounds.X: bottomBorder.Right, bottomBorder.Y, bounds.Width - bottomBorder.Width, borderWidth); } } ////// /// Paints the row. /// public virtual int PaintData(Graphics g, Rectangle bounds, int firstVisibleColumn, int columnCount) { return PaintData(g, bounds, firstVisibleColumn, columnCount, false); } public virtual int PaintData(Graphics g, Rectangle bounds, int firstVisibleColumn, int columnCount, bool alignToRight) { Debug.WriteLineIf(CompModSwitches.DGRowPaint.TraceVerbose, "Painting DataGridAddNewRow: bounds = " + bounds.ToString()); Rectangle cellBounds = bounds; int bWidth = this.dgTable.IsDefault ? this.DataGrid.GridLineWidth : this.dgTable.GridLineWidth; int cx = 0; DataGridCell current = this.dgTable.DataGrid.CurrentCell; GridColumnStylesCollection columns = dgTable.GridColumnStyles; int nCols = columns.Count; for (int col = firstVisibleColumn; col < nCols; ++col) { if (cx > bounds.Width) break; // if (!columns[col].Visible || columns[col].PropertyDescriptor == null) if (columns[col].PropertyDescriptor == null || columns[col].Width <= 0) continue; cellBounds.Width = columns[col].Width - bWidth; if (alignToRight) cellBounds.X = bounds.Right - cx - cellBounds.Width; else cellBounds.X = bounds.X + cx; // Paint the data with the the DataGridColumn Brush backBr = BackBrushForDataPaint(ref current, columns[col], col); Brush foreBrush = ForeBrushForDataPaint(ref current, columns[col], col); PaintCellContents(g, cellBounds, columns[col], backBr, foreBrush, alignToRight); // Paint the border to the right of each cell if (bWidth > 0) { g.FillRectangle(this.dgTable.IsDefault ? this.DataGrid.GridLineBrush : this.dgTable.GridLineBrush, alignToRight ? cellBounds.X - bWidth : cellBounds.Right, cellBounds.Y, bWidth, cellBounds.Height); } cx += cellBounds.Width + bWidth; } // Paint any exposed area to the right ( or left ) of the data cell area if (cx < bounds.Width) { g.FillRectangle(this.dgTable.DataGrid.BackgroundBrush, alignToRight ? bounds.X : bounds.X + cx, bounds.Y, bounds.Width - cx, bounds.Height); } return cx; } protected virtual void PaintCellContents(Graphics g, Rectangle cellBounds, DataGridColumnStyle column, Brush backBr, Brush foreBrush) { PaintCellContents(g, cellBounds, column, backBr, foreBrush, false); } protected virtual void PaintCellContents(Graphics g, Rectangle cellBounds, DataGridColumnStyle column, Brush backBr, Brush foreBrush, bool alignToRight) { g.FillRectangle(backBr, cellBounds); } // // This function will do the following: if paintIcon is set to true, then // will draw the image on the RowHeader. if paintIcon is set to false, // then this function will fill the rectangle on which otherwise will // have been drawn the image // // will return the rectangle that includes the Icon // protected Rectangle PaintIcon(Graphics g, Rectangle visualBounds, bool paintIcon, bool alignToRight, Bitmap bmp) { return PaintIcon(g, visualBounds, paintIcon, alignToRight, bmp, this.dgTable.IsDefault ? this.DataGrid.HeaderBackBrush : this.dgTable.HeaderBackBrush); } protected Rectangle PaintIcon(Graphics g, Rectangle visualBounds, bool paintIcon, bool alignToRight, Bitmap bmp, Brush backBrush) { Size bmpSize = bmp.Size; Rectangle bmpRect = new Rectangle(alignToRight ? visualBounds.Right - xOffset - bmpSize.Width : visualBounds.X + xOffset, visualBounds.Y + yOffset, bmpSize.Width, bmpSize.Height); g.FillRectangle(backBrush, visualBounds); if (paintIcon) { colorMap[0].NewColor = this.dgTable.IsDefault ? this.DataGrid.HeaderForeColor : this.dgTable.HeaderForeColor; colorMap[0].OldColor = Color.Black; ImageAttributes attr = new ImageAttributes(); attr.SetRemapTable(colorMap, ColorAdjustType.Bitmap); g.DrawImage(bmp, bmpRect, 0, 0, bmpRect.Width, bmpRect.Height,GraphicsUnit.Pixel, attr); // g.DrawImage(bmp, bmpRect); attr.Dispose(); } return bmpRect; } // assume that the row is not aligned to right, and that the row is not dirty public virtual void PaintHeader(Graphics g, Rectangle visualBounds) { PaintHeader(g, visualBounds, false); } // assume that the row is not dirty public virtual void PaintHeader(Graphics g, Rectangle visualBounds, bool alignToRight) { PaintHeader(g,visualBounds, alignToRight, false); } public virtual void PaintHeader(Graphics g, Rectangle visualBounds, bool alignToRight, bool rowIsDirty) { Rectangle bounds = visualBounds; // paint the first part of the row header: the Arror or Pencil/Star Bitmap bmp; if (this is DataGridAddNewRow) { bmp = GetStarBitmap(); lock (bmp) { bounds.X += PaintIcon(g, bounds, true, alignToRight, bmp).Width + xOffset; } return; } else if (rowIsDirty) { bmp = GetPencilBitmap(); lock (bmp) { bounds.X += PaintIcon(g, bounds, RowNumber == this.DataGrid.CurrentCell.RowNumber, alignToRight, bmp).Width + xOffset; } } else { bmp = alignToRight ? GetLeftArrowBitmap() : GetRightArrowBitmap(); lock (bmp) { bounds.X += PaintIcon(g, bounds, RowNumber == this.DataGrid.CurrentCell.RowNumber, alignToRight, bmp).Width + xOffset; } } // Paint the error icon // object errorInfo = DataGrid.ListManager[this.number]; if (!(errorInfo is IDataErrorInfo)) return; string errString = ((IDataErrorInfo) errorInfo).Error; if (errString == null) errString = String.Empty; if (tooltip != errString) { if (!String.IsNullOrEmpty(tooltip)) { DataGrid.ToolTipProvider.RemoveToolTip(tooltipID); tooltip = String.Empty; tooltipID = new IntPtr(-1); } } if (String.IsNullOrEmpty(errString)) return; // we now have an error string: paint the errorIcon and add the tooltip Rectangle errRect; bmp = GetErrorBitmap(); lock (bmp) { errRect = PaintIcon(g, bounds, true, alignToRight, bmp); } bounds.X += errRect.Width + xOffset; tooltip = errString; tooltipID = (IntPtr)((int)DataGrid.ToolTipId++); DataGrid.ToolTipProvider.AddToolTip(tooltip, tooltipID, errRect); } protected Brush GetBackBrush() { Brush br = this.dgTable.IsDefault ? DataGrid.BackBrush : this.dgTable.BackBrush; if (DataGrid.LedgerStyle && (RowNumber % 2 == 1)) { br = this.dgTable.IsDefault ? this.DataGrid.AlternatingBackBrush : this.dgTable.AlternatingBackBrush; } return br; } ////// /// Returns the BackColor and TextColor that the Graphics object should use /// for the appropriate values for a given row and column when painting the data. /// /// protected Brush BackBrushForDataPaint(ref DataGridCell current, DataGridColumnStyle gridColumn, int column) { Brush backBr = this.GetBackBrush(); if (Selected) { backBr = this.dgTable.IsDefault ? this.DataGrid.SelectionBackBrush : this.dgTable.SelectionBackBrush; } /* if (RowNumber == current.RowNumber && column == current.ColumnNumber) { backBr = grid.CurrentCellBackBrush; } */ return backBr; } protected Brush ForeBrushForDataPaint(ref DataGridCell current, DataGridColumnStyle gridColumn, int column) { // Brush foreBrush = gridColumn.ForeBrush; Brush foreBrush = this.dgTable.IsDefault ? this.DataGrid.ForeBrush : this.dgTable.ForeBrush; if (Selected) { foreBrush = this.dgTable.IsDefault ? this.DataGrid.SelectionForeBrush : this.dgTable.SelectionForeBrush; } /* if (RowNumber == current.RowNumber && column == current.ColumnNumber) { foreColor = grid.CurrentCellForeColor; } */ return foreBrush; } [ComVisible(true)] protected class DataGridRowAccessibleObject : AccessibleObject { ArrayList cells; DataGridRow owner = null; internal static string CellToDisplayString(DataGrid grid, int row, int column) { if (column < grid.myGridTable.GridColumnStyles.Count) { return grid.myGridTable.GridColumnStyles[column].PropertyDescriptor.Converter.ConvertToString(grid[row, column]); } else { return ""; } } internal static object DisplayStringToCell(DataGrid grid, int row, int column, string value) { if (column < grid.myGridTable.GridColumnStyles.Count) { return grid.myGridTable.GridColumnStyles[column].PropertyDescriptor.Converter.ConvertFromString(value); } // ignore... // return null; } [ SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors") // This class and its derived classes are internal. // So this is not a security back door. ] public DataGridRowAccessibleObject(DataGridRow owner) : base() { Debug.Assert(owner != null, "DataGridRowAccessibleObject must have a valid owner DataGridRow"); this.owner = owner; DataGrid grid = DataGrid; Debug.WriteLineIf(DataGrid.DataGridAcc.TraceVerbose, "Create row accessible object"); EnsureChildren(); } private void EnsureChildren() { if (cells == null) { // default size... little extra for relationships... // cells = new ArrayList(DataGrid.myGridTable.GridColumnStyles.Count + 2); AddChildAccessibleObjects(cells); } } protected virtual void AddChildAccessibleObjects(IList children) { Debug.WriteLineIf(DataGrid.DataGridAcc.TraceVerbose, "Create row's accessible children"); Debug.Indent(); GridColumnStylesCollection cols = DataGrid.myGridTable.GridColumnStyles; int len = cols.Count; Debug.WriteLineIf(DataGrid.DataGridAcc.TraceVerbose, len + " columns present"); for (int i=0; i/// /// Returns the currently focused child, if any. /// Returns this if the object itself is focused. /// public override AccessibleObject GetFocused() { if (DataGrid.Focused) { DataGridCell cell = DataGrid.CurrentCell; if (cell.RowNumber == owner.RowNumber) { return (AccessibleObject)cells[cell.ColumnNumber]; } } return null; } ////// /// Navigate to the next or previous grid entry.entry. /// [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override AccessibleObject Navigate(AccessibleNavigation navdir) { switch (navdir) { case AccessibleNavigation.Down: case AccessibleNavigation.Right: case AccessibleNavigation.Next: return DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber + 1); case AccessibleNavigation.Up: case AccessibleNavigation.Left: case AccessibleNavigation.Previous: return DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber - 1); case AccessibleNavigation.FirstChild: if (GetChildCount() > 0) { return GetChild(0); } break; case AccessibleNavigation.LastChild: if (GetChildCount() > 0) { return GetChild(GetChildCount() - 1); } break; } return null; } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override void Select(AccessibleSelection flags) { // Focus the PropertyGridView window // if ( (flags & AccessibleSelection.TakeFocus) == AccessibleSelection.TakeFocus) { DataGrid.Focus(); } // Select the grid entry // if ( (flags & AccessibleSelection.TakeSelection) == AccessibleSelection.TakeSelection) { DataGrid.CurrentRowIndex = owner.RowNumber; } } } [ComVisible(true)] protected class DataGridCellAccessibleObject : AccessibleObject { DataGridRow owner = null; int column; public DataGridCellAccessibleObject(DataGridRow owner, int column) : base() { Debug.Assert(owner != null, "DataGridColumnAccessibleObject must have a valid owner DataGridRow"); this.owner = owner; this.column = column; Debug.WriteLineIf(DataGrid.DataGridAcc.TraceVerbose, "Create cell accessible object"); } public override Rectangle Bounds { get { return DataGrid.RectangleToScreen(DataGrid.GetCellBounds(new DataGridCell(owner.RowNumber, column))); } } public override string Name { get { return DataGrid.myGridTable.GridColumnStyles[column].HeaderText; } } public override AccessibleObject Parent { [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] get { return owner.AccessibleObject; } } protected DataGrid DataGrid { get { return owner.DataGrid; } } public override string DefaultAction { get { return SR.GetString(SR.AccDGEdit); } } public override AccessibleRole Role { get { return AccessibleRole.Cell; } } public override AccessibleStates State { get { AccessibleStates state = AccessibleStates.Selectable | AccessibleStates.Focusable; // Determine focus // if (DataGrid.CurrentCell.RowNumber == owner.RowNumber && DataGrid.CurrentCell.ColumnNumber == column) { if (DataGrid.Focused) { state |= AccessibleStates.Focused; } state |= AccessibleStates.Selected; } return state; } } public override string Value { [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] get { if (owner is DataGridAddNewRow) { return null; } else { return DataGridRowAccessibleObject.CellToDisplayString(DataGrid, owner.RowNumber, column); } } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] set { if (!(owner is DataGridAddNewRow)) { object realValue = DataGridRowAccessibleObject.DisplayStringToCell(DataGrid, owner.RowNumber, column, value); DataGrid[owner.RowNumber, column] = realValue; } } } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override void DoDefaultAction() { Select(AccessibleSelection.TakeFocus | AccessibleSelection.TakeSelection); } ////// /// Returns the currently focused child, if any. /// Returns this if the object itself is focused. /// public override AccessibleObject GetFocused() { // Datagrid always returns the cell as the focused thing... so do we! // return DataGrid.AccessibilityObject.GetFocused(); } ////// /// Navigate to the next or previous grid entry. /// [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override AccessibleObject Navigate(AccessibleNavigation navdir) { switch (navdir) { case AccessibleNavigation.Right: case AccessibleNavigation.Next: if (column < owner.AccessibleObject.GetChildCount() - 1) { return owner.AccessibleObject.GetChild(column + 1); } else { AccessibleObject o = DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber + 1); if (o != null) { return o.Navigate(AccessibleNavigation.FirstChild); } } break; case AccessibleNavigation.Down: return DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber + 1).Navigate(AccessibleNavigation.FirstChild); case AccessibleNavigation.Up: return DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber - 1).Navigate(AccessibleNavigation.FirstChild); case AccessibleNavigation.Left: case AccessibleNavigation.Previous: if (column > 0) { return owner.AccessibleObject.GetChild(column - 1); } else { AccessibleObject o = DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber - 1); if (o != null) { return o.Navigate(AccessibleNavigation.LastChild); } } break; case AccessibleNavigation.FirstChild: case AccessibleNavigation.LastChild: break; } return null; } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override void Select(AccessibleSelection flags) { // Focus the PropertyGridView window // if ( (flags & AccessibleSelection.TakeFocus) == AccessibleSelection.TakeFocus) { DataGrid.Focus(); } // Select the grid entry // if ( (flags & AccessibleSelection.TakeSelection) == AccessibleSelection.TakeSelection) { DataGrid.CurrentCell = new DataGridCell(owner.RowNumber, column); } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System.Runtime.Remoting; using System.Runtime.Versioning; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System; using System.Runtime.InteropServices; using System.Windows.Forms; using System.ComponentModel; using System.Drawing; using System.Drawing.Imaging; using System.Security.Permissions; using Microsoft.Win32; using System.Collections; ////// /// internal abstract class DataGridRow : MarshalByRefObject { internal protected int number; // row number private bool selected; private int height; // protected DataRow dataRow; private IntPtr tooltipID = new IntPtr(-1); private string tooltip = String.Empty; AccessibleObject accessibleObject; // for accessibility... // // internal DataGrid dataGrid; // will need this for the painting information ( row header color ) // protected DataGridTableStyle dgTable; // we will be mapping only the black color to // the HeaderForeColor // private static ColorMap[] colorMap = new ColorMap[] {new ColorMap()}; // bitmaps // private static Bitmap rightArrow = null; private static Bitmap leftArrow = null; private static Bitmap errorBmp = null; private static Bitmap pencilBmp = null; private static Bitmap starBmp = null; protected const int xOffset = 3; protected const int yOffset = 2; ///Encapsulates the painting logic for a new row added to a /// ////// control. /// /// [ SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors") // This class and its derived classes are internal. // So this is not a security back door. ] public DataGridRow(DataGrid dataGrid, DataGridTableStyle dgTable, int rowNumber) { if (dataGrid == null || dgTable.DataGrid == null) throw new ArgumentNullException("dataGrid"); if (rowNumber < 0) throw new ArgumentException(SR.GetString(SR.DataGridRowRowNumber), "rowNumber"); // this.dataGrid = dataGrid; this.number = rowNumber; // map the black color in the pictures to the DataGrid's HeaderForeColor // colorMap[0].OldColor = Color.Black; colorMap[0].NewColor = dgTable.HeaderForeColor; this.dgTable = dgTable; height = MinimumRowHeight(dgTable); } public AccessibleObject AccessibleObject { get { if (accessibleObject == null) { accessibleObject = CreateAccessibleObject(); } return accessibleObject; } } protected virtual AccessibleObject CreateAccessibleObject() { return new DataGridRowAccessibleObject(this); } internal protected virtual int MinimumRowHeight(DataGridTableStyle dgTable) { return MinimumRowHeight(dgTable.GridColumnStyles); } internal protected virtual int MinimumRowHeight(GridColumnStylesCollection columns) { int h = dgTable.IsDefault ? this.DataGrid.PreferredRowHeight : dgTable.PreferredRowHeight; try { if (this.dgTable.DataGrid.DataSource != null) { int nCols = columns.Count; for (int i = 0; i < nCols; ++i) { // if (columns[i].Visible && columns[i].PropertyDescriptor != null) if (columns[i].PropertyDescriptor != null) h = Math.Max(h, columns[i].GetMinimumHeight()); } } } catch { } return h; } // =----------------------------------------------------------------- // = Properties // =----------------------------------------------------------------- ///Initializes a new instance of a ///. /// /// public DataGrid DataGrid { get { return this.dgTable.DataGrid; } } internal DataGridTableStyle DataGridTableStyle { get { return this.dgTable; } set { dgTable = value; } } /* public DataGridTable DataGridTable { get { return dgTable; } } */ /* public DataRow DataRow { get { return dataRow; } } */ ///Gets the ///control the row belongs to. /// /// public virtual int Height { get { return height; } set { // the height of the row should be at least 0. // this way, if the row has a relationship list and the user resizes the row such that // the new height does not accomodate the height of the relationship list // the row will at least show the relationship list ( and not paint on the portion of the row above this one ) height = Math.Max(0, value); // when we resize the row, or when we set the PreferredRowHeigth on the // DataGridTableStyle, we change the height of the Row, which will cause to invalidate, // then the grid itself will do another invalidate call. this.dgTable.DataGrid.OnRowHeightChanged(this); } } ///Gets or sets the height of the row. ////// /// public int RowNumber { get { return this.number; } } ///Gets the row's number. ////// /// public virtual bool Selected { get { return selected; } set { selected = value; InvalidateRow(); } } // =------------------------------------------------------------------ // = Methods // =----------------------------------------------------------------- ///Gets or sets a value indicating whether the row is selected. ////// /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected Bitmap GetBitmap(string bitmapName) { Bitmap b = null; try { b = new Bitmap(typeof(DataGridCaption), bitmapName); b.MakeTransparent(); } catch (Exception e) { Debug.Fail("Failed to load bitmap: " + bitmapName, e.ToString()); throw e; } return b; } ///Gets the bitmap associated with the row. ////// /// public virtual Rectangle GetCellBounds(int col) { int firstVisibleCol = this.dgTable.DataGrid.FirstVisibleColumn; int cx = 0; Rectangle cellBounds = new Rectangle(); GridColumnStylesCollection columns = this.dgTable.GridColumnStyles; if (columns != null) { for (int i = firstVisibleCol; i < col; i++) if (columns[i].PropertyDescriptor != null) cx += columns[i].Width; int borderWidth = this.dgTable.GridLineWidth; cellBounds = new Rectangle(cx, 0, columns[col].Width - borderWidth, Height - borderWidth); } return cellBounds; } ///When overridden in a derived class, gets the ////// where a cell's contents gets painted. /// /// public virtual Rectangle GetNonScrollableArea() { return Rectangle.Empty; } ///When overridden in a derived class, gets the ///of the non-scrollable area of /// the row. /// /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected Bitmap GetStarBitmap() { if (starBmp == null) starBmp = GetBitmap("DataGridRow.star.bmp"); return starBmp; } ///Gets or sets the bitmap displayed in the row header of a new row. ////// /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected Bitmap GetPencilBitmap() { if (pencilBmp == null) pencilBmp = GetBitmap("DataGridRow.pencil.bmp"); return pencilBmp; } ///Gets or sets the bitmap displayed in the row header that indicates a row can /// be edited. ////// /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected Bitmap GetErrorBitmap() { if (errorBmp == null) errorBmp = GetBitmap("DataGridRow.error.bmp"); errorBmp.MakeTransparent(); return errorBmp; } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected Bitmap GetLeftArrowBitmap() { if (leftArrow == null) leftArrow = GetBitmap("DataGridRow.left.bmp"); return leftArrow; } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected Bitmap GetRightArrowBitmap() { if (rightArrow == null) rightArrow = GetBitmap("DataGridRow.right.bmp"); return rightArrow; } public virtual void InvalidateRow() { this.dgTable.DataGrid.InvalidateRow(number); } public virtual void InvalidateRowRect(Rectangle r) { this.dgTable.DataGrid.InvalidateRowRect(number, r); } ///Gets or sets the bitmap displayed on a row with an error. ////// /// public virtual void OnEdit() { } ///When overridden in a derived class, notifies the grid that an edit will /// occur. ////// /// public virtual bool OnKeyPress(Keys keyData) { int currentColIndex = this.dgTable.DataGrid.CurrentCell.ColumnNumber; GridColumnStylesCollection columns = this.dgTable.GridColumnStyles; if (columns != null && currentColIndex >= 0 && currentColIndex < columns.Count) { DataGridColumnStyle currentColumn = columns[currentColIndex]; if (currentColumn.KeyPress(this.RowNumber, keyData)) { return true; } } return false; } ///When overridden in a derived class, called by the ///control when a key press occurs on a row with focus. /// /// public virtual bool OnMouseDown(int x, int y, Rectangle rowHeaders) { return OnMouseDown(x,y,rowHeaders, false); } ///Called by the ///when a click occurs in the row's client area /// specifed by the x and y coordinates and the specified /// . /// /// public virtual bool OnMouseDown(int x, int y, Rectangle rowHeaders, bool alignToRight) { // if we call base.OnMouseDown, then the row could not use this // mouse click at all. in that case LoseChildFocus, so the edit control // will become visible LoseChildFocus(rowHeaders, alignToRight); // we did not use this click at all. return false; } ///When overridden in a derived class, is called by the ///when a click occurs /// in the row's /// client area, specified by x and y coordinates. /// /// public virtual bool OnMouseMove(int x, int y, Rectangle rowHeaders) { return false; } ////// /// public virtual bool OnMouseMove(int x, int y, Rectangle rowHeaders, bool alignToRight) { return false; } ///When overridden in a derived class, is called by the ///when /// the mouse moves within the row's client area. /// /// public virtual void OnMouseLeft(Rectangle rowHeaders, bool alignToRight) { } public virtual void OnMouseLeft() { } ////// /// public virtual void OnRowEnter() {} public virtual void OnRowLeave() {} // processes the Tab Key // returns TRUE if the TAB key is processed internal abstract bool ProcessTabKey(Keys keyData, Rectangle rowHeaders, bool alignToRight); // tells the dataGridRow that it lost the focus internal abstract void LoseChildFocus(Rectangle rowHeaders, bool alignToRight); ///When overridden in a derived class, causes the RowEnter event to occur. ////// /// Paints the row. /// public abstract int Paint(Graphics g, Rectangle dataBounds, Rectangle rowBounds, int firstVisibleColumn, int numVisibleColumns); public abstract int Paint(Graphics g, Rectangle dataBounds, Rectangle rowBounds, int firstVisibleColumn, int numVisibleColumns, bool alignToRight); ////// /// Draws a border on the bottom DataGrid.GridLineWidth pixels /// of the bounding rectangle passed in. /// protected virtual void PaintBottomBorder(Graphics g, Rectangle bounds, int dataWidth) { PaintBottomBorder(g, bounds, dataWidth, this.dgTable.GridLineWidth, false); } protected virtual void PaintBottomBorder(Graphics g, Rectangle bounds, int dataWidth, int borderWidth, bool alignToRight) { // paint bottom border Rectangle bottomBorder = new Rectangle(alignToRight ? bounds.Right - dataWidth : bounds.X, bounds.Bottom - borderWidth, dataWidth, borderWidth); g.FillRectangle(this.dgTable.IsDefault ? this.DataGrid.GridLineBrush : this.dgTable.GridLineBrush, bottomBorder); // paint any exposed region to the right if (dataWidth < bounds.Width) { g.FillRectangle(this.dgTable.DataGrid.BackgroundBrush, alignToRight ? bounds.X: bottomBorder.Right, bottomBorder.Y, bounds.Width - bottomBorder.Width, borderWidth); } } ////// /// Paints the row. /// public virtual int PaintData(Graphics g, Rectangle bounds, int firstVisibleColumn, int columnCount) { return PaintData(g, bounds, firstVisibleColumn, columnCount, false); } public virtual int PaintData(Graphics g, Rectangle bounds, int firstVisibleColumn, int columnCount, bool alignToRight) { Debug.WriteLineIf(CompModSwitches.DGRowPaint.TraceVerbose, "Painting DataGridAddNewRow: bounds = " + bounds.ToString()); Rectangle cellBounds = bounds; int bWidth = this.dgTable.IsDefault ? this.DataGrid.GridLineWidth : this.dgTable.GridLineWidth; int cx = 0; DataGridCell current = this.dgTable.DataGrid.CurrentCell; GridColumnStylesCollection columns = dgTable.GridColumnStyles; int nCols = columns.Count; for (int col = firstVisibleColumn; col < nCols; ++col) { if (cx > bounds.Width) break; // if (!columns[col].Visible || columns[col].PropertyDescriptor == null) if (columns[col].PropertyDescriptor == null || columns[col].Width <= 0) continue; cellBounds.Width = columns[col].Width - bWidth; if (alignToRight) cellBounds.X = bounds.Right - cx - cellBounds.Width; else cellBounds.X = bounds.X + cx; // Paint the data with the the DataGridColumn Brush backBr = BackBrushForDataPaint(ref current, columns[col], col); Brush foreBrush = ForeBrushForDataPaint(ref current, columns[col], col); PaintCellContents(g, cellBounds, columns[col], backBr, foreBrush, alignToRight); // Paint the border to the right of each cell if (bWidth > 0) { g.FillRectangle(this.dgTable.IsDefault ? this.DataGrid.GridLineBrush : this.dgTable.GridLineBrush, alignToRight ? cellBounds.X - bWidth : cellBounds.Right, cellBounds.Y, bWidth, cellBounds.Height); } cx += cellBounds.Width + bWidth; } // Paint any exposed area to the right ( or left ) of the data cell area if (cx < bounds.Width) { g.FillRectangle(this.dgTable.DataGrid.BackgroundBrush, alignToRight ? bounds.X : bounds.X + cx, bounds.Y, bounds.Width - cx, bounds.Height); } return cx; } protected virtual void PaintCellContents(Graphics g, Rectangle cellBounds, DataGridColumnStyle column, Brush backBr, Brush foreBrush) { PaintCellContents(g, cellBounds, column, backBr, foreBrush, false); } protected virtual void PaintCellContents(Graphics g, Rectangle cellBounds, DataGridColumnStyle column, Brush backBr, Brush foreBrush, bool alignToRight) { g.FillRectangle(backBr, cellBounds); } // // This function will do the following: if paintIcon is set to true, then // will draw the image on the RowHeader. if paintIcon is set to false, // then this function will fill the rectangle on which otherwise will // have been drawn the image // // will return the rectangle that includes the Icon // protected Rectangle PaintIcon(Graphics g, Rectangle visualBounds, bool paintIcon, bool alignToRight, Bitmap bmp) { return PaintIcon(g, visualBounds, paintIcon, alignToRight, bmp, this.dgTable.IsDefault ? this.DataGrid.HeaderBackBrush : this.dgTable.HeaderBackBrush); } protected Rectangle PaintIcon(Graphics g, Rectangle visualBounds, bool paintIcon, bool alignToRight, Bitmap bmp, Brush backBrush) { Size bmpSize = bmp.Size; Rectangle bmpRect = new Rectangle(alignToRight ? visualBounds.Right - xOffset - bmpSize.Width : visualBounds.X + xOffset, visualBounds.Y + yOffset, bmpSize.Width, bmpSize.Height); g.FillRectangle(backBrush, visualBounds); if (paintIcon) { colorMap[0].NewColor = this.dgTable.IsDefault ? this.DataGrid.HeaderForeColor : this.dgTable.HeaderForeColor; colorMap[0].OldColor = Color.Black; ImageAttributes attr = new ImageAttributes(); attr.SetRemapTable(colorMap, ColorAdjustType.Bitmap); g.DrawImage(bmp, bmpRect, 0, 0, bmpRect.Width, bmpRect.Height,GraphicsUnit.Pixel, attr); // g.DrawImage(bmp, bmpRect); attr.Dispose(); } return bmpRect; } // assume that the row is not aligned to right, and that the row is not dirty public virtual void PaintHeader(Graphics g, Rectangle visualBounds) { PaintHeader(g, visualBounds, false); } // assume that the row is not dirty public virtual void PaintHeader(Graphics g, Rectangle visualBounds, bool alignToRight) { PaintHeader(g,visualBounds, alignToRight, false); } public virtual void PaintHeader(Graphics g, Rectangle visualBounds, bool alignToRight, bool rowIsDirty) { Rectangle bounds = visualBounds; // paint the first part of the row header: the Arror or Pencil/Star Bitmap bmp; if (this is DataGridAddNewRow) { bmp = GetStarBitmap(); lock (bmp) { bounds.X += PaintIcon(g, bounds, true, alignToRight, bmp).Width + xOffset; } return; } else if (rowIsDirty) { bmp = GetPencilBitmap(); lock (bmp) { bounds.X += PaintIcon(g, bounds, RowNumber == this.DataGrid.CurrentCell.RowNumber, alignToRight, bmp).Width + xOffset; } } else { bmp = alignToRight ? GetLeftArrowBitmap() : GetRightArrowBitmap(); lock (bmp) { bounds.X += PaintIcon(g, bounds, RowNumber == this.DataGrid.CurrentCell.RowNumber, alignToRight, bmp).Width + xOffset; } } // Paint the error icon // object errorInfo = DataGrid.ListManager[this.number]; if (!(errorInfo is IDataErrorInfo)) return; string errString = ((IDataErrorInfo) errorInfo).Error; if (errString == null) errString = String.Empty; if (tooltip != errString) { if (!String.IsNullOrEmpty(tooltip)) { DataGrid.ToolTipProvider.RemoveToolTip(tooltipID); tooltip = String.Empty; tooltipID = new IntPtr(-1); } } if (String.IsNullOrEmpty(errString)) return; // we now have an error string: paint the errorIcon and add the tooltip Rectangle errRect; bmp = GetErrorBitmap(); lock (bmp) { errRect = PaintIcon(g, bounds, true, alignToRight, bmp); } bounds.X += errRect.Width + xOffset; tooltip = errString; tooltipID = (IntPtr)((int)DataGrid.ToolTipId++); DataGrid.ToolTipProvider.AddToolTip(tooltip, tooltipID, errRect); } protected Brush GetBackBrush() { Brush br = this.dgTable.IsDefault ? DataGrid.BackBrush : this.dgTable.BackBrush; if (DataGrid.LedgerStyle && (RowNumber % 2 == 1)) { br = this.dgTable.IsDefault ? this.DataGrid.AlternatingBackBrush : this.dgTable.AlternatingBackBrush; } return br; } ////// /// Returns the BackColor and TextColor that the Graphics object should use /// for the appropriate values for a given row and column when painting the data. /// /// protected Brush BackBrushForDataPaint(ref DataGridCell current, DataGridColumnStyle gridColumn, int column) { Brush backBr = this.GetBackBrush(); if (Selected) { backBr = this.dgTable.IsDefault ? this.DataGrid.SelectionBackBrush : this.dgTable.SelectionBackBrush; } /* if (RowNumber == current.RowNumber && column == current.ColumnNumber) { backBr = grid.CurrentCellBackBrush; } */ return backBr; } protected Brush ForeBrushForDataPaint(ref DataGridCell current, DataGridColumnStyle gridColumn, int column) { // Brush foreBrush = gridColumn.ForeBrush; Brush foreBrush = this.dgTable.IsDefault ? this.DataGrid.ForeBrush : this.dgTable.ForeBrush; if (Selected) { foreBrush = this.dgTable.IsDefault ? this.DataGrid.SelectionForeBrush : this.dgTable.SelectionForeBrush; } /* if (RowNumber == current.RowNumber && column == current.ColumnNumber) { foreColor = grid.CurrentCellForeColor; } */ return foreBrush; } [ComVisible(true)] protected class DataGridRowAccessibleObject : AccessibleObject { ArrayList cells; DataGridRow owner = null; internal static string CellToDisplayString(DataGrid grid, int row, int column) { if (column < grid.myGridTable.GridColumnStyles.Count) { return grid.myGridTable.GridColumnStyles[column].PropertyDescriptor.Converter.ConvertToString(grid[row, column]); } else { return ""; } } internal static object DisplayStringToCell(DataGrid grid, int row, int column, string value) { if (column < grid.myGridTable.GridColumnStyles.Count) { return grid.myGridTable.GridColumnStyles[column].PropertyDescriptor.Converter.ConvertFromString(value); } // ignore... // return null; } [ SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors") // This class and its derived classes are internal. // So this is not a security back door. ] public DataGridRowAccessibleObject(DataGridRow owner) : base() { Debug.Assert(owner != null, "DataGridRowAccessibleObject must have a valid owner DataGridRow"); this.owner = owner; DataGrid grid = DataGrid; Debug.WriteLineIf(DataGrid.DataGridAcc.TraceVerbose, "Create row accessible object"); EnsureChildren(); } private void EnsureChildren() { if (cells == null) { // default size... little extra for relationships... // cells = new ArrayList(DataGrid.myGridTable.GridColumnStyles.Count + 2); AddChildAccessibleObjects(cells); } } protected virtual void AddChildAccessibleObjects(IList children) { Debug.WriteLineIf(DataGrid.DataGridAcc.TraceVerbose, "Create row's accessible children"); Debug.Indent(); GridColumnStylesCollection cols = DataGrid.myGridTable.GridColumnStyles; int len = cols.Count; Debug.WriteLineIf(DataGrid.DataGridAcc.TraceVerbose, len + " columns present"); for (int i=0; i/// /// Returns the currently focused child, if any. /// Returns this if the object itself is focused. /// public override AccessibleObject GetFocused() { if (DataGrid.Focused) { DataGridCell cell = DataGrid.CurrentCell; if (cell.RowNumber == owner.RowNumber) { return (AccessibleObject)cells[cell.ColumnNumber]; } } return null; } ////// /// Navigate to the next or previous grid entry.entry. /// [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override AccessibleObject Navigate(AccessibleNavigation navdir) { switch (navdir) { case AccessibleNavigation.Down: case AccessibleNavigation.Right: case AccessibleNavigation.Next: return DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber + 1); case AccessibleNavigation.Up: case AccessibleNavigation.Left: case AccessibleNavigation.Previous: return DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber - 1); case AccessibleNavigation.FirstChild: if (GetChildCount() > 0) { return GetChild(0); } break; case AccessibleNavigation.LastChild: if (GetChildCount() > 0) { return GetChild(GetChildCount() - 1); } break; } return null; } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override void Select(AccessibleSelection flags) { // Focus the PropertyGridView window // if ( (flags & AccessibleSelection.TakeFocus) == AccessibleSelection.TakeFocus) { DataGrid.Focus(); } // Select the grid entry // if ( (flags & AccessibleSelection.TakeSelection) == AccessibleSelection.TakeSelection) { DataGrid.CurrentRowIndex = owner.RowNumber; } } } [ComVisible(true)] protected class DataGridCellAccessibleObject : AccessibleObject { DataGridRow owner = null; int column; public DataGridCellAccessibleObject(DataGridRow owner, int column) : base() { Debug.Assert(owner != null, "DataGridColumnAccessibleObject must have a valid owner DataGridRow"); this.owner = owner; this.column = column; Debug.WriteLineIf(DataGrid.DataGridAcc.TraceVerbose, "Create cell accessible object"); } public override Rectangle Bounds { get { return DataGrid.RectangleToScreen(DataGrid.GetCellBounds(new DataGridCell(owner.RowNumber, column))); } } public override string Name { get { return DataGrid.myGridTable.GridColumnStyles[column].HeaderText; } } public override AccessibleObject Parent { [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] get { return owner.AccessibleObject; } } protected DataGrid DataGrid { get { return owner.DataGrid; } } public override string DefaultAction { get { return SR.GetString(SR.AccDGEdit); } } public override AccessibleRole Role { get { return AccessibleRole.Cell; } } public override AccessibleStates State { get { AccessibleStates state = AccessibleStates.Selectable | AccessibleStates.Focusable; // Determine focus // if (DataGrid.CurrentCell.RowNumber == owner.RowNumber && DataGrid.CurrentCell.ColumnNumber == column) { if (DataGrid.Focused) { state |= AccessibleStates.Focused; } state |= AccessibleStates.Selected; } return state; } } public override string Value { [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] get { if (owner is DataGridAddNewRow) { return null; } else { return DataGridRowAccessibleObject.CellToDisplayString(DataGrid, owner.RowNumber, column); } } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] set { if (!(owner is DataGridAddNewRow)) { object realValue = DataGridRowAccessibleObject.DisplayStringToCell(DataGrid, owner.RowNumber, column, value); DataGrid[owner.RowNumber, column] = realValue; } } } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override void DoDefaultAction() { Select(AccessibleSelection.TakeFocus | AccessibleSelection.TakeSelection); } ////// /// Returns the currently focused child, if any. /// Returns this if the object itself is focused. /// public override AccessibleObject GetFocused() { // Datagrid always returns the cell as the focused thing... so do we! // return DataGrid.AccessibilityObject.GetFocused(); } ////// /// Navigate to the next or previous grid entry. /// [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override AccessibleObject Navigate(AccessibleNavigation navdir) { switch (navdir) { case AccessibleNavigation.Right: case AccessibleNavigation.Next: if (column < owner.AccessibleObject.GetChildCount() - 1) { return owner.AccessibleObject.GetChild(column + 1); } else { AccessibleObject o = DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber + 1); if (o != null) { return o.Navigate(AccessibleNavigation.FirstChild); } } break; case AccessibleNavigation.Down: return DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber + 1).Navigate(AccessibleNavigation.FirstChild); case AccessibleNavigation.Up: return DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber - 1).Navigate(AccessibleNavigation.FirstChild); case AccessibleNavigation.Left: case AccessibleNavigation.Previous: if (column > 0) { return owner.AccessibleObject.GetChild(column - 1); } else { AccessibleObject o = DataGrid.AccessibilityObject.GetChild(1 + owner.dgTable.GridColumnStyles.Count + owner.RowNumber - 1); if (o != null) { return o.Navigate(AccessibleNavigation.LastChild); } } break; case AccessibleNavigation.FirstChild: case AccessibleNavigation.LastChild: break; } return null; } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override void Select(AccessibleSelection flags) { // Focus the PropertyGridView window // if ( (flags & AccessibleSelection.TakeFocus) == AccessibleSelection.TakeFocus) { DataGrid.Focus(); } // Select the grid entry // if ( (flags & AccessibleSelection.TakeSelection) == AccessibleSelection.TakeSelection) { DataGrid.CurrentCell = new DataGridCell(owner.RowNumber, column); } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataFormat.cs
- IdentifierElement.cs
- Utils.cs
- ScriptControl.cs
- CollectionContainer.cs
- MenuAutoFormat.cs
- MenuItemStyle.cs
- IncrementalCompileAnalyzer.cs
- WebPageTraceListener.cs
- XmlEnumAttribute.cs
- SplashScreenNativeMethods.cs
- MultiTargetingUtil.cs
- PointLightBase.cs
- BuiltInExpr.cs
- ResourceDescriptionAttribute.cs
- TableItemPattern.cs
- RecognizerInfo.cs
- DispatcherOperation.cs
- FilteredDataSetHelper.cs
- mediaeventargs.cs
- ListMarkerSourceInfo.cs
- SqlMetaData.cs
- PrintEvent.cs
- PackageDigitalSignature.cs
- XmlWrappingReader.cs
- SafeProcessHandle.cs
- RelationshipManager.cs
- ExcCanonicalXml.cs
- DefaultValidator.cs
- MissingManifestResourceException.cs
- _ListenerAsyncResult.cs
- GridEntry.cs
- PointLight.cs
- MutableAssemblyCacheEntry.cs
- ELinqQueryState.cs
- DataObjectCopyingEventArgs.cs
- Event.cs
- OutputCacheModule.cs
- MenuItemBindingCollection.cs
- DecimalAnimationBase.cs
- Journal.cs
- DynamicHyperLink.cs
- MetafileHeaderWmf.cs
- GridErrorDlg.cs
- DataExpression.cs
- MimeAnyImporter.cs
- FieldBuilder.cs
- BaseAppDomainProtocolHandler.cs
- ValidatedControlConverter.cs
- AnnotationComponentChooser.cs
- FloaterBaseParagraph.cs
- SqlCommandAsyncResult.cs
- EventLogPermission.cs
- KeyGestureValueSerializer.cs
- PlaceHolder.cs
- Random.cs
- UDPClient.cs
- SystemResources.cs
- CollectionViewSource.cs
- ProxyAssemblyNotLoadedException.cs
- ViewKeyConstraint.cs
- ContractSearchPattern.cs
- DataSetMappper.cs
- SeverityFilter.cs
- XmlHierarchyData.cs
- IsolatedStorageFile.cs
- UriParserTemplates.cs
- DefaultMergeHelper.cs
- DataGridCommandEventArgs.cs
- MimeBasePart.cs
- ColumnProvider.cs
- TabletDevice.cs
- SingleConverter.cs
- NameValueCollection.cs
- SiblingIterators.cs
- Switch.cs
- WebPartRestoreVerb.cs
- StylusCollection.cs
- ManagementEventArgs.cs
- GorillaCodec.cs
- GridViewSelectEventArgs.cs
- RijndaelManagedTransform.cs
- ObjectDataSourceDisposingEventArgs.cs
- _OverlappedAsyncResult.cs
- HiddenField.cs
- SQLStringStorage.cs
- ActivityValidationServices.cs
- WindowsTreeView.cs
- ValidatedControlConverter.cs
- WebPartHelpVerb.cs
- MulticastDelegate.cs
- RandomNumberGenerator.cs
- WorkflowWebService.cs
- ScriptControl.cs
- QuaternionRotation3D.cs
- WinInet.cs
- WorkflowView.cs
- OverflowException.cs
- GcHandle.cs
- ClientRuntimeConfig.cs