技術總結:c# 之winform datagridview操做列

datagridview在winform的框架裏面就和html裏面的table同樣。

但不一樣的是,原生的datagridview裏面並無操做列這個概念,默認的列類型 有下拉框、文本、按鈕、圖片、連接這幾類,若是須要其餘的樣式還須要從新寫。html

其實大部分需求都是如圖的效果,固然你使用了別的組件【不是官方自帶】,可能實現如圖的效果很簡單git

下面講講如圖==》操做列 有多個按鈕的不一樣實現方式後端

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 方式二

    使用右鍵菜單==》也可套用點擊行裏面的按鈕顯示菜單。【學會觸類旁通就行】this

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裏面,進入連接在最下面。【其實這種思惟更適合客戶端,網頁和桌面應用仍是有區別的】spa

效果:.net

1.3 方式三

    是我參考網上一些固有樣式,寫出的一個動態的操做列,能夠適合權限管理【按鈕】。推薦使用。固然可能有些小問題,暫時我還沒發現。這種樣式和後端管理的操做列相似。若是按鈕超出列的寬度,請設置合適的該列的寬度。3d

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_MouseClick,FormTest_Load 主要是自定義單元格,dataGridView1_MouseClick是點擊判斷點擊的按鈕區域進而作業務處,須要使用自定義的列DataGridViewActionButtonColumn和自定義的單元格**DataGridViewActionButtonCell。**代碼在FormTest.cs裏面,進入連接在最下面。【其實這種思惟更適合客戶端,網頁和桌面應用仍是有區別的】code

效果:

源代碼:https://gitee.com/ten-ken/csharp-demo-code/tree/master/chao.net

[暫時不對外開放,等過段時間]

本文來源於:宋文超super,專屬平臺有csdn、思否(SegmentFault)、 簡書、 開源中國(oschina),轉載請註明出處。

相關文章
相關標籤/搜索