protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates dataGridViewElementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) { if (cellStyle == null) { throw new ArgumentNullException(nameof(cellStyle)); } if (DataGridViewCell.PaintBorder(paintParts)) { PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); } if (DataGridViewCell.PaintBackground(paintParts)) { Rectangle valBounds = cellBounds; Rectangle borderWidths = BorderWidths(advancedBorderStyle); valBounds.Offset(borderWidths.X, borderWidths.Y); valBounds.Width -= borderWidths.Right; valBounds.Height -= borderWidths.Bottom; bool cellSelected = (dataGridViewElementState & DataGridViewElementStates.Selected) != 0; SolidBrush br = DataGridView.GetCachedBrush((DataGridViewCell.PaintSelectionBackground(paintParts) && cellSelected) ? cellStyle.SelectionBackColor : cellStyle.BackColor); if (br.Color.A == 255) { graphics.FillRectangle(br, valBounds); } } }
// PaintPrivate is used in three places that need to duplicate the paint code: // 1. DataGridViewCell::Paint method // 2. DataGridViewCell::GetContentBounds // 3. DataGridViewCell::GetErrorIconBounds // // if computeContentBounds is true then PaintPrivate returns the contentBounds // else if computeErrorIconBounds is true then PaintPrivate returns the errorIconBounds // else it returns Rectangle.Empty; private Rectangle PaintPrivate(Graphics g, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts, bool computeContentBounds, bool computeErrorIconBounds, bool paint) { // Parameter checking. // One bit and one bit only should be turned on Debug.Assert(paint || computeContentBounds || computeErrorIconBounds); Debug.Assert(!paint || !computeContentBounds || !computeErrorIconBounds); Debug.Assert(!computeContentBounds || !computeErrorIconBounds || !paint); Debug.Assert(!computeErrorIconBounds || !paint || !computeContentBounds); Debug.Assert(cellStyle != null); if (paint && DataGridViewCell.PaintBorder(paintParts)) { PaintBorder(g, clipBounds, cellBounds, cellStyle, advancedBorderStyle); } Rectangle resultBounds; Rectangle valBounds = cellBounds; Rectangle borderWidths = BorderWidths(advancedBorderStyle); valBounds.Offset(borderWidths.X, borderWidths.Y); valBounds.Width -= borderWidths.Right; valBounds.Height -= borderWidths.Bottom; if (valBounds.Width > 0 && valBounds.Height > 0 && (paint || computeContentBounds)) { Rectangle imgBounds = valBounds; if (cellStyle.Padding != Padding.Empty) { if (DataGridView.RightToLeftInternal) { imgBounds.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top); } else { imgBounds.Offset(cellStyle.Padding.Left, cellStyle.Padding.Top); } imgBounds.Width -= cellStyle.Padding.Horizontal; imgBounds.Height -= cellStyle.Padding.Vertical; } bool cellSelected = (elementState & DataGridViewElementStates.Selected) != 0; SolidBrush br = DataGridView.GetCachedBrush((DataGridViewCell.PaintSelectionBackground(paintParts) && cellSelected) ? cellStyle.SelectionBackColor : cellStyle.BackColor); if (imgBounds.Width > 0 && imgBounds.Height > 0) { Image img = formattedValue as Image; Icon ico = null; if (img == null) { ico = formattedValue as Icon; } if (ico != null || img != null) { DataGridViewImageCellLayout imageLayout = ImageLayout; if (imageLayout == DataGridViewImageCellLayout.NotSet) { if (OwningColumn is DataGridViewImageColumn) { imageLayout = ((DataGridViewImageColumn)OwningColumn).ImageLayout; Debug.Assert(imageLayout != DataGridViewImageCellLayout.NotSet); } else { imageLayout = DataGridViewImageCellLayout.Normal; } } if (imageLayout == DataGridViewImageCellLayout.Stretch) { if (paint) { if (DataGridViewCell.PaintBackground(paintParts)) { DataGridViewCell.PaintPadding(g, valBounds, cellStyle, br, DataGridView.RightToLeftInternal); } if (DataGridViewCell.PaintContentForeground(paintParts)) { if (img != null) { // ImageAttributes attr = new ImageAttributes(); attr.SetWrapMode(WrapMode.TileFlipXY); g.DrawImage(img, imgBounds, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, attr); attr.Dispose(); } else { g.DrawIcon(ico, imgBounds); } } } resultBounds = imgBounds; } else { Rectangle imgBounds2 = ImgBounds(imgBounds, (img == null) ? ico.Width : img.Width, (img == null) ? ico.Height : img.Height, imageLayout, cellStyle); resultBounds = imgBounds2; if (paint) { if (DataGridViewCell.PaintBackground(paintParts) && br.Color.A == 255) { g.FillRectangle(br, valBounds); } if (DataGridViewCell.PaintContentForeground(paintParts)) { //paint the image Region reg = g.Clip; g.SetClip(Rectangle.Intersect(Rectangle.Intersect(imgBounds2, imgBounds), Rectangle.Truncate(g.VisibleClipBounds))); if (img != null) { g.DrawImage(img, imgBounds2); } else { g.DrawIconUnstretched(ico, imgBounds2); } g.Clip = reg; } } } } else { if (paint && DataGridViewCell.PaintBackground(paintParts) && br.Color.A == 255) { g.FillRectangle(br, valBounds); } resultBounds = Rectangle.Empty; } } else { if (paint && DataGridViewCell.PaintBackground(paintParts) && br.Color.A == 255) { g.FillRectangle(br, valBounds); } resultBounds = Rectangle.Empty; } Point ptCurrentCell = DataGridView.CurrentCellAddress; if (paint && DataGridViewCell.PaintFocus(paintParts) && ptCurrentCell.X == ColumnIndex && ptCurrentCell.Y == rowIndex && DataGridView.ShowFocusCues && DataGridView.Focused) { // Draw focus rectangle ControlPaint.DrawFocusRectangle(g, valBounds, Color.Empty, br.Color); } if (DataGridView.ShowCellErrors && paint && DataGridViewCell.PaintErrorIcon(paintParts)) { PaintErrorIcon(g, cellStyle, rowIndex, cellBounds, valBounds, errorText); } } else if (computeErrorIconBounds) { if (!string.IsNullOrEmpty(errorText)) { resultBounds = ComputeErrorIconBounds(valBounds); } else { resultBounds = Rectangle.Empty; } } else { Debug.Assert(valBounds.Height <= 0 || valBounds.Width <= 0); resultBounds = Rectangle.Empty; } return(resultBounds); }
// PaintPrivate is used in three places that need to duplicate the paint code: // 1. DataGridViewCell::Paint method // 2. DataGridViewCell::GetContentBounds // 3. DataGridViewCell::GetErrorIconBounds // // if computeContentBounds is true then PaintPrivate returns the contentBounds // else if computeErrorIconBounds is true then PaintPrivate returns the errorIconBounds // else it returns Rectangle.Empty; private Rectangle PaintPrivate(Graphics g, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts, bool computeContentBounds, bool computeErrorIconBounds, bool paint) { // Parameter checking. // One bit and one bit only should be turned on Debug.Assert(paint || computeContentBounds || computeErrorIconBounds); Debug.Assert(!paint || !computeContentBounds || !computeErrorIconBounds); Debug.Assert(!computeContentBounds || !computeErrorIconBounds || !paint); Debug.Assert(!computeErrorIconBounds || !paint || !computeContentBounds); Debug.Assert(cellStyle != null); if (paint && DataGridViewCell.PaintBorder(paintParts)) { PaintBorder(g, clipBounds, cellBounds, cellStyle, advancedBorderStyle); } Rectangle resultBounds = Rectangle.Empty; Rectangle borderWidths = BorderWidths(advancedBorderStyle); Rectangle valBounds = cellBounds; valBounds.Offset(borderWidths.X, borderWidths.Y); valBounds.Width -= borderWidths.Right; valBounds.Height -= borderWidths.Bottom; Point ptCurrentCell = DataGridView.CurrentCellAddress; bool cellCurrent = ptCurrentCell.X == ColumnIndex && ptCurrentCell.Y == rowIndex; bool cellSelected = (cellState & DataGridViewElementStates.Selected) != 0; SolidBrush br = DataGridView.GetCachedBrush((DataGridViewCell.PaintSelectionBackground(paintParts) && cellSelected) ? cellStyle.SelectionBackColor : cellStyle.BackColor); if (paint && DataGridViewCell.PaintBackground(paintParts) && br.Color.A == 255) { g.FillRectangle(br, valBounds); } if (cellStyle.Padding != Padding.Empty) { if (DataGridView.RightToLeftInternal) { valBounds.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top); } else { valBounds.Offset(cellStyle.Padding.Left, cellStyle.Padding.Top); } valBounds.Width -= cellStyle.Padding.Horizontal; valBounds.Height -= cellStyle.Padding.Vertical; } Rectangle errorBounds = valBounds; if (formattedValue is string formattedValueStr && (paint || computeContentBounds)) { // Font independent margins valBounds.Offset(DATAGRIDVIEWLINKCELL_horizontalTextMarginLeft, DATAGRIDVIEWLINKCELL_verticalTextMarginTop); valBounds.Width -= DATAGRIDVIEWLINKCELL_horizontalTextMarginLeft + DATAGRIDVIEWLINKCELL_horizontalTextMarginRight; valBounds.Height -= DATAGRIDVIEWLINKCELL_verticalTextMarginTop + DATAGRIDVIEWLINKCELL_verticalTextMarginBottom; if ((cellStyle.Alignment & anyBottom) != 0) { valBounds.Height -= DATAGRIDVIEWLINKCELL_verticalTextMarginBottom; } Font linkFont = null; Font hoverFont = null; LinkUtilities.EnsureLinkFonts(cellStyle.Font, LinkBehavior, ref linkFont, ref hoverFont); TextFormatFlags flags = DataGridViewUtilities.ComputeTextFormatFlagsForCellStyleAlignment(DataGridView.RightToLeftInternal, cellStyle.Alignment, cellStyle.WrapMode); // paint the focus rectangle around the link if (paint) { if (valBounds.Width > 0 && valBounds.Height > 0) { if (cellCurrent && DataGridView.ShowFocusCues && DataGridView.Focused && DataGridViewCell.PaintFocus(paintParts)) { Rectangle focusBounds = DataGridViewUtilities.GetTextBounds(valBounds, formattedValueStr, flags, cellStyle, LinkState == LinkState.Hover ? hoverFont : linkFont); if ((cellStyle.Alignment & anyLeft) != 0) { focusBounds.X--; focusBounds.Width++; } else if ((cellStyle.Alignment & anyRight) != 0) { focusBounds.X++; focusBounds.Width++; } focusBounds.Height += 2; ControlPaint.DrawFocusRectangle(g, focusBounds, Color.Empty, br.Color); } Color linkColor; if ((LinkState & LinkState.Active) == LinkState.Active) { linkColor = ActiveLinkColor; } else if (LinkVisited) { linkColor = VisitedLinkColor; } else { linkColor = LinkColor; } if (DataGridViewCell.PaintContentForeground(paintParts)) { if ((flags & TextFormatFlags.SingleLine) != 0) { flags |= TextFormatFlags.EndEllipsis; } TextRenderer.DrawText(g, formattedValueStr, LinkState == LinkState.Hover ? hoverFont : linkFont, valBounds, linkColor, flags); } } else if (cellCurrent && DataGridView.ShowFocusCues && DataGridView.Focused && DataGridViewCell.PaintFocus(paintParts) && errorBounds.Width > 0 && errorBounds.Height > 0) { // Draw focus rectangle ControlPaint.DrawFocusRectangle(g, errorBounds, Color.Empty, br.Color); } } else { Debug.Assert(computeContentBounds); resultBounds = DataGridViewUtilities.GetTextBounds(valBounds, formattedValueStr, flags, cellStyle, LinkState == LinkState.Hover ? hoverFont : linkFont); } linkFont.Dispose(); hoverFont.Dispose(); }
private Rectangle PaintPrivate(Graphics g, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts, bool computeContentBounds, bool computeErrorIconBounds, bool paint) { // Parameter checking. // One bit and one bit only should be turned on Debug.Assert(paint || computeContentBounds || computeErrorIconBounds); Debug.Assert(!paint || !computeContentBounds || !computeErrorIconBounds); Debug.Assert(!computeContentBounds || !computeErrorIconBounds || !paint); Debug.Assert(!computeErrorIconBounds || !paint || !computeContentBounds); Debug.Assert(cellStyle != null); Point ptCurrentCell = DataGridView.CurrentCellAddress; bool cellSelected = (elementState & DataGridViewElementStates.Selected) != 0; bool cellCurrent = (ptCurrentCell.X == ColumnIndex && ptCurrentCell.Y == rowIndex); Rectangle resultBounds; string formattedString = formattedValue as string; SolidBrush backBrush = DataGridView.GetCachedBrush((PaintSelectionBackground(paintParts) && cellSelected) ? cellStyle.SelectionBackColor : cellStyle.BackColor); SolidBrush foreBrush = DataGridView.GetCachedBrush(cellSelected ? cellStyle.SelectionForeColor : cellStyle.ForeColor); if (paint && PaintBorder(paintParts)) { PaintBorder(g, clipBounds, cellBounds, cellStyle, advancedBorderStyle); } Rectangle valBounds = cellBounds; Rectangle borderWidths = BorderWidths(advancedBorderStyle); valBounds.Offset(borderWidths.X, borderWidths.Y); valBounds.Width -= borderWidths.Right; valBounds.Height -= borderWidths.Bottom; if (valBounds.Height <= 0 || valBounds.Width <= 0) { return(Rectangle.Empty); } if (paint && PaintBackground(paintParts) && backBrush.Color.A == 255) { g.FillRectangle(backBrush, valBounds); } if (cellStyle.Padding != Padding.Empty) { if (DataGridView.RightToLeftInternal) { valBounds.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top); } else { valBounds.Offset(cellStyle.Padding.Left, cellStyle.Padding.Top); } valBounds.Width -= cellStyle.Padding.Horizontal; valBounds.Height -= cellStyle.Padding.Vertical; } Rectangle errorBounds = valBounds; if (valBounds.Height > 0 && valBounds.Width > 0 && (paint || computeContentBounds)) { switch (FlatStyle) { case FlatStyle.Standard: case FlatStyle.System: if (DataGridView.ApplyVisualStylesToInnerCells) { if (paint && PaintContentBackground(paintParts)) { PushButtonState pbState = VisualStyles.PushButtonState.Normal; if ((ButtonState & (ButtonState.Pushed | ButtonState.Checked)) != 0) { pbState = PushButtonState.Pressed; } else if (DataGridView.MouseEnteredCellAddress.Y == rowIndex && DataGridView.MouseEnteredCellAddress.X == ColumnIndex && mouseInContentBounds) { pbState = PushButtonState.Hot; } if (PaintFocus(paintParts) && cellCurrent && DataGridView.ShowFocusCues && DataGridView.Focused) { pbState |= PushButtonState.Default; } DataGridViewButtonCellRenderer.DrawButton(g, valBounds, (int)pbState); } resultBounds = valBounds; valBounds = DataGridViewButtonCellRenderer.DataGridViewButtonRenderer.GetBackgroundContentRectangle(g, valBounds); } else { if (paint && PaintContentBackground(paintParts)) { ControlPaint.DrawBorder( g, valBounds, SystemColors.Control, (ButtonState == ButtonState.Normal) ? ButtonBorderStyle.Outset : ButtonBorderStyle.Inset); } resultBounds = valBounds; valBounds.Inflate(-SystemInformation.Border3DSize.Width, -SystemInformation.Border3DSize.Height); } break; case FlatStyle.Flat: // ButtonBase::PaintFlatDown and ButtonBase::PaintFlatUp paint the border in the same way valBounds.Inflate(-1, -1); if (paint && PaintContentBackground(paintParts)) { ButtonBaseAdapter.DrawDefaultBorder(g, valBounds, foreBrush.Color, true /*isDefault == true*/); if (backBrush.Color.A == 255) { if ((ButtonState & (ButtonState.Pushed | ButtonState.Checked)) != 0) { ButtonBaseAdapter.ColorData colors = ButtonBaseAdapter.PaintFlatRender( g, cellStyle.ForeColor, cellStyle.BackColor, DataGridView.Enabled).Calculate(); using var hdc = new DeviceContextHdcScope(g); using var hbrush = new Gdi32.CreateBrushScope( colors.options.HighContrast ? colors.buttonShadow : colors.lowHighlight); hdc.FillRectangle(valBounds, hbrush); } else if (DataGridView.MouseEnteredCellAddress.Y == rowIndex && DataGridView.MouseEnteredCellAddress.X == ColumnIndex && mouseInContentBounds) { using var hdc = new DeviceContextHdcScope(g); using var hbrush = new Gdi32.CreateBrushScope(SystemColors.ControlDark); hdc.FillRectangle(valBounds, hbrush); } } } resultBounds = valBounds; break; default: Debug.Assert(FlatStyle == FlatStyle.Popup, "FlatStyle.Popup is the last flat style"); valBounds.Inflate(-1, -1); if (paint && PaintContentBackground(paintParts)) { if ((ButtonState & (ButtonState.Pushed | ButtonState.Checked)) != 0) { // paint down ButtonBaseAdapter.ColorData colors = ButtonBaseAdapter.PaintPopupRender( g, cellStyle.ForeColor, cellStyle.BackColor, DataGridView.Enabled).Calculate(); ButtonBaseAdapter.DrawDefaultBorder( g, valBounds, colors.options.HighContrast ? colors.windowText : colors.windowFrame, isDefault: true); ControlPaint.DrawBorder( g, valBounds, colors.options.HighContrast ? colors.windowText : colors.buttonShadow, ButtonBorderStyle.Solid); } else if (DataGridView.MouseEnteredCellAddress.Y == rowIndex && DataGridView.MouseEnteredCellAddress.X == ColumnIndex && mouseInContentBounds) { // paint over ButtonBaseAdapter.ColorData colors = ButtonBaseAdapter.PaintPopupRender( g, cellStyle.ForeColor, cellStyle.BackColor, DataGridView.Enabled).Calculate(); ButtonBaseAdapter.DrawDefaultBorder( g, valBounds, colors.options.HighContrast ? colors.windowText : colors.buttonShadow, isDefault: false); ButtonBaseAdapter.Draw3DLiteBorder(g, valBounds, colors, true); } else { // paint up ButtonBaseAdapter.ColorData colors = ButtonBaseAdapter.PaintPopupRender( g, cellStyle.ForeColor, cellStyle.BackColor, DataGridView.Enabled).Calculate(); ButtonBaseAdapter.DrawDefaultBorder( g, valBounds, colors.options.HighContrast ? colors.windowText : colors.buttonShadow, isDefault: false); ControlPaint.DrawBorderSolid( g, valBounds, colors.options.HighContrast ? colors.windowText : colors.buttonShadow); } } resultBounds = valBounds; break; } } else if (computeErrorIconBounds) { if (!string.IsNullOrEmpty(errorText)) { resultBounds = ComputeErrorIconBounds(errorBounds); } else { resultBounds = Rectangle.Empty; } } else { Debug.Assert(valBounds.Height <= 0 || valBounds.Width <= 0); resultBounds = Rectangle.Empty; } if (paint && PaintFocus(paintParts) && cellCurrent && DataGridView.ShowFocusCues && DataGridView.Focused && valBounds.Width > 2 * SystemInformation.Border3DSize.Width + 1 && valBounds.Height > 2 * SystemInformation.Border3DSize.Height + 1) { // Draw focus rectangle if (FlatStyle == FlatStyle.System || FlatStyle == FlatStyle.Standard) { ControlPaint.DrawFocusRectangle(g, Rectangle.Inflate(valBounds, -1, -1), Color.Empty, SystemColors.Control); } else if (FlatStyle == FlatStyle.Flat) { if ((ButtonState & (ButtonState.Pushed | ButtonState.Checked)) != 0 || (DataGridView.CurrentCellAddress.Y == rowIndex && DataGridView.CurrentCellAddress.X == ColumnIndex)) { ButtonBaseAdapter.ColorData colors = ButtonBaseAdapter.PaintFlatRender( g, cellStyle.ForeColor, cellStyle.BackColor, DataGridView.Enabled).Calculate(); string text = formattedString ?? string.Empty; ButtonBaseAdapter.LayoutOptions options = ButtonFlatAdapter.PaintFlatLayout( true, SystemInformation.HighContrast, 1, valBounds, Padding.Empty, false, cellStyle.Font, text, DataGridView.Enabled, DataGridViewUtilities.ComputeDrawingContentAlignmentForCellStyleAlignment(cellStyle.Alignment), DataGridView.RightToLeft); options.everettButtonCompat = false; ButtonBaseAdapter.LayoutData layout = options.Layout(); ButtonBaseAdapter.DrawFlatFocus( g, layout.focus, colors.options.HighContrast ? colors.windowText : colors.constrastButtonShadow); } } else { Debug.Assert(FlatStyle == FlatStyle.Popup, "FlatStyle.Popup is the last flat style"); if ((ButtonState & (ButtonState.Pushed | ButtonState.Checked)) != 0 || (DataGridView.CurrentCellAddress.Y == rowIndex && DataGridView.CurrentCellAddress.X == ColumnIndex)) { // If we are painting the current cell, then paint the text up. // If we are painting the current cell and the current cell is pressed down, then paint the text down. bool paintUp = (ButtonState == ButtonState.Normal); string text = formattedString ?? string.Empty; ButtonBaseAdapter.LayoutOptions options = ButtonPopupAdapter.PaintPopupLayout( paintUp, SystemInformation.HighContrast ? 2 : 1, valBounds, Padding.Empty, false, cellStyle.Font, text, DataGridView.Enabled, DataGridViewUtilities.ComputeDrawingContentAlignmentForCellStyleAlignment(cellStyle.Alignment), DataGridView.RightToLeft); options.everettButtonCompat = false; ButtonBaseAdapter.LayoutData layout = options.Layout(); ControlPaint.DrawFocusRectangle( g, layout.focus, cellStyle.ForeColor, cellStyle.BackColor); } } } if (formattedString != null && paint && DataGridViewCell.PaintContentForeground(paintParts)) { // Font independent margins valBounds.Offset(DATAGRIDVIEWBUTTONCELL_horizontalTextMargin, DATAGRIDVIEWBUTTONCELL_verticalTextMargin); valBounds.Width -= 2 * DATAGRIDVIEWBUTTONCELL_horizontalTextMargin; valBounds.Height -= 2 * DATAGRIDVIEWBUTTONCELL_verticalTextMargin; if ((ButtonState & (ButtonState.Pushed | ButtonState.Checked)) != 0 && FlatStyle != FlatStyle.Flat && FlatStyle != FlatStyle.Popup) { valBounds.Offset(1, 1); valBounds.Width--; valBounds.Height--; } if (valBounds.Width > 0 && valBounds.Height > 0) { Color textColor; if (DataGridView.ApplyVisualStylesToInnerCells && (FlatStyle == FlatStyle.System || FlatStyle == FlatStyle.Standard)) { textColor = DataGridViewButtonCellRenderer.DataGridViewButtonRenderer.GetColor(ColorProperty.TextColor); } else { textColor = foreBrush.Color; } TextFormatFlags flags = DataGridViewUtilities.ComputeTextFormatFlagsForCellStyleAlignment(DataGridView.RightToLeftInternal, cellStyle.Alignment, cellStyle.WrapMode); TextRenderer.DrawText(g, formattedString, cellStyle.Font, valBounds, textColor, flags); } } if (DataGridView.ShowCellErrors && paint && PaintErrorIcon(paintParts)) { PaintErrorIcon(g, cellStyle, rowIndex, cellBounds, errorBounds, errorText); } return(resultBounds); }
// PaintPrivate is used in three places that need to duplicate the paint code: // 1. DataGridViewCell::Paint method // 2. DataGridViewCell::GetContentBounds // 3. DataGridViewCell::GetErrorIconBounds // // if computeContentBounds is true then PaintPrivate returns the contentBounds // else if computeErrorIconBounds is true then PaintPrivate returns the errorIconBounds // else it returns Rectangle.Empty; private Rectangle PaintPrivate(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts, bool computeContentBounds, bool computeErrorIconBounds, bool paint) { // Parameter checking. // One bit and one bit only should be turned on Debug.Assert(paint || computeContentBounds || computeErrorIconBounds); Debug.Assert(!paint || !computeContentBounds || !computeErrorIconBounds); Debug.Assert(!computeContentBounds || !computeErrorIconBounds || !paint); Debug.Assert(!computeErrorIconBounds || !paint || !computeContentBounds); Debug.Assert(cellStyle != null); // If computeContentBounds == TRUE then resultBounds will be the contentBounds. // If computeErrorIconBounds == TRUE then resultBounds will be the error icon bounds. // Else resultBounds will be Rectangle.Empty; Rectangle resultBounds = Rectangle.Empty; Rectangle valBounds = cellBounds; Rectangle borderWidths = BorderWidths(advancedBorderStyle); valBounds.Offset(borderWidths.X, borderWidths.Y); valBounds.Width -= borderWidths.Right; valBounds.Height -= borderWidths.Bottom; bool cellSelected = (cellState & DataGridViewElementStates.Selected) != 0; if (paint && DataGridViewCell.PaintBackground(paintParts)) { if (DataGridView.ApplyVisualStylesToHeaderCells) { // Theming int state = (int)HeaderItemState.Normal; if (ButtonState != ButtonState.Normal) { Debug.Assert(ButtonState == ButtonState.Pushed); state = (int)HeaderItemState.Pressed; } else if (DataGridView.MouseEnteredCellAddress.Y == rowIndex && DataGridView.MouseEnteredCellAddress.X == ColumnIndex) { state = (int)HeaderItemState.Hot; } valBounds.Inflate(16, 16); DataGridViewTopLeftHeaderCellRenderer.DrawHeader(graphics, valBounds, state); valBounds.Inflate(-16, -16); } else { SolidBrush br = DataGridView.GetCachedBrush((DataGridViewCell.PaintSelectionBackground(paintParts) && cellSelected) ? cellStyle.SelectionBackColor : cellStyle.BackColor); if (br.Color.A == 255) { graphics.FillRectangle(br, valBounds); } } } if (paint && DataGridViewCell.PaintBorder(paintParts)) { PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); } if (cellStyle.Padding != Padding.Empty) { if (DataGridView.RightToLeftInternal) { valBounds.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top); } else { valBounds.Offset(cellStyle.Padding.Left, cellStyle.Padding.Top); } valBounds.Width -= cellStyle.Padding.Horizontal; valBounds.Height -= cellStyle.Padding.Vertical; } Rectangle errorBounds = valBounds; string formattedValueStr = formattedValue as string; // Font independent margins valBounds.Offset(DATAGRIDVIEWTOPLEFTHEADERCELL_horizontalTextMarginLeft, DATAGRIDVIEWTOPLEFTHEADERCELL_verticalTextMargin); valBounds.Width -= DATAGRIDVIEWTOPLEFTHEADERCELL_horizontalTextMarginLeft + DATAGRIDVIEWTOPLEFTHEADERCELL_horizontalTextMarginRight; valBounds.Height -= 2 * DATAGRIDVIEWTOPLEFTHEADERCELL_verticalTextMargin; if (valBounds.Width > 0 && valBounds.Height > 0 && !string.IsNullOrEmpty(formattedValueStr) && (paint || computeContentBounds)) { Color textColor; if (DataGridView.ApplyVisualStylesToHeaderCells) { textColor = DataGridViewTopLeftHeaderCellRenderer.VisualStyleRenderer.GetColor(ColorProperty.TextColor); } else { textColor = cellSelected ? cellStyle.SelectionForeColor : cellStyle.ForeColor; } TextFormatFlags flags = DataGridViewUtilities.ComputeTextFormatFlagsForCellStyleAlignment(DataGridView.RightToLeftInternal, cellStyle.Alignment, cellStyle.WrapMode); if (paint) { if (DataGridViewCell.PaintContentForeground(paintParts)) { if ((flags & TextFormatFlags.SingleLine) != 0) { flags |= TextFormatFlags.EndEllipsis; } TextRenderer.DrawText(graphics, formattedValueStr, cellStyle.Font, valBounds, textColor, flags); } } else { Debug.Assert(computeContentBounds); resultBounds = DataGridViewUtilities.GetTextBounds(valBounds, formattedValueStr, flags, cellStyle); } } else if (computeErrorIconBounds && !string.IsNullOrEmpty(errorText)) { resultBounds = ComputeErrorIconBounds(errorBounds); } if (DataGridView.ShowCellErrors && paint && DataGridViewCell.PaintErrorIcon(paintParts)) { PaintErrorIcon(graphics, cellStyle, rowIndex, cellBounds, errorBounds, errorText); } return(resultBounds); }
private Rectangle PaintPrivate(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates dataGridViewElementState, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts, bool computeContentBounds, bool computeErrorIconBounds, bool paint) { // Parameter checking. // One bit and one bit only should be turned on Debug.Assert(paint || computeContentBounds || computeErrorIconBounds); Debug.Assert(!paint || !computeContentBounds || !computeErrorIconBounds); Debug.Assert(!computeContentBounds || !computeErrorIconBounds || !paint); Debug.Assert(!computeErrorIconBounds || !paint || !computeContentBounds); Debug.Assert(cellStyle != null); // If computeContentBounds == TRUE then resultBounds will be the contentBounds. // If computeErrorIconBounds == TRUE then resultBounds will be the error icon bounds. // Else resultBounds will be Rectangle.Empty; Rectangle resultBounds = Rectangle.Empty; if (paint && DataGridViewCell.PaintBorder(paintParts)) { PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); } Rectangle valBounds = cellBounds; Rectangle borderWidths = BorderWidths(advancedBorderStyle); valBounds.Offset(borderWidths.X, borderWidths.Y); valBounds.Width -= borderWidths.Right; valBounds.Height -= borderWidths.Bottom; Rectangle backgroundBounds = valBounds; bool cellSelected = (dataGridViewElementState & DataGridViewElementStates.Selected) != 0; if (DataGridView.ApplyVisualStylesToHeaderCells) { if (cellStyle.Padding != Padding.Empty) { if (DataGridView.RightToLeftInternal) { valBounds.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top); } else { valBounds.Offset(cellStyle.Padding.Left, cellStyle.Padding.Top); } valBounds.Width -= cellStyle.Padding.Horizontal; valBounds.Height -= cellStyle.Padding.Vertical; } if (backgroundBounds.Width > 0 && backgroundBounds.Height > 0) { if (paint && DataGridViewCell.PaintBackground(paintParts)) { // Theming int state = (int)HeaderItemState.Normal; if (DataGridView.SelectionMode == DataGridViewSelectionMode.FullRowSelect || DataGridView.SelectionMode == DataGridViewSelectionMode.RowHeaderSelect) { if (ButtonState != ButtonState.Normal) { Debug.Assert(ButtonState == ButtonState.Pushed); state = (int)HeaderItemState.Pressed; } else if (DataGridView.MouseEnteredCellAddress.Y == rowIndex && DataGridView.MouseEnteredCellAddress.X == -1) { state = (int)HeaderItemState.Hot; } else if (cellSelected) { state = (int)HeaderItemState.Pressed; } } // Flip the column header background using (Bitmap bmFlipXPThemes = new Bitmap(backgroundBounds.Height, backgroundBounds.Width)) { using (Graphics gFlip = Graphics.FromImage(bmFlipXPThemes)) { DataGridViewRowHeaderCellRenderer.DrawHeader(gFlip, new Rectangle(0, 0, backgroundBounds.Height, backgroundBounds.Width), state); bmFlipXPThemes.RotateFlip(DataGridView.RightToLeftInternal ? RotateFlipType.Rotate90FlipNone : RotateFlipType.Rotate270FlipY); graphics.DrawImage(bmFlipXPThemes, backgroundBounds, new Rectangle(0, 0, backgroundBounds.Width, backgroundBounds.Height), GraphicsUnit.Pixel); } } } // update the val bounds Rectangle rectThemeMargins = DataGridViewHeaderCell.GetThemeMargins(graphics); if (DataGridView.RightToLeftInternal) { valBounds.X += rectThemeMargins.Height; } else { valBounds.X += rectThemeMargins.Y; } valBounds.Width -= rectThemeMargins.Y + rectThemeMargins.Height; valBounds.Height -= rectThemeMargins.X + rectThemeMargins.Width; valBounds.Y += rectThemeMargins.X; } } else { // No visual style applied if (valBounds.Width > 0 && valBounds.Height > 0) { SolidBrush br = DataGridView.GetCachedBrush((DataGridViewCell.PaintSelectionBackground(paintParts) && cellSelected) ? cellStyle.SelectionBackColor : cellStyle.BackColor); if (paint && DataGridViewCell.PaintBackground(paintParts) && br.Color.A == 255) { graphics.FillRectangle(br, valBounds); } } if (cellStyle.Padding != Padding.Empty) { if (DataGridView.RightToLeftInternal) { valBounds.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top); } else { valBounds.Offset(cellStyle.Padding.Left, cellStyle.Padding.Top); } valBounds.Width -= cellStyle.Padding.Horizontal; valBounds.Height -= cellStyle.Padding.Vertical; } } Bitmap bmp = null; if (valBounds.Width > 0 && valBounds.Height > 0) { Rectangle errorBounds = valBounds; string formattedString = formattedValue as string; if (!string.IsNullOrEmpty(formattedString)) { // There is text to display if (valBounds.Width >= s_iconsWidth + 2 * RowHeaderIconMarginWidth && valBounds.Height >= s_iconsHeight + 2 * RowHeaderIconMarginHeight) { if (paint && DataGridViewCell.PaintContentBackground(paintParts)) { // There is enough room for the potential glyph which is the first priority if (DataGridView.CurrentCellAddress.Y == rowIndex) { if (DataGridView.VirtualMode) { if (DataGridView.IsCurrentRowDirty && DataGridView.ShowEditingIcon) { bmp = GetPencilBitmap(DataGridView.RightToLeftInternal); } else if (DataGridView.NewRowIndex == rowIndex) { bmp = GetArrowStarBitmap(DataGridView.RightToLeftInternal); } else { bmp = GetArrowBitmap(DataGridView.RightToLeftInternal); } } else { if (DataGridView.IsCurrentCellDirty && DataGridView.ShowEditingIcon) { bmp = GetPencilBitmap(DataGridView.RightToLeftInternal); } else if (DataGridView.NewRowIndex == rowIndex) { bmp = GetArrowStarBitmap(DataGridView.RightToLeftInternal); } else { bmp = GetArrowBitmap(DataGridView.RightToLeftInternal); } } } else if (DataGridView.NewRowIndex == rowIndex) { bmp = DataGridViewRowHeaderCell.StarBitmap; } if (bmp != null) { Color iconColor; if (DataGridView.ApplyVisualStylesToHeaderCells) { iconColor = DataGridViewRowHeaderCellRenderer.VisualStyleRenderer.GetColor(ColorProperty.TextColor); } else { iconColor = cellSelected ? cellStyle.SelectionForeColor : cellStyle.ForeColor; } lock (bmp) { PaintIcon(graphics, bmp, valBounds, iconColor); } } } if (!DataGridView.RightToLeftInternal) { valBounds.X += s_iconsWidth + 2 * RowHeaderIconMarginWidth; } valBounds.Width -= s_iconsWidth + 2 * RowHeaderIconMarginWidth; Debug.Assert(valBounds.Width >= 0); Debug.Assert(valBounds.Height >= 0); } // Second priority is text // Font independent margins valBounds.Offset(HorizontalTextMarginLeft + ContentMarginWidth, VerticalTextMargin); valBounds.Width -= HorizontalTextMarginLeft + 2 * ContentMarginWidth + HorizontalTextMarginRight; valBounds.Height -= 2 * VerticalTextMargin; if (valBounds.Width > 0 && valBounds.Height > 0) { TextFormatFlags flags = DataGridViewUtilities.ComputeTextFormatFlagsForCellStyleAlignment(DataGridView.RightToLeftInternal, cellStyle.Alignment, cellStyle.WrapMode); if (DataGridView.ShowRowErrors && valBounds.Width > s_iconsWidth + 2 * RowHeaderIconMarginWidth) { // Check if the text fits if we remove the room required for the row error icon Size maxBounds = new Size(valBounds.Width - s_iconsWidth - 2 * RowHeaderIconMarginWidth, valBounds.Height); if (DataGridViewCell.TextFitsInBounds(graphics, formattedString, cellStyle.Font, maxBounds, flags)) { // There is enough room for both the text and the row error icon, so use it all. if (DataGridView.RightToLeftInternal) { valBounds.X += s_iconsWidth + 2 * RowHeaderIconMarginWidth; } valBounds.Width -= s_iconsWidth + 2 * RowHeaderIconMarginWidth; } } if (DataGridViewCell.PaintContentForeground(paintParts)) { if (paint) { Color textColor; if (DataGridView.ApplyVisualStylesToHeaderCells) { textColor = DataGridViewRowHeaderCellRenderer.VisualStyleRenderer.GetColor(ColorProperty.TextColor); } else { textColor = cellSelected ? cellStyle.SelectionForeColor : cellStyle.ForeColor; } if ((flags & TextFormatFlags.SingleLine) != 0) { flags |= TextFormatFlags.EndEllipsis; } TextRenderer.DrawText(graphics, formattedString, cellStyle.Font, valBounds, textColor, flags); } else if (computeContentBounds) { resultBounds = DataGridViewUtilities.GetTextBounds(valBounds, formattedString, flags, cellStyle); } } } // Third priority is the row error icon, which may be painted on top of text if (errorBounds.Width >= 3 * RowHeaderIconMarginWidth + 2 * s_iconsWidth) { // There is enough horizontal room for the error icon and the glyph if (paint && DataGridView.ShowRowErrors && DataGridViewCell.PaintErrorIcon(paintParts)) { PaintErrorIcon(graphics, clipBounds, errorBounds, errorText); } else if (computeErrorIconBounds) { if (!string.IsNullOrEmpty(errorText)) { resultBounds = ComputeErrorIconBounds(errorBounds); } } } } else { // There is no text to display if (valBounds.Width >= s_iconsWidth + 2 * RowHeaderIconMarginWidth && valBounds.Height >= s_iconsHeight + 2 * RowHeaderIconMarginHeight) { if (paint && DataGridViewCell.PaintContentBackground(paintParts)) { // There is enough room for the potential icon if (DataGridView.CurrentCellAddress.Y == rowIndex) { if (DataGridView.VirtualMode) { if (DataGridView.IsCurrentRowDirty && DataGridView.ShowEditingIcon) { bmp = GetPencilBitmap(DataGridView.RightToLeftInternal); } else if (DataGridView.NewRowIndex == rowIndex) { bmp = GetArrowStarBitmap(DataGridView.RightToLeftInternal); } else { bmp = GetArrowBitmap(DataGridView.RightToLeftInternal); } } else { if (DataGridView.IsCurrentCellDirty && DataGridView.ShowEditingIcon) { bmp = GetPencilBitmap(DataGridView.RightToLeftInternal); } else if (DataGridView.NewRowIndex == rowIndex) { bmp = GetArrowStarBitmap(DataGridView.RightToLeftInternal); } else { bmp = GetArrowBitmap(DataGridView.RightToLeftInternal); } } } else if (DataGridView.NewRowIndex == rowIndex) { bmp = DataGridViewRowHeaderCell.StarBitmap; } if (bmp != null) { lock (bmp) { Color iconColor; if (DataGridView.ApplyVisualStylesToHeaderCells) { iconColor = DataGridViewRowHeaderCellRenderer.VisualStyleRenderer.GetColor(ColorProperty.TextColor); } else { iconColor = cellSelected ? cellStyle.SelectionForeColor : cellStyle.ForeColor; } PaintIcon(graphics, bmp, valBounds, iconColor); } } } } if (errorBounds.Width >= 3 * RowHeaderIconMarginWidth + 2 * s_iconsWidth) { // There is enough horizontal room for the error icon if (paint && DataGridView.ShowRowErrors && DataGridViewCell.PaintErrorIcon(paintParts)) { PaintErrorIcon(graphics, cellStyle, rowIndex, cellBounds, errorBounds, errorText); } else if (computeErrorIconBounds) { if (!string.IsNullOrEmpty(errorText)) { resultBounds = ComputeErrorIconBounds(errorBounds); } } } } } // else no room for content or error icon, resultBounds = Rectangle.Empty return(resultBounds); }