一.DatagridView 导出数据到Excel                                 

有两种方法:一种是直接利用I/O读写去生成非标准格式的xls文件,速度很快。另外种就是直接使用EXCEL的COM组件实现,需要在项目中引用EXCEL的COM组件。

代码

(1)利用I/O。

 

 1 private void button4_Click(object sender, EventArgs e)
 2         {
 3 
 4             //利用流导出Exce
 5              saveFileDialog.Filter = "Execl files (*.xls)|*.xls";
 6             saveFileDialog.FileName = "mydata";
 7 
 8             saveFileDialog.FilterIndex = 0;
 9 
10             saveFileDialog.RestoreDirectory = true;
11 
12             saveFileDialog.CreatePrompt = true;
13 
14             saveFileDialog.Title = "Export Excel File To";
15             saveFileDialog.ShowDialog();
16             Stream myStream;
17 
18             try
19             {
20                 myStream = saveFileDialog.OpenFile();
21             }
22             catch
23             {
24                 return;
25             }
26 
27             //StreamWriter sw = new StreamWriter(myStream, System.Text.Encoding.GetEncoding("gb2312"));
28              StreamWriter sw = new StreamWriter(myStream, System.Text.Encoding.GetEncoding(-0));
29             string str = "";
30             try
31             {
32                 //写标题
33                  for (int i = 0; i < this.DataGridView1.ColumnCount; i++)
34                 {
35                     if (i > 0)
36                     {
37                         str += "\t";
38                     }
39                     str += DataGridView1.Columns[i].HeaderText;
40 
41                 }
42                 sw.WriteLine(str);
43                 //写内容
44  
45                 for (int j = 0; j < DataGridView1.Rows.Count; j++)
46                 {
47                     string tempStr = "";
48 
49                     for (int k = 0; k < DataGridView1.Columns.Count; k++)
50                     {
51                         if (k > 0)
52                         {
53                             tempStr += "\t";
54                         }
55 
56                         tempStr += DataGridView1.Rows[j].Cells[k].Value.ToString();
57 
58                     }
59                     sw.WriteLine(tempStr);
60 
61                 }
62                 sw.Close();
63                 myStream.Close();
64 
65             }
66 
67             catch (Exception ex)
68             {
69                 MessageBox.Show(ex.ToString());
70             }
71 
72             finally
73             {
74                 sw.Close();
75                 myStream.Close();
76             }
77             //System.Diagnostics.Stopwatch swT = new System.Diagnostics.Stopwatch();
78             //swT.Start();
79             //long ts1 = swT.ElapsedMilliseconds;
80             //MessageBox.Show(ts1.ToString() + "\n");
81          }

 

 

(2).利用组件。 

首先添加Excel引用

 

实现代码

       

 

 1  public static void DataGridViewToExcel(string fileName, DataGridView myDGV)
 2         {
 3             string saveFileName = "";
 4             //bool fileSaved = false;
 5              SaveFileDialog saveDialog = new SaveFileDialog();
 6             saveDialog.DefaultExt = "xls";
 7             saveDialog.Filter = "Excel文件|*.xls";
 8             saveDialog.FileName = fileName;
 9             saveDialog.ShowDialog();
10             saveFileName = saveDialog.FileName;
11             if (saveFileName.IndexOf(":"< 0return//被点了取消 
12              Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
13             if (xlApp == null)
14             {
15                 MessageBox.Show("无法创建Excel对象,可能您的机子未安装Excel");
16                 return;
17             }
18 
19             Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks;
20             Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
21             Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1];//取得sheet1 
22 
23             //写入标题
24              for (int i = 0; i < myDGV.ColumnCount; i++)
25             {
26                 worksheet.Cells[1, i + 1= myDGV.Columns[i].HeaderText;
27             }
28             //写入数值
29              for (int r = 0; r < myDGV.Rows.Count; r++)
30             {
31                 for (int i = 0; i < myDGV.ColumnCount; i++)
32                 {
33                     worksheet.Cells[r + 2, i + 1= myDGV.Rows[r].Cells[i].Value;
34                 }
35                 System.Windows.Forms.Application.DoEvents();
36             }
37             worksheet.Columns.EntireColumn.AutoFit();//列宽自适应
38             //if (Microsoft.Office.Interop.cmbxType.Text != "Notification")
39             //{
40             //    Excel.Range rg = worksheet.get_Range(worksheet.Cells[2, 2], worksheet.Cells[ds.Tables[0].Rows.Count + 1, 2]);
41             //    rg.NumberFormat = "00000000";
42             //}
43  
44             if (saveFileName != "")
45             {
46                 try
47                 {
48                     workbook.Saved = true;
49                     workbook.SaveCopyAs(saveFileName);
50                     //fileSaved = true;
51                  }
52                 catch (Exception ex)
53                 {
54                     //fileSaved = false;
55                     MessageBox.Show("导出文件时出错,文件可能正被打开!\n" + ex.Message);
56                 }
57 
58             }
59             //else
60             //{
61             //    fileSaved = false;
62             //}
63             xlApp.Quit();
64             GC.Collect();//强行销毁 
65             // if (fileSaved && System.IO.File.Exists(saveFileName)) System.Diagnostics.Process.Start(saveFileName); //打开EXCEL
66             MessageBox.Show("导出成功""提示", MessageBoxButtons.OK);
67         }

 

 

以上两种方法都能实现Excel的导出,根据验证第一种方法的导出效率要比第二种要高很多,至于选择哪种导出方式以及性能的具体对比还需要读者详细的去衡量。

 

 

 

二.显示密码列                                                            

 

DataGridView.CellFormatting事件

 

在单元格的内容需要设置格式以便于显示时发生。

命名空间:System.Windows.Forms

程序集:System.Windows.Forms(在 system.windows.forms.dll 中)

如:

 

代码
/// <summary>

/// 单元格显示格式事件

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void dataGridView1_CellFormatting(object sender, 

DataGridViewCellFormattingEventArgs e)

{

    
// 把第4列显示*号,*号的个数和实际数据的长度相同

    
if (e.ColumnIndex == 3)

    {

       
if (e.Value != null && e.Value.ToString().Length > 0)

       {

          e.Value 
= new string('*',e.Value.ToString().Length);

        }

     }

 }

 

DataGridView.EditingControlShowing 事件在显示用于编辑单元格的控件时发生。

命名空间: System.Windows.Forms

程序集: System.Windows.Forms(在 system.windows.forms.dll 中)

 

 1 /// <summary>
 2 
 3 /// 编辑单元格控件事件
 4 
 5 /// </summary>
 6 
 7 /// <param name="sender"></param>
 8 
 9 /// <param name="e"></param>
10 
11 private void dataGridView1_EditingControlShowing(object sender, 
12 
13 DataGridViewEditingControlShowingEventArgs e)
14 
15 {
16 
17     // 编辑第4列时,把第4列显示为*号
18 
19     TextBox t = e.Control as TextBox;
20 
21     if (t != null)
22 
23     {
24 
25        if (this.dataGridView1.CurrentCell.ColumnIndex == 3)
26 
27            t.PasswordChar = '*';
28 
29        else
30 
31               t.PasswordChar = new char();
32 
33         }
34 
35     }
36 

 

 

三.WinForm最简单两GridView同步滚动                                        

 

DataGridView. Scroll网格水平滚动或垂直滚动引发的事件。

如何让两个DataGridView保持同步滚动?

一个最简单方法: 不过大数据量时界面会闪。

       

代码
 private void DataGridView1_Scroll(object sender, ScrollEventArgs e)
 {
    dataGridView2.FirstDisplayedScrollingRowIndex 
=DataGridView1.FirstDisplayedScrollingRowIndex;

    dataGridView2.HorizontalScrollingOffset 
=DataGridView1.HorizontalScrollingOffset;

 }

 
private void dataGridView2_Scroll(object sender, ScrollEventArgs e)
 {
    DataGridView1.FirstDisplayedScrollingRowIndex 
=dataGridView2.FirstDisplayedScrollingRowIndex;

    DataGridView1.HorizontalScrollingOffset 
=dataGridView2.HorizontalScrollingOffset;

 }

 

 

四.DataGridView添加任何控件                                               

 

 

代码
void dataGridView2_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            
if (e.Control is DataGridViewTextBoxEditingControl)
            {
                TextBox textbox 
= (TextBox)e.Control;
                
// Panel p = (Panel)textbox.Parent;  //找到当前的父控件,其实就是一个Panel,你将此Panel中的控件清空,然后你就可以在Panel中加入任何控件并随意布局了
                Panel p = (Panel)e.Control.Parent;
                p.Controls.Clear();
               
                btn.Width 
= 38;
                btn.Text 
= textbox.Text;
                btn.Click
+=new EventHandler(btn_Click);
                p.Controls.Add(btn);
            }

        }

 

利用容器(panel)添加控件。

五、DataGridView 单元格验证

 

比如只允许输入数字

要求:验证错误后焦点不离开。

 

有两种方法:

DataGridView.EditingControlShowing 事件和DataGridView.CellValidating 事件。

(1) DataGridView.EditingControlShowing 事件。

显示用于编辑单元格的控件时发生,命名空间: System.Windows.Forms

程序集: System.Windows.Forms(在 system.windows.forms.dll 中)。

如:

void dgvCs_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)

        {

            e.CellStyle.BackColor = Color.Aquamarine;//设置编译时的颜色

            control = new TextBox();

            control = (TextBox)e.Control;

            control.KeyPress += new KeyPressEventHandler(txt_KeyPress);//

        } 

然后在txt_KeyPress这里进行验证。

 

 

(2) DataGridView.CellValidating 事件。

在单元格失去输入焦点时发生,并启用内容验证功能。命名空间: System.Windows.Form,程序集: System.Windows.Forms(在 System.Windows

.Forms.dll 中)

备注:

验证不通过时调用e.Cancel = true,终止事件链,单元格将保持编辑状态。

调用dgv_details.CancelEdit();可以使单元格的内容会滚到修改前的值。

使用System.Windows.Forms.SendKeys.Send("^a");将全选单元格的内容。

如: 

void dgv_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)

        {

                decimal tmp = 0.0m;

                if (!decimal.TryParse(e.FormattedValue.ToString(), out tmp))//是否是数字

                {

                    if (e.FormattedValue != null && e.FormattedValue.ToString().Length != 0)

                    {

                       DevComponents.DotNetBar.MessageBoxEx.Show("请输入有效数字!", "提示");

                       e.Cancel = true;

                    }

                }

         }

这两种方法都能验证。第一种方法当按键按下时(即当编译时)就去验证,而第二种方法是当焦点离开单元格编译区域时触发。所以个人感觉第一种方法更优一点。

 

六、指定选中单元格并开始编辑状态

 

实现:

//获得焦点

DataGridView.Focus();

//指定当前单元格

DataGridView.CurrentCell = dgv_details[0, 0]; []中对应参数为列索引(或列标题)、行索引。(注意:不是默认的先行索引)

//开始编辑状态

d DataGridView.BeginEdit(false);false是指对指定行进行编辑。

DataGridView.BeginEdit 方法 尝试将网格置于允许编辑的状态。

 

命名空间: System.Windows.Forms

程序集: System.Windows.Forms(在 System.Windows.Forms.dll 中)

 

七、在拖动列的滚动条时可以将指定的列冻结。

 

this.dataGridView1.Columns["AddToCartButton"].Frozen = true;

说明:中括号([])中指相应列的索引或者相应列的标题

这个知道了后一看就应该明白,无需多加解释。

 

 

八、 DataGridView选择的部分拷贝至剪贴板 。

 

拷贝模式设定

 

DataGridView1.ClipboardCopyMode= DataGridViewClipboardCopyMode.EnableWithoutHeaderText //设置可复制的模式

 

其中DataGridView.ClipboardCopyMode 属性获取或设置一个值,该值指示用户是否可以将单元格的文本值复制到 Clipboard,以及是否包括行标题和列标题文本。

 

命名空间: System.Windows.Forms

程序集: System.Windows.Forms(在 System.Windows.Forms.dll 中)

 

选中部分拷贝

 

Clipboard.SetDataObject(DataGridView1.GetClipboardContent()) //将控件选中的数据置于系统剪贴板中

 

DataGridView粘贴

 

代码

if (DataGridView1.CurrentCell.Value == null)

{

    return;

}

int insertRowIndex = DataGridView1.CurrentCell.RowIndex;

string pasteText=Clipboard.GetText();//从系统剪贴板中获取数据

if(string.IsNullOrEmpty(pasteText))

{

    return;

}

string[] lines=pasteText.Split('\r');//按行分组

bool isHeader=true;

foreach(string line in lines)

{   

    if(isHeader)

    {

        isHeader=false;//当可复制模式中含有标题时的过滤操作

    }

    else

    {

        string[] vals=line.Split('\t');//按tab空格分组

        if (vals.Length - 1 != DataGridView1.ColumnCount)

        {

            throw new ApplicationException("列数错误");

        }

        DataGridViewRow row = DataGridView1.Rows[insertRowIndex];

        row.HeaderCell.Value=vals[0];

        for(int i=0;i<row.Cells.Count-1;i++)

        {

            row.Cells[i].Value=vals[(i+1)];

        }

        insertRowIndex+=1;

    }

}

 

 

九、DatagridView自动编号

 

代码

 private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)

        {

               //自动编号与数据库无关

            Rectangle rectangle = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y

,dataGridView1.RowHeadersWidth - 4,e.RowBounds.Height);

 

            TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(),dataGridView1.

RowHeadersDefaultCellStyle.Font, rectangle,

            dataGridView1.RowHeadersDefaultCellStyle.ForeColor, TextFormatFlags.VerticalCenter | TextFormatFlags.Right);

        }

 

显示行号

 

 

十、 指定单元格属性

 

 

 

  

DataGridViewCell dgcell = new DataGridViewTextBoxCell();//申明单元格类型

 this.dgvCss.Rows[i].Cells[k] = dgcell;

其实很简单,只是很多人不知道有这个属性。但这种方式和带有复选框类型的单元格使用时,一般情况下出错,也给一些人一种错觉以为单元格类型不能这么操作。其实是因为你在申明列的时候先申明的checkbox类型的,而这时他们便有一个默认值(FormattedValue)false,当你重新给他赋值单元格类型时便会出现FormattedValue错误,这时你只需给它一个默认值就可以,如

this.dgvCss.Rows[i].Cells[k].Value = ""; 这样便可解决。

DataGridView的用法很多,后续会继续介绍。

如有不足欢迎大家指出。

Demo  Demo中包含很多例子或有疑问,可eMail:点击此处

如有转载,请注明出处!
斗破苍穹最新章节,布衣官道-elivn小说网 http://www.elivn.com/

作者: 都市小说 发表于 2011-04-08 09:24 原文链接

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架