技术总结:c# 之winform datagridview自定义操作列

datagridview在winform的框架里面就和html里面的table一样。

但不同的是,原生的datagridview里面并没有操作列这个概念,默认的列类型 有下拉框、文本、按钮、图片、链接这几类,如果需要其他的样式还需要重新写。

其实大部分需求都是如图的效果,当然你使用了别的组件【不是官方自带】,可能实现如图的效果很简单

下面讲讲如图==》操作列 有多个按钮的不同实现方式

1.1 方式一

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace chao.net
{
    public partial class FormTest2 : Form
    {
        public FormTest2()
        {
            InitializeComponent();
        }

        private void toolStripLabel1_Click(object sender, EventArgs e)
        {

        }

        private void FormTest2_Load(object sender, EventArgs e)
        {
            this.dataGridView1.AutoGenerateColumns = false;;
            this.dataGridView1.CellMouseClick += dataGridView1_CellMouseClick;
            this.dataGridView1.CellPainting += dataGridView1_CellPainting;
            this.dataGridView1.Rows.Add();
            

        }



        /// <summary>
        ///  单元格重绘
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
            {
                if (this.dataGridView1.Columns[e.ColumnIndex].HeaderText == "操作")
                {
                    StringFormat sf = StringFormat.GenericDefault.Clone() as StringFormat;//设置重绘入单元格的字体样式
                    sf.FormatFlags = StringFormatFlags.DisplayFormatControl;
                    sf.Alignment = StringAlignment.Center;
                    sf.LineAlignment = StringAlignment.Center;
                    sf.Trimming = StringTrimming.EllipsisCharacter;

                    //e.PaintContent

                    e.PaintBackground(e.CellBounds, false);//重绘边框

                    //设置要写入字体的大小
                    System.Drawing.Font myFont = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                    //myFon

                    SizeF sizeDel = e.Graphics.MeasureString("删除", myFont);

                    SizeF sizeMod = e.Graphics.MeasureString("修改", myFont);
                    SizeF sizeLook = e.Graphics.MeasureString("查看", myFont);

                    float fDel = sizeDel.Width / (sizeDel.Width + sizeMod.Width + sizeLook.Width); //
                    float fMod = sizeMod.Width / (sizeDel.Width + sizeMod.Width + sizeLook.Width);
                    float fLook = sizeLook.Width / (sizeDel.Width + sizeMod.Width + sizeLook.Width);

                    //设置每个“按钮的边界”
                    RectangleF rectDel = new RectangleF(e.CellBounds.Left, e.CellBounds.Top, e.CellBounds.Width * fDel, e.CellBounds.Height);

                    RectangleF rectMod = new RectangleF(rectDel.Right, e.CellBounds.Top, e.CellBounds.Width * fMod, e.CellBounds.Height);

                    RectangleF rectLook = new RectangleF(rectMod.Right, e.CellBounds.Top, e.CellBounds.Width * fLook, e.CellBounds.Height);

                    e.Graphics.DrawString("删除", myFont, Brushes.Black, rectDel, sf); //绘制“按钮”
                    e.Graphics.DrawString("修改", myFont, Brushes.Black, rectMod, sf);
                    e.Graphics.DrawString("查看", myFont, Brushes.Black, rectLook, sf);

                    e.Handled = true;
                }
            }

        }


        /// <summary>
        /// 鼠标点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
            {
                Point curPosition = e.Location;//当前鼠标在当前单元格中的坐标
                if (this.dataGridView1.Columns[e.ColumnIndex].HeaderText == "操作")
                {
                    //this.dataGridView1.Columns[e.ColumnIndex].Add

                    Graphics g = this.dataGridView1.CreateGraphics();
                    System.Drawing.Font myFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                    SizeF sizeDel = g.MeasureString("删除", myFont);
                    SizeF sizeMod = g.MeasureString("修改", myFont);
                    SizeF sizeLook = g.MeasureString("查看", myFont);
                    float fDel = sizeDel.Width / (sizeDel.Width + sizeMod.Width + sizeLook.Width);
                    float fMod = sizeMod.Width / (sizeDel.Width + sizeMod.Width + sizeLook.Width);
                    float fLook = sizeLook.Width / (sizeDel.Width + sizeMod.Width + sizeLook.Width);

                    Rectangle rectTotal = new Rectangle(0, 0, this.dataGridView1.Columns[e.ColumnIndex].Width, this.dataGridView1.Rows[e.RowIndex].Height);
                    RectangleF rectDel = new RectangleF(rectTotal.Left, rectTotal.Top, rectTotal.Width * fDel, rectTotal.Height);
                    RectangleF rectMod = new RectangleF(rectDel.Right, rectTotal.Top, rectTotal.Width * fMod, rectTotal.Height);
                    RectangleF rectLook = new RectangleF(rectMod.Right, rectTotal.Top, rectTotal.Width * fLook, rectTotal.Height);
                    //判断当前鼠标在哪个“按钮”范围内
                    if (rectDel.Contains(curPosition))//删除
                        MessageBox.Show("点击删除按钮");
                    else if (rectMod.Contains(curPosition))//修改
                        MessageBox.Show("点击修改按钮");
                    else if (rectLook.Contains(curPosition))//查看
                        MessageBox.Show("点击查看按钮");
                }
            }

        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }
    }
}

主要方法是:dataGridView1_CellPainting  就是重新绘制单元格。代码在FormTest2.cs里面,进入链接在最下面。

效果:

1.2 方式二

    使用右键菜单==》也可套用点击行里面的按钮显示菜单。【学会举一反三就行】

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace chao.net
{
    public partial class FormTest3 : Form
    {
        public FormTest3()
        {
            InitializeComponent();
        }

        private void FormTest3_Load(object sender, EventArgs e)
        {
            this.dataGridView1.AutoGenerateColumns = false; ;
            this.dataGridView1.MouseClick += dataGridView1_MouseClick;
            this.dataGridView1.Rows.Add();
        }



        /// <summary>
        /// stripItem0点击事件-删除选中行
        /// </summary>
        private void stripItems0_Click(object sender, EventArgs e)
        {
            MessageBox.Show("-删除选中行--");
        }

        private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
        {
            ContextMenuStrip strip = new ContextMenuStrip();
            strip.ShowImageMargin = false;//设置右击菜单属性
            strip.Items.Add("删除选定行");
            strip.Items.Add("添加行");

            strip.Items[0].Click += stripItems0_Click;//弹出菜单第一项点击事件
            strip.Items[1].Click += stripItems1_Click;//弹出菜单第二项点击事件

            if (e.Button == MouseButtons.Right)//右键点击
            {
                strip.Show(this.dataGridView1, e.Location);//弹出菜单
            }
        }

        /// <summary>
        /// 弹出菜单第二项点击事件
        /// </summary>
        private void stripItems1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("-添加行-");
        }

    }
}

解释:主要方法是:dataGridView1_MouseClick,这边判断是否右键点击【操作请在datagridview里面右键点击】。代码在FormTest3.cs里面,进入链接在最下面。【其实这种思维更适合客户端,网页和桌面应用还是有区别的】

效果:

1.3 方式三

    是我参考网上一些固有样式,写出的一个动态的操作列,可以适合权限管理【按钮】。推荐使用。当然可能有些小问题,暂时我还没发现。这种样式和后端管理的操作列类似。如果按钮超出列的宽度,请设置合适的该列的宽度。


using chao.net.UIL;
using chao.net.UIL.UserControls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;

using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace chao.net
{
    public partial class FormTest : Form
    {

  

       
        public FormTest()
        {
            InitializeComponent();
        }

        private void FormTest_Load(object sender, EventArgs e)
        {
       
            this.dataGridView1.AutoGenerateColumns = false;


            DataGridViewActionButtonColumn dataGridViewColumn = new DataGridViewActionButtonColumn();
            dataGridViewColumn.Width = 240;
            dataGridViewColumn.HeaderText = "操作列2";
            dataGridViewColumn.Resizable = DataGridViewTriState.False;
            this.dataGridView1.Columns.Add(dataGridViewColumn);

/*
            DataGridViewDetailButtonColumn buttonColumn = new DataGridViewDetailButtonColumn();
            buttonColumn.HeaderText = "操作列3";
            this.dataGridView1.Columns.Add(buttonColumn);*/

            this.dataGridView1.Rows.Add();
           /* this.dataGridView1.RowHeadersVisible = true;
            this.dataGridView1.ColumnHeadersVisible = true;*/

        }





        private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {

            if (this.dataGridView1.Columns[e.ColumnIndex].HeaderText == "操作列2")
            {
                DataGridViewActionButtonColumn dataGridViewColumn = (DataGridViewActionButtonColumn)this.dataGridView1.Columns[e.ColumnIndex];

                //DataGridViewActionButtonCell dataGridViewActionButtonCell = (DataGridViewActionButtonCell)dataGridViewColumn.CellTemplate;

                List<ActionButton> buttonList = dataGridViewColumn.ButtonList;

                foreach(ActionButton act in buttonList){
                    if (act.MouseOnButton)//此时鼠标悬浮在上面
                    {
                        Console.WriteLine("点击了:" + act.Name);
                        //MessageBox.Show("点击了:"+act.Name);
                    }
                }
           
            }

        }


    }
}

解释:主要方法是:FormTest_Load dataGridView1_MouseClickFormTest_Load 主要是自定义单元格,dataGridView1_MouseClick是点击判断点击的按钮区域进而做业务处,需要使用自定义的列DataGridViewActionButtonColumn和自定义的单元格DataGridViewActionButtonCell。代码在FormTest.cs里面,进入链接在最下面。【其实这种思维更适合客户端,网页和桌面应用还是有区别的】

效果:

源代码:csharp-demo-code: c#实例代码 - Gitee.com

[暂时不对外开放,等过段时间]

  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员ken

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值