• [WinForm ADO.NET实现TaskVision][SQL Server 2008][winform datagridview总结][自定义Custom控件]Winform DataGridView各种现有column及自定义column+Winform自定义控件


    前面的博文:WPF+SQL Server 2008 TaskVision Demo小结,写了用WPF和SQL Server 2008实现这个Demo时候遇到的一些有必要说明的地方。如SQL Server的相关设置问题,DataGrid的Binding等...

    毕竟那是WPF,其为我们简化了页面的表示,如提供了DataGrid控件扩展了Winform下的DataGridView控件!

    那么我们用Winform如何实现相同的功能呢?

    下面DebugLZQ来总结下Winform中的DataGridView的使用。

    一般用过datagridview控件的人都知道,该控件提供了6种不同的column,vs08、vs10、vs12都是这样,如下:

    DebugLZQ写了一个小例子来展示这些column的使用。

    我在一个Winform页面上添加了一个datagridview控件,并通过编辑器,添加了7个column,这些column包含了以上所有的6中DataGridViewColumn。如下:

    我们来看下用法:

            private void Form3_Load(object sender, EventArgs e)
            {
                LoadData();
                dataGridView1.AutoGenerateColumns = false;
            }
            /// <summary>
            //1.DataGridView各种Column使用
            //可添加CellContentClick事件根据列进行相应的处理
            /// </summary>
            private void LoadData()
            {
                //演示DataGridView各种Colum使用
                dataGridView1.AutoGenerateColumns = false;
                DataTable dataTable = SQLHelper.GetDataTable("select * from tb_TaskInfo");
                //dataGridView1.DataSource = dataTable;
                dataGridView1.Rows.Add(dataTable.Rows.Count);
                for (int i = 0; i < dataTable.Rows.Count; i++)
                {                
                    dataGridView1.Rows[i].Cells["Id"].Value = dataTable.Rows[i].ItemArray[0].ToString();//DataGridViewTextBoxColumn
                    dataGridView1.Rows[i].Cells["PLevel"].Value = Image.FromFile(dataTable.Rows[i].ItemArray[9].ToString());//DataGridViewImageColumn
                    dataGridView1.Rows[i].Cells["Distribution"].Value = dataTable.Rows[i].ItemArray[2].ToString();//DataGridViewLinkColumn
                    dataGridView1.Rows[i].Cells["Abstract"].Value = dataTable.Rows[i].ItemArray[3].ToString();
                    dataGridView1.Rows[i].Cells["State"].Value = dataTable.Rows[i].ItemArray[4].ToString();//DataGridViewComboBoxColumn
                    if (dataTable.Rows[i].ItemArray[4].ToString() == "Open")
                    {
                        dataGridView1.Rows[i].Cells["State2"].Value = true;//DataGridViewCheckBoxColumn
                    }
                    else
                    {
                        dataGridView1.Rows[i].Cells["State2"].Value = false;
                    }
                    dataGridView1.Rows[i].Cells["Rate"].Value = dataTable.Rows[i].ItemArray[5].ToString() + "%";//DataGridViewButtonColumn
                    
                }
            }

    需要对鼠标点击事件进行处理的话,我们可以添加类似CellContentClick事件,定位具体列、单元格等进行相应的处理。
    其运行效果如下:

    其数据库表数据格式如下:

    上面的运行图只是演示下如何用自带的各种Column,奇丑无比不谈,还没有实现相应的功能,比如说我们最后一列的百分。

    一般情况下,我们可以在使用datagridview自带Column的基础上,通过datagridview的cellpainting事件,来进行处理,实现一些特殊的功能。

    添加dataGridView1的CellPainting事件,事件处理如下:

            //2.有特别需要的地方用CellPainting事件进行重绘
            private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
            {
                if (e.RowIndex >= 0 && e.ColumnIndex == 6)
                {
                    int rate = Convert.ToInt32(dataGridView1.Rows[e.RowIndex].Cells["Rate"].Value.ToString().Substring(0, dataGridView1.Rows[e.RowIndex].Cells["Rate"].Value.ToString().Length - 1));
    
                    Rectangle newRect = new Rectangle(e.CellBounds.X, e.CellBounds.Y, rate,
                        e.CellBounds.Height);
    
                    using (Brush gridBrush = new SolidBrush(dataGridView1.GridColor), backColorBrush = new SolidBrush(e.CellStyle.BackColor))
                    {
                        using (Pen gridLinePen = new Pen(gridBrush, 2))
                        {
                            // Erase the cell.
                            e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
    
                            //划线
                            Point p1 = new Point(e.CellBounds.Left + e.CellBounds.Width, e.CellBounds.Top);
                            Point p2 = new Point(e.CellBounds.Left + e.CellBounds.Width, e.CellBounds.Top + e.CellBounds.Height);
                            Point p3 = new Point(e.CellBounds.Left, e.CellBounds.Top + e.CellBounds.Height);
                            Point[] ps = new Point[] { p1, p2, p3 };
                            e.Graphics.DrawLines(gridLinePen, ps);
    
                            //画多边形
                            e.Graphics.DrawRectangle(Pens.LightBlue, newRect);
                            e.Graphics.FillRectangle(Brushes.LightBlue, newRect);
                            //画字符串
                            e.Graphics.DrawString(rate.ToString() + "%", e.CellStyle.Font, Brushes.Crimson,
                                e.CellBounds.Left + 20, e.CellBounds.Top + 5, StringFormat.GenericDefault);
                            e.Handled = true;
                        }
                    }
                }
            }

    效果如下:

    一般的用法就是这样。

    界面丑?                                                                             

    我们来美化下:

    主要的美化方法是:

      去掉自动生成的第一列 :RowHeadersVisible=false;  

      隔行变色:设置以下2个属性  

        dataGridViewX1.RowsDefaultCellStyle.BackColor ;

        dataGridViewX1.AlternatingRowsDefaultCellStyle.BackColor ;

      设置行选中:SelectionMode=FullRowSelect;  

      禁止改变列高:AllowUserToResizeRows = False

      鼠标经过改变形状及颜色:后面有代码。

    都是一些datagridview的小细节,无伤大雅,重点不在这。内在的东西才最重要!

    还是有点丑?                                                                         

    再来美化下,加个皮肤吧----这个DebugLZQ千米的博文有介绍。

    效果如下:

    界面这下差不多OK了。是不是有点像WPF搞得?

    貌似有点跑的远了,光盯着界面了。我们来总结下:

    datagridview为我们提供了6种自带的Column,不能满足要求的话,我们可以通过datagridview的CellPainting事件绘制,来实现一些特别的需求。

    当然针对上面的Form2,DebugLZQ只是用了DataGridViewTextBoxColumn+CellPainting来实现的。

    实现过程如下:

    1.定义DataGridView的列,注意这个DataPropertyName:设置显示DataTable中的列名。

    注意设置:dataGridView1.AutoGenerateColumns = false;来禁止datagridView自动为我们添加列。

    2.数据绑定及CellPainting事件处理如下:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace TaskVision_V_1_WinForm
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
    
                imageComboBoxUserControl1.Items.Add(new ImageComboBoxUserControl.ItemEx("Major", Image.FromFile("Images/Major.gif")));
                imageComboBoxUserControl1.Items.Add(new ImageComboBoxUserControl.ItemEx("Medium", Image.FromFile("Images/Medium.gif")));
                imageComboBoxUserControl1.Items.Add(new ImageComboBoxUserControl.ItemEx("Minor", Image.FromFile("Images/Minor.gif")));
            }
    
            private void Form2_Load(object sender, EventArgs e)
            {
                dataGridView1.AutoGenerateColumns = false;
                DataTable dataTable = SQLHelper.GetDataTable("select * from tb_TaskInfo");
                dataGridView1.DataSource = dataTable;
            }
    
            private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
            {
                //第2列改成显示图片
                if (e.RowIndex >= 0 && e.ColumnIndex == 1)
                {
                    if (dataGridView1.Rows[e.RowIndex].Cells["PLevel"].Value == DBNull.Value)
                        return;
                    string imagePath = "Images/" + dataGridView1.Rows[e.RowIndex].Cells["PLevel"].Value + ".gif";
                    if (imagePath == "Images/.gif")
                        return;
                    Image img = Image.FromFile(imagePath);
    
                    Rectangle newRect = new Rectangle(e.CellBounds.X, e.CellBounds.Y, e.CellBounds.Height,
                        e.CellBounds.Height);
    
    
                    using (Brush gridBrush = new SolidBrush(dataGridView1.GridColor), backColorBrush = new SolidBrush(e.CellStyle.BackColor))
                    {
                        using (Pen gridLinePen = new Pen(gridBrush, 2))
                        {
                            // Erase the cell.
                            e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
    
                            //划线
                            Point p1 = new Point(e.CellBounds.Left + e.CellBounds.Width, e.CellBounds.Top);
                            Point p2 = new Point(e.CellBounds.Left + e.CellBounds.Width, e.CellBounds.Top + e.CellBounds.Height);
                            Point p3 = new Point(e.CellBounds.Left, e.CellBounds.Top + e.CellBounds.Height);
                            Point[] ps = new Point[] { p1, p2, p3 };
                            e.Graphics.DrawLines(gridLinePen, ps);
    
                            //画图标
                            e.Graphics.DrawImage(img, newRect);
                            ////画字符串
                            //e.Graphics.DrawString(dataGridView1.Rows[e.RowIndex].Cells["PLevel"].Value.ToString(), e.CellStyle.Font, Brushes.Crimson,
                            //    e.CellBounds.Left + 20, e.CellBounds.Top + 5, StringFormat.GenericDefault);
                            e.Handled = true;
                        }
                    }
                }
                //第6列改成图形百分比
                else if (e.RowIndex >= 0 && e.ColumnIndex == 5)
                {
                    int rate = Convert.ToInt32(dataGridView1.Rows[e.RowIndex].Cells["Rate"].Value);
    
                    Rectangle newRect = new Rectangle(e.CellBounds.X, e.CellBounds.Y, rate,
                        e.CellBounds.Height);
    
                    using (Brush gridBrush = new SolidBrush(dataGridView1.GridColor), backColorBrush = new SolidBrush(e.CellStyle.BackColor))
                    {
                        using (Pen gridLinePen = new Pen(gridBrush, 2))
                        {
                            // Erase the cell.
                            e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
    
                            //划线
                            Point p1 = new Point(e.CellBounds.Left + e.CellBounds.Width, e.CellBounds.Top);
                            Point p2 = new Point(e.CellBounds.Left + e.CellBounds.Width, e.CellBounds.Top + e.CellBounds.Height);
                            Point p3 = new Point(e.CellBounds.Left, e.CellBounds.Top + e.CellBounds.Height);
                            Point[] ps = new Point[] { p1, p2, p3 };
                            e.Graphics.DrawLines(gridLinePen, ps);
    
                            //画多边形
                            e.Graphics.DrawRectangle(Pens.LightBlue, newRect);
                            e.Graphics.FillRectangle(Brushes.LightBlue, newRect);
                            //画字符串
                            e.Graphics.DrawString(rate.ToString() + "%", e.CellStyle.Font, Brushes.Crimson,
                                e.CellBounds.Left + 20, e.CellBounds.Top + 5, StringFormat.GenericDefault);
                            e.Handled = true;
                        }
                    }
                }           
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                //get/set
                imageComboBoxUserControl1.SelectedIndex = 2;
                MessageBox.Show(imageComboBoxUserControl1.SelectedItem.ToString());
            }
            /////////////////////////////////////
            //设置鼠标经过改变颜色              
            Color colorTmp = Color.White; // 用来记录先前的颜色值      
            private void dataGridView1_CellMouseEnter(object sender, DataGridViewCellEventArgs e)
            {
                if (e.RowIndex >= 0)
                {
                    colorTmp = dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor;
                    dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Red;
                }
            }
    
            private void dataGridView1_CellMouseLeave(object sender, DataGridViewCellEventArgs e)
            {
                if (e.RowIndex >= 0)
                {
                    dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = colorTmp;
                }
            }
    
        }
    }

    页面中多了一些代码?是LZ为了模仿WPF的ComboBox自定义的ImageComboBoxUserControl控件,

    该自定义ImageComboBoxUserControl控件,让ComboBox中同时显示图片和文字。

    其源码如下,控件的使用方法见上面的代码。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing.Drawing2D;
    
    namespace TaskVision_V_1_WinForm
    {
        public partial class ImageComboBoxUserControl : ComboBox
        {
            public ImageComboBoxUserControl()
            {
                //InitializeComponent();
                DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
                DropDownStyle = ComboBoxStyle.DropDownList;
                ItemHeight = 30;
                Width = 80;
            }
    
            protected override void OnDrawItem(DrawItemEventArgs e)
            {
                if (Items.Count == 0 || e.Index == -1)
                    return;
                if ((e.State & DrawItemState.Selected) != 0)
                {
                    //渐变画刷
                    LinearGradientBrush brush = new LinearGradientBrush(e.Bounds, Color.FromArgb(255, 251, 237),
                                                     Color.FromArgb(255, 236, 181), LinearGradientMode.Vertical);
                    //填充区域
                    Rectangle borderRect = new Rectangle(3, e.Bounds.Y, e.Bounds.Width - 5, e.Bounds.Height - 2);
    
                    e.Graphics.FillRectangle(brush, borderRect);
    
                    //画边框
                    Pen pen = new Pen(Color.FromArgb(229, 195, 101));
                    e.Graphics.DrawRectangle(pen, borderRect);
                }
                else
                {
                    SolidBrush brush = new SolidBrush(Color.FromArgb(255, 255, 255));
                    e.Graphics.FillRectangle(brush, e.Bounds);
                }
    
                //获得项图片,绘制图片
                ItemEx item = (ItemEx)Items[e.Index];
                Image img = item.Image;
    
                //图片绘制的区域
                Rectangle imgRect = new Rectangle(6, e.Bounds.Y + 3, 30, 30);
                e.Graphics.DrawImage(img, imgRect);
    
                //文本内容显示区域
                Rectangle textRect =
                        new Rectangle(imgRect.Right + 2, imgRect.Y, e.Bounds.Width - imgRect.Width, e.Bounds.Height - 2);
    
                //获得项文本内容,绘制文本
                String itemText = Items[e.Index].ToString();
    
                //文本格式垂直居中
                StringFormat strFormat = new StringFormat();
                strFormat.LineAlignment = StringAlignment.Center;            
                e.Graphics.DrawString(itemText, new Font("微软雅黑", 12), Brushes.Black, textRect, strFormat);
                base.OnDrawItem(e);            
            }
    
            public class ItemEx
            {
                public ItemEx(string text, Image img)
                {
                    Text = text;
                    Image = img;
                }
    
                public string Text { get; set; }
                public Image Image { get; set; }
    
                public override string ToString()
                {
                    return Text;
                }
            }
    
        }
    }

    这样就用Winform从技术上重新实现了前面的WPF+SQL Server 2008的TaskVision。
    感受的是Winform datagridview和WPF datagrid的使用,区别,及两种不同的界面驱动编码方式。

     关于:实现Winform自定义控件ImageComboBoxUserControl,也可以参考DebugLZQ前面的一篇博文:在Winform窗体中使用WPF控件(附源码)

     关于:DataGridView控件默认只支持DataGridViewButtonColumn、DataGridViewCheckBoxColumn、DataGridViewComboBoxColumn、DataGridViewImageColumn、DataGridViewLinkColumn和DataGridViewTextBoxColumn六种列类型,如果你想要在DataGridView的列中添加其它的子控件,则需要自己实现DataGridViewColumn和DataGridViewCell。可参考:C# WinForm下DataGridView单选按钮列和支持三种选择状态的复选框列的实现

     另外:直接在datagridview中编辑,批量更新。如下:

    View Code
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.SqlClient;
    
    namespace TaskVision_V_1_WinForm
    {
        public partial class Form4 : Form
        {
            public Form4()
            {
                InitializeComponent();
            }
    
            private DataTable dt = new DataTable();
            private SqlDataAdapter sda = new SqlDataAdapter();
            private Boolean isUpdate = false;
    
            private void Form4_Load(object sender, EventArgs e)
            {
                LoadData();
            }
    
    
            private void LoadData()
            {
                dataGridView1.AutoGenerateColumns = false;
    
                SqlConnection conn = new SqlConnection(@"server=LocalHost;database=TaskVision;Trusted_Connection=SSPI"); 
                SqlCommand cmd = new SqlCommand("select * from tb_TaskInfo ", conn); 
                sda.SelectCommand = cmd; 
                sda.Fill(dt); 
                dataGridView1.DataSource = dt;
            }
    
            private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
            {
                isUpdate = true;            
            }
    
            /// <summary>
            /// 直接在datagridview中进行批量修改
            /// </summary>        
            private void button1_Click(object sender, EventArgs e)
            {
                if (isUpdate)
                {
                    try 
                    { 
                        SqlCommandBuilder SCB = new SqlCommandBuilder(sda); 
                        sda.Update(dt);
                        isUpdate = false;
                    } 
                    catch (System.Exception ex) 
                    {
                        MessageBox.Show(ex.ToString());
                        return;
                    } 
                    MessageBox.Show("更新成功! "); 
                }
                else
                { 
                    MessageBox.Show("没有更新内容! ");
                }
            }
        }
    }
  • 相关阅读:
    vue2 v-model/v-text 中使用过滤器的方法示例
    HTML5游戏开发案例教程合集
    Docker实战案例视频课程
    Java项目框架架构与优化教程
    Linux云计算-虚拟化技术视频教程
    udl
    Chloe官网及基于NFine的后台源码毫无保留开放
    抽象类存在的意义和作用
    Shell 脚本语法
    Github 高级搜索功能
  • 原文地址:https://www.cnblogs.com/DebugLZQ/p/3024344.html
Copyright © 2020-2023  润新知