DataGridViewRowPainting

using System;
using System.Drawing;
using System.Windows.Forms;

class DataGridViewRowPainting : Form
{
    private DataGridView dataGridView1 = new DataGridView();
    private Int32 oldRowIndex = 0;
    private const Int32 CUSTOM_CONTENT_HEIGHT = 30;

    [STAThreadAttribute()]
    public static void Main()
    {
        Application.Run(new DataGridViewRowPainting());
    }

    public DataGridViewRowPainting()
    {
        this.dataGridView1.Dock = DockStyle.Fill;
        this.Controls.Add(this.dataGridView1);
        this.Load += new EventHandler(DataGridViewRowPainting_Load);
        this.Text = "DataGridView row painting demo";
    }

    void DataGridViewRowPainting_Load(object sender, EventArgs e)
    {
        // Set a cell padding to provide space for the top of the focus
        // rectangle and for the content that spans multiple columns.
        Padding newPadding = new Padding(0, 1, 0, CUSTOM_CONTENT_HEIGHT);
        this.dataGridView1.RowTemplate.DefaultCellStyle.Padding = newPadding;

        // Set the selection background color to transparent so
        // the cell won't paint over the custom selection background.
        this.dataGridView1.RowTemplate.DefaultCellStyle.SelectionBackColor =
            Color.Transparent;

        // Set the row height to accommodate the content that
        // spans multiple columns.
        this.dataGridView1.RowTemplate.Height += CUSTOM_CONTENT_HEIGHT;

        // Initialize other DataGridView properties.
        this.dataGridView1.AllowUserToAddRows = false;
        this.dataGridView1.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2;
        this.dataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.None;
        this.dataGridView1.SelectionMode =
            DataGridViewSelectionMode.FullRowSelect;

        // Set the column header names.
        this.dataGridView1.ColumnCount = 4;
        this.dataGridView1.Columns[0].Name = "Recipe";
        this.dataGridView1.Columns[0].SortMode =
            DataGridViewColumnSortMode.NotSortable;
        this.dataGridView1.Columns[1].Name = "Category";
        this.dataGridView1.Columns[2].Name = "Main Ingredients";
        this.dataGridView1.Columns[3].Name = "Rating";

        // Hide the column that contains the content that spans
        // multiple columns.
        this.dataGridView1.Columns[2].Visible = false;

        // Populate the rows of the DataGridView.
        string[] row1 = new string[]{"Meatloaf", "Main Dish",
            "1 lb. lean ground beef, 1/2 cup bread crumbs, " +
            "1/4 cup ketchup, 1/3 tsp onion powder, 1 clove of garlic, " +
            "1/2 pack onion soup mix, dash of your favorite BBQ Sauce",
            "****"};
        string[] row2 = new string[]{"Key Lime Pie", "Dessert",
            "lime juice, whipped cream, eggs, evaporated milk", "****"};
        string[] row3 = new string[]{"Orange-Salsa Pork Chops",
            "Main Dish", "pork chops, salsa, orange juice, pineapple", "****"};
        string[] row4 = new string[]{"Black Bean and Rice Salad",
            "Salad", "black beans, brown rice", "****"};
        string[] row5 = new string[]{"Chocolate Cheesecake",
            "Dessert", "cream cheese, unsweetened chocolate", "***"};
        string[] row6 = new string[]{"Black Bean Dip", "Appetizer",
            "black beans, sour cream, salsa, chips", "***"};
        object[] rows = new object[] { row1, row2, row3, row4, row5, row6 };
        foreach (string[] rowArray in rows)
        {
            this.dataGridView1.Rows.Add(rowArray);
        }

        // Adjust the row heights to accommodate the normal cell content.
        this.dataGridView1.AutoResizeRows(DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders);

        // Attach handlers to DataGridView events.
        this.dataGridView1.ColumnWidthChanged += new
            DataGridViewColumnEventHandler(dataGridView1_ColumnWidthChanged);
        this.dataGridView1.RowPrePaint += new
            DataGridViewRowPrePaintEventHandler(dataGridView1_RowPrePaint);
        this.dataGridView1.RowPostPaint += new
            DataGridViewRowPostPaintEventHandler(dataGridView1_RowPostPaint);
        this.dataGridView1.CurrentCellChanged += new
            EventHandler(dataGridView1_CurrentCellChanged);
        this.dataGridView1.RowHeightChanged += new
            DataGridViewRowEventHandler(dataGridView1_RowHeightChanged);
    }

    // Forces the control to repaint itself when the user
    // manually changes the width of a column.
    void dataGridView1_ColumnWidthChanged(object sender,
        DataGridViewColumnEventArgs e)
    {
        this.dataGridView1.Invalidate();
    }

    // Forces the row to repaint itself when the user changes the
    // current cell. This is necessary to refresh the focus rectangle.
    void dataGridView1_CurrentCellChanged(object sender, EventArgs e)
    {
        if (oldRowIndex != -1)
        {
            this.dataGridView1.InvalidateRow(oldRowIndex);
        }
        oldRowIndex = this.dataGridView1.CurrentCellAddress.Y;
    }

    // Paints the custom selection background for selected rows.
    void dataGridView1_RowPrePaint(object sender,
            DataGridViewRowPrePaintEventArgs e)
    {
        // Do not automatically paint the focus rectangle.
        e.PaintParts &= ~DataGridViewPaintParts.Focus;

        // Determine whether the cell should be painted
        // with the custom selection background.
        if ((e.State & DataGridViewElementStates.Selected) ==
                    DataGridViewElementStates.Selected)
        {
            // Calculate the bounds of the row.
            Rectangle rowBounds = new Rectangle(
                this.dataGridView1.RowHeadersWidth, e.RowBounds.Top,
                this.dataGridView1.Columns.GetColumnsWidth(
                    DataGridViewElementStates.Visible) -
                this.dataGridView1.HorizontalScrollingOffset + 1,
                e.RowBounds.Height);

            // Paint the custom selection background.
            using (Brush backbrush =
                new System.Drawing.Drawing2D.LinearGradientBrush(rowBounds,
                    this.dataGridView1.DefaultCellStyle.SelectionBackColor,
                    e.InheritedRowStyle.ForeColor,
                    System.Drawing.Drawing2D.LinearGradientMode.Horizontal))
            {
                e.Graphics.FillRectangle(backbrush, rowBounds);
            }
        }
    }

    // Paints the content that spans multiple columns and the focus rectangle.
    void dataGridView1_RowPostPaint(object sender,
        DataGridViewRowPostPaintEventArgs e)
    {
        // Calculate the bounds of the row.
        Rectangle rowBounds = new Rectangle(
            this.dataGridView1.RowHeadersWidth, e.RowBounds.Top,
            this.dataGridView1.Columns.GetColumnsWidth(
                DataGridViewElementStates.Visible) -
            this.dataGridView1.HorizontalScrollingOffset + 1,
            e.RowBounds.Height);

        SolidBrush forebrush = null;
        try
        {
            // Determine the foreground color.
            if ((e.State & DataGridViewElementStates.Selected) ==
                DataGridViewElementStates.Selected)
            {
                forebrush = new SolidBrush(e.InheritedRowStyle.SelectionForeColor);
            }
            else
            {
                forebrush = new SolidBrush(e.InheritedRowStyle.ForeColor);
            }

            // Get the content that spans multiple columns.
            object recipe =
                this.dataGridView1.Rows.SharedRow(e.RowIndex).Cells[2].Value;

            if (recipe != null)
            {
                String text = recipe.ToString();

                // Calculate the bounds for the content that spans multiple
                // columns, adjusting for the horizontal scrolling position
                // and the current row height, and displaying only whole
                // lines of text.
                Rectangle textArea = rowBounds;
                textArea.X -= this.dataGridView1.HorizontalScrollingOffset;
                textArea.Width += this.dataGridView1.HorizontalScrollingOffset;
                textArea.Y += rowBounds.Height - e.InheritedRowStyle.Padding.Bottom;
                textArea.Height -= rowBounds.Height -
                    e.InheritedRowStyle.Padding.Bottom;
                textArea.Height = (textArea.Height / e.InheritedRowStyle.Font.Height) *
                    e.InheritedRowStyle.Font.Height;

                // Calculate the portion of the text area that needs painting.
                RectangleF clip = textArea;
                clip.Width -= this.dataGridView1.RowHeadersWidth + 1 - clip.X;
                clip.X = this.dataGridView1.RowHeadersWidth + 1;
                RectangleF oldClip = e.Graphics.ClipBounds;

                e.Graphics.SetClip(clip);

                // Draw the content that spans multiple columns.
                e.Graphics.DrawString(
                    text, e.InheritedRowStyle.Font, forebrush, textArea);

                e.Graphics.SetClip(oldClip);
            }
        }
        finally
        {
            forebrush.Dispose();
        }

        if (this.dataGridView1.CurrentCellAddress.Y == e.RowIndex)
        {
            // Paint the focus rectangle.
            e.DrawFocus(rowBounds, true);
        }
    }

    // Adjusts the padding when the user changes the row height so that
    // the normal cell content is fully displayed and any extra
    // height is used for the content that spans multiple columns.
    void dataGridView1_RowHeightChanged(object sender,
        DataGridViewRowEventArgs e)
    {
        // Calculate the new height of the normal cell content.
        Int32 preferredNormalContentHeight =
            e.Row.GetPreferredHeight(e.Row.Index,
            DataGridViewAutoSizeRowMode.AllCellsExceptHeader, true) -
            e.Row.DefaultCellStyle.Padding.Bottom;

        // Specify a new padding.
        Padding newPadding = e.Row.DefaultCellStyle.Padding;
        newPadding.Bottom = e.Row.Height - preferredNormalContentHeight;
        e.Row.DefaultCellStyle.Padding = newPadding;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值