设为首页 收藏本站
查看: 899|回复: 0

[经验分享] [WinForm ADO.NET实现TaskVision][SQL Server 2008][winform datagridview总结][自定义Custom

[复制链接]

尚未签到

发表于 2015-7-1 07:04:42 | 显示全部楼层 |阅读模式
  前面的博文: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都是这样,如下:
DSC0000.png
  DebugLZQ写了一个小例子来展示这些column的使用。
  我在一个Winform页面上添加了一个datagridview控件,并通过编辑器,添加了7个column,这些column包含了以上所有的6中DataGridViewColumn。如下:
DSC0001.png
  我们来看下用法:



        private void Form3_Load(object sender, EventArgs e)
{
LoadData();
dataGridView1.AutoGenerateColumns = false;
}
///
//1.DataGridView各种Column使用
//可添加CellContentClick事件根据列进行相应的处理
///
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.Cells["Id"].Value = dataTable.Rows.ItemArray[0].ToString();//DataGridViewTextBoxColumn
dataGridView1.Rows.Cells["PLevel"].Value = Image.FromFile(dataTable.Rows.ItemArray[9].ToString());//DataGridViewImageColumn
dataGridView1.Rows.Cells["Distribution"].Value = dataTable.Rows.ItemArray[2].ToString();//DataGridViewLinkColumn
dataGridView1.Rows.Cells["Abstract"].Value = dataTable.Rows.ItemArray[3].ToString();
dataGridView1.Rows.Cells["State"].Value = dataTable.Rows.ItemArray[4].ToString();//DataGridViewComboBoxColumn
if (dataTable.Rows.ItemArray[4].ToString() == "Open")
{
dataGridView1.Rows.Cells["State2"].Value = true;//DataGridViewCheckBoxColumn
                }
else
{
dataGridView1.Rows.Cells["State2"].Value = false;
}
dataGridView1.Rows.Cells["Rate"].Value = dataTable.Rows.ItemArray[5].ToString() + "%";//DataGridViewButtonColumn
               
}
}
  需要对鼠标点击事件进行处理的话,我们可以添加类似CellContentClick事件,定位具体列、单元格等进行相应的处理。
其运行效果如下:
DSC0002.png
  其数据库表数据格式如下:
DSC0003.png
  上面的运行图只是演示下如何用自带的各种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;
}
}
}
}
  效果如下:
DSC0004.png
  一般的用法就是这样。

界面丑?                                                                              
  我们来美化下:
DSC0005.png
  主要的美化方法是:
  去掉自动生成的第一列 :RowHeadersVisible=false;   
  隔行变色:设置以下2个属性  
  dataGridViewX1.RowsDefaultCellStyle.BackColor ;
  dataGridViewX1.AlternatingRowsDefaultCellStyle.BackColor ;
  设置行选中:SelectionMode=FullRowSelect;   
  禁止改变列高:AllowUserToResizeRows = False
  鼠标经过改变形状及颜色:后面有代码。
  都是一些datagridview的小细节,无伤大雅,重点不在这。内在的东西才最重要!

还是有点丑?                                                                          
  再来美化下,加个皮肤吧----这个DebugLZQ千米的博文有介绍。
  效果如下:
DSC0006.png
  界面这下差不多OK了。是不是有点像WPF搞得?
  貌似有点跑的远了,光盯着界面了。我们来总结下:

datagridview为我们提供了6种自带的Column,不能满足要求的话,我们可以通过datagridview的CellPainting事件绘制,来实现一些特别的需求。
  当然针对上面的Form2,DebugLZQ只是用了DataGridViewTextBoxColumn+CellPainting来实现的。
  实现过程如下:
  1.定义DataGridView的列,注意这个DataPropertyName:设置显示DataTable中的列名。
DSC0007.png
  注意设置: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中同时显示图片和文字。
DSC0008.png
  其源码如下,控件的使用方法见上面的代码。



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中编辑,批量更新。如下:


DSC0009.gif DSC00010.gif 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;            
}
///
/// 直接在datagridview中进行批量修改
///         
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("没有更新内容! ");
}
}
}
}
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-82071-1-1.html 上篇帖子: 终于看到了《Data Mining with SQL Server 2005》全书 下篇帖子: 《Microsoft Sql server 2008 Internals》读书笔记--第十一章DBCC Internals(4)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表