1、实现一个用于处理数据库教程数据检索的详细信息的方法。
下面的代码示例实现一个 getdata 方法,该方法对一个 sqldataadapter 组件进行初始化,并使用该组件填充 datatable。
然后,将 datatable 绑定到 bindingsource 组件。请确保将 connectionstring 变量的值设置为与数据库相应的值。
1 private void getdata(string selectcommand) 2 { 3 try 4 { 5 string connectionstring = "integrated security=sspi;persist security info=false;" + "initial catalog=northwind;data source=localhost"; dataadapter = new sqldataadapter(selectcommand, connectionstring); 6 sqlcommandbuilder commandbuilder = new sqlcommandbuilder(dataadapter); 7 datatable table = new datatable(); 8 table.locale = system.globalization.cultureinfo.invariantculture; dataadapter.fill(table); 9 bindingsource1.datasource = table; datagridview1.autoresizecolumns( datagridviewautosizecolumnsmode.allcellsexceptheader); 10 } 11 catch (sqlexception) 12 { messagebox.show("to run this example, replace the value of the " + "connectionstring variable with a connection string that is " + "valid for your system."); 13 } 14 }
2、在窗体的 load 事件处理程序中,将 datagridview 控件绑定到 bindingsource 组件,并调用 getdata 方法从数据库中检索数据
1 private void form1_load(object sender, system.eventargs e) 2 { 3 datagridview1.datasource = bindingsource1; 4 getdata("select * from customers"); 5 }
① 取得或者修改当前单元格的内容 ② 设定单元格只读 ③ 不显示最下面的新行 ④ 判断新增行 ⑤ 行的用户删除操作的自定义 ⑥ 行、列的隐藏和删除 ⑦ 禁止列或者行的resize ⑧ 列宽和行高以及列头的高度和行头的宽度的自动调整 ⑨ 冻结列或行 ⑩ 列顺序的调整 ? 行头列头的单元格 ? 剪切板的操作 ? 单元格的tooltip的设置 ? 右键菜单(contextmenustrip)的设置 ? 单元格的边框、 网格线样式的设定 ? 单元格表示值的设定 ? 用户输入时,单元格输入值的设定 ? 设定新加行的默认值 ① datagridview 取得或者修改当前单元格的内容: go to top 当前单元格指的是 datagridview 焦点所在的单元格,它可以通过 datagridview 对象的 currentcell 属性取得。如果当前单元格不存在的时候,返回nothing(c#是null)
[vb.net] ' 取得当前单元格内容 console.writeline(datagridview1.currentcell.value) ' 取得当前单元格的列 index console.writeline(datagridview1.currentcell.columnindex) ' 取得当前单元格的行 index console.writeline(datagridview1.currentcell.rowindex)
[c#] // 取得当前单元格内容 console.writeline(datagridview1.currentcell.value); // 取得当前单元格的列 index console.writeline(datagridview1.currentcell.columnindex);
// 取得当前单元格的行 index console.writeline(datagridview1.currentcell.rowindex); 另外,使用 datagridview.currentcelladdress 属性(而不是直接访问单元格)来确定单元格所在的行:datagridview.currentcelladdress.y 和列: datagridview.currentcelladdress.x 。这对于避免取消共享行的共享非常有用。 当前的单元格可以通过设定 datagridview 对象的 currentcell 来改变。可以通过 currentcell 来设定 datagridview 的激活单元格。将 currentcell 设为 nothing(null) 可以取消激活的单元格。 [vb.net] ' 设定 (0, 0) 为当前单元格 datagridview1.currentcell = datagridview1(0, 0)
[c#] // 设定 (0, 0) 为当前单元格 datagridview1.currentcell = datagridview1[0, 0]; 在整行选中模式开启时,你也可以通过 currentcell 来设定选定行。
1 /**//// <summary> 2 /// 向下遍历 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void button4_click(object sender, eventargs e) ... 7 { 8 int row = this.datagridview1.currentrow.index + 1; 9 if (row > this.datagridview1.rowcount - 1) 10 row = 0; 11 this.datagridview1.currentcell = this.datagridview1[0,row]; 12 } /** 13 <summary> 14 /// 向上遍历 15 /// </summary> 16 /// <param name="sender"></param> 17 /// <param name="e"></param> 18 private void button5_click(object sender, eventargs e) ... 19 { 20 int row = this.datagridview1.currentrow.index - 1; 21 if (row < 0) 22 row = this.datagridview1.rowcount - 1; this.datagridview1.currentcell = this.datagridview1[0, row]; 23 }
* 注意: this.datagridview 的索引器的参数是: columnindex, rowindex 或是 columnname, rowindex 这与习惯不同。
-------------------------------------------------------------------------------- ② datagridview 设定单元格只读: go to top 1) 使用 readonly 属性 → 如果希望,datagridview 内所有单元格都不可编辑, 那么只要:
[vb.net] ' 设置 datagridview1 为只读 datagridview1.readonly = true
[c#] // 设置 datagridview1 为只读 datagridview1.readonly = true;此时,用户的新增行操作和删除行操作也被屏蔽了。
如果希望,datagridview 内某个单元格不可编辑, 那么只要:
[vb.net] ' 设置 datagridview1 的第2列整列单元格为只读 datagridview1.columns(1).readonly = true ' 设置 datagridview1 的第3行整行单元格为只读 datagridview1.rows(2).readonly = true ' 设置 datagridview1 的[0,0]单元格为只读 datagridview1(0, 0).readonly = true
[c#] // 设置 datagridview1 的第2列整列单元格为只读 datagridview1.columns[1].readonly = true; // 设置 datagridview1 的第3行整行单元格为只读 datagridview1.rows[2].readonly = true; // 设置 datagridview1 的[0,0]单元格为只读 datagridview1[0, 0].readonly = true; 2) 使用 editmode 属性 datagridview.editmode 属性被设置为 datagridvieweditmode.editprogrammatically 时,用户就不能手动编辑单元格的内容了。
但是可以通过程序,调用 datagridview.beginedit 方法,使单元格进入编辑模式进行编辑。
[vb.net] datagridview1.editmode = datagridvieweditmode.editprogrammatically
[c#] datagridview1.editmode = datagridvieweditmode.editprogrammatically;
3) 根据条件设定单元格的不可编辑状态 当一个一个的通过单元格坐标设定单元格 readonly 属性的方法太麻烦的时候,你可以通过 cellbeginedit 事件来取消单元格的编辑。 [vb.net] 'cellbeginedit 事件处理方法
[c#] // cellbeginedit 事件处理方法 private void datagridview1_cellbeginedit(object sender, datagridviewcellcanceleventargs e) { datagridview dgv = (datagridview)sender; //是否可以进行编辑的条件检查 if (dgv.columns[e.columnindex].name == "column1" && !(bool)dgv["column2", e.rowindex].value) { // 取消编辑 e.cancel = true; } } -------------------------------------------------------------------------------- ③ datagridview 不显示最下面的新行: go to top 通常 datagridview 的最下面一行是用户新追加的行(行头显示 * )。如果不想让用户新追加行即不想显示该新行,可以将 datagridview 对象的 allowusertoaddrows 属性设置为 false。 [vb.net] ' 设置用户不能手动给 datagridview1 添加新行 datagridview1.allowusertoaddrows = false [c#] // 设置用户不能手动给 datagridview1 添加新行 datagridview1.allowusertoaddrows = false; 但是,可以通过程序: datagridviewrowcollection.add 为 datagridview 追加新行。 补足: 如果 datagridview 的 datasource 绑定的是 dataview, 还可以通过设置 dataview.allowadd 属性为 false 来达到同样的效果。
-------------------------------------------------------------------------------- ④ datagridview 判断新增行: go to top datagridview的allowusertoaddrows属性为true时也就是允许用户追加新行的场合下,datagridview的最后一行就是新追加的行(*行)。使用 datagridviewrow.isnewrow 属性可以判断哪一行是新追加的行。另外,通过datagridview.newrowindex 可以获取新行的行序列号。在没有新行的时候,newrowindex = -1。 [vb.net] if datagridview1.currentrow.isnewrow then console.writeline("当前行为新追加行。") else console.writeline("当前行不是新追加行。") end if -------------------------------------------------------------------------------- ⑤ datagridview 行的用户删除操作的自定义: go to top 1) 无条件的限制行删除操作。 默认时,datagridview 是允许用户进行行的删除操作的。如果设置 datagridview对象的allowusertodeleterows属性为 false 时, 用户的行删除操作就被禁止了。 [vb.net] ' 禁止datagridview1的行删除操作。 datagridview1.allowusertodeleterows = false [c#] // 禁止datagridview1的行删除操作。 datagridview1.allowusertodeleterows = false; 但是,通过 datagridviewrowcollection.remove 还是可以进行行的删除。 补足: 如果 datagridview 绑定的是 dataview 的话,通过 dataview.allowdelete 也可以控制行的删除。 2) 行删除时的条件判断处理。 用户在删除行的时候,将会引发 datagridview.userdeletingrow 事件。 在这个事件里,可以判断条件并取消删除操作。 [vb.net] ' datagridview1 的 userdeletingrow 事件 private sub datagridview1_userdeletingrow(byval sender as object, _ byval e as datagridviewrowcanceleventargs) _ handles datagridview1.userdeletingrow ' 删除前的用户确认。 if messagebox.show("确认要删除该行数据吗?", "删除确认", _ messageboxbuttons.okcancel, messageboxicon.question) <> _ windows.forms.dialogresult.ok then ' 如果不是 ok,则取消。 e.cancel = true end if end sub [c#] // datagridview1 的 userdeletingrow 事件 private void datagridview1_userdeletingrow( object sender, datagridviewrowcanceleventargs e) { // 删除前的用户确认。 if (messagebox.show("确认要删除该行数据吗?", "删除确认", messageboxbuttons.okcancel, messageboxicon.question) != dialogresult.ok) { // 如果不是 ok,则取消。 e.cancel = true; } } -------------------------------------------------------------------------------- ⑥ datagridview 行、列的隐藏和删除: go to top 1) 行、列的隐藏 [vb.net] ' datagridview1的第一列隐藏 datagridview1.columns(0).visible = false ' datagridview1的第一行隐藏 datagridview1.rows(0).visible = false [c#] // datagridview1的第一列隐藏 datagridview1.columns[0].visible = false; // datagridview1的第一行隐藏 datagridview1.rows[0].visible = false; 2) 行头、列头的隐藏 [vb.net] ' 列头隐藏 datagridview1.columnheadersvisible = false ' 行头隐藏 datagridview1.rowheadersvisible = false [c#] // 列头隐藏 datagridview1.columnheadersvisible = false; // 行头隐藏 datagridview1.rowheadersvisible = false; 3) 行和列的删除 [vb.net] ' 删除名为"column1"的列 datagridview1.columns.remove("column1") ' 删除第一列 datagridview1.columns.removeat(0) ' 删除第一行 datagridview1.rows.removeat(0) [c#] ' 删除名为"column1"的列 datagridview1.columns.remove("column1"); ' 删除第一列 datagridview1.columns.removeat(0); ' 删除第一行 datagridview1.rows.removeat(0); 4) 删除选中行 [vb.net] for each r as datagridviewrow in datagridview1.selectedrows if not r.isnewrow then datagridview1.rows.remove(r) end if next [c#] foreach (datagridviewrow r in datagridview1.selectedrows) { if (!r.isnewrow) { datagridview1.rows.remove(r); } } -------------------------------------------------------------------------------- ⑦ datagridview 禁止列或者行的resize: go to top 1) 禁止所有的列或者行的resize [vb.net] ' 禁止用户改变datagridview1的所有列的列宽 datagridview1.allowusertoresizecolumns = false '禁止用户改变datagridview1の所有行的行高 datagridview1.allowusertoresizerows = false [c#] // 禁止用户改变datagridview1的所有列的列宽 datagridview1.allowusertoresizecolumns = false; //禁止用户改变datagridview1の所有行的行高 datagridview1.allowusertoresizerows = false; 但是可以通过 datagridviewcolumn.width 或者 datagridviewrow.height 属性设定列宽和行高。 2) 禁止指定行或者列的resize [vb.net] ' 禁止用户改变datagridview1的第一列的列宽 datagridview1.columns(0).resizable = datagridviewtristate.false ' 禁止用户改变datagridview1的第一列的行宽 datagridview1.rows(0).resizable = datagridviewtristate.false [c#] // 禁止用户改变datagridview1的第一列的列宽 datagridview1.columns[0].resizable = datagridviewtristate.false; // 禁止用户改变datagridview1的第一列的行宽 datagridview1.rows[0].resizable = datagridviewtristate.false; → 关于 noset 当 resizable 属性设为 datagridviewtristate.notset 时, 实际上会默认以 datagridview 的 allowusertoresizecolumns 和 allowusertoresizerows 的属性值进行设定。比如: datagridview.allowusertoresizecolumns = false 且 resizable 是 noset 设定时,resizable = false 。
判断 resizable 是否是继承设定了 datagridview 的 allowusertoresizecolumns 和 allowusertoresizerows 的属性值, 可以根据 state 属性判断。如果 state 属性含有 resizableset,那么说明没有继承设定。
3) 列宽和行高的最小值的设定 [vb.net] ' 第一列的最小列宽设定为 100 datagridview1.columns(0).minimumwidth = 100 ' 第一行的最小行高设定为 50 datagridview1.rows(0).minimumheight = 50 [c#] // 第一列的最小列宽设定为 100 datagridview1.columns[0].minimumwidth = 100; // 第一行的最小行高设定为 50 datagridview1.rows[0].minimumheight = 50; 4) 禁止用户改变行头的宽度以及列头的高度
[vb.net] ' 禁止用户改变列头的高度 datagridview1.columnheadersheightsizemode = _ datagridviewcolumnheadersheightsizemode.disableresizing ' 禁止用户改变行头的宽度 datagridview1.rowheaderswidthsizemode = _ datagridviewrowheaderswidthsizemode.enableresizing
[c#] // 禁止用户改变列头的高度 datagridview1.columnheadersheightsizemode = datagridviewcolumnheadersheightsizemode.disableresizing; // 禁止用户改变行头的宽度 datagridview1.rowheaderswidthsizemode = datagridviewrowheaderswidthsizemode.enableresizing;
-------------------------------------------------------------------------------- ⑧ datagridview 列宽和行高自动调整的设定: go to top 1) 设定行高和列宽自动调整 [vb.net] ' 设定包括header和所有单元格的列宽自动调整 datagridview1.autosizecolumnsmode = datagridviewautosizecolumnsmode.allcells ' 设定包括header和所有单元格的行高自动调整 datagridview1.autosizerowsmode = datagridviewautosizerowsmode.allcells
[c#] // 设定包括header和所有单元格的列宽自动调整 datagridview1.autosizecolumnsmode = datagridviewautosizecolumnsmode.allcells; // 设定包括header和所有单元格的行高自动调整 datagridview1.autosizerowsmode = datagridviewautosizerowsmode.allcells; autosizecolumnsmode 属性的设定值枚举请参照 msdn 的 datagridviewautosizerowsmode 说明。
2)指定列或行自动调整
[vb.net] ' 第一列自动调整 datagridview1.columns(0).autosizemode = _ datagridviewautosizecolumnmode.displayedcells
[c#] // 第一列自动调整 datagridview1.columns[0].autosizemode = datagridviewautosizecolumnmode.displayedcells; autosizemode 设定为 notset 时, 默认继承的是 datagridview.autosizecolumnsmode 属性。
3) 设定列头的高度和行头的宽度自动调整
[vb.net] ' 设定列头的宽度可以自由调整 datagridview1.columnheadersheightsizemode = _ datagridviewcolumnheadersheightsizemode.autosize ' 设定行头的宽度可以自由调整 datagridview1.rowheaderswidthsizemode = _ datagridviewrowheaderswidthsizemode.autosizetoallheaders
[c#] // 设定列头的宽度可以自由调整 datagridview1.columnheadersheightsizemode = datagridviewcolumnheadersheightsizemode.autosize; // 设定行头的宽度可以自由调整 datagridview1.rowheaderswidthsizemode = datagridviewrowheaderswidthsizemode.autosizetoallheaders;
4) 随时自动调整 a, 临时的,让列宽自动调整,这和指定autosizecolumnsmode属性一样。
[vb.net] ' 让 datagridview1 的所有列宽自动调整一下。 datagridview1.autoresizecolumns(datagridviewautosizecolumnsmode.allcells) ' 让 datagridview1 的第一列的列宽自动调整一下。 datagridview1.autoresizecolumn(0, datagridviewautosizecolumnmode.allcells)
[c#] // 让 datagridview1 的所有列宽自动调整一下。 datagridview1.autoresizecolumns(datagridviewautosizecolumnsmode.allcells); // 让 datagridview1 的第一列的列宽自动调整一下。 datagridview1.autoresizecolumn(0, datagridviewautosizecolumnmode.allcells);上面调用的 autoresizecolumns 和 autoresizecolumn 当指定的是datagridviewautosizecolumnmode.allcells 的时候, 参数可以省略。即: datagridview1.autoresizecolumn(0) 和 datagridview1.autoresizecolumns() b,临时的,让行高自动调整 [vb.net] ' 让 datagridview1 的所有行高自动调整一下。 datagridview1.autoresizerows(datagridviewautosizerowsmode.allcells) ' 让 datagridview1 的第一行的行高自动调整一下。 datagridview1.autoresizerow(0, datagridviewautosizerowmode.allcells) [c#] // 让 datagridview1 的所有行高自动调整一下。 datagridview1.autoresizerows(datagridviewautosizerowsmode.allcells); //让 datagridview1 的第一行的行高自动调整一下。 datagridview1.autoresizerow(0, datagridviewautosizerowmode.allcells);上面调用的 autoresizerows 和 autoresizerow 当指定的是datagridviewautosizerowmode.allcells 的时候, 参数可以省略。即:datagridview1.autoresizerow (0) 和 datagridview1.autoresizerows() c,临时的,让行头和列头自动调整 [vb.net] ' 列头高度自动调整 datagridview1.autoresizecolumnheadersheight() ' 行头宽度自动调整 datagridview1.autoresizerowheaderswidth( _ datagridviewrowheaderswidthsizemode.autosizetoallheaders) [c#] // 列头高度自动调整 datagridview1.autoresizecolumnheadersheight(); // 行头宽度自动调整 datagridview1.autoresizerowheaderswidth( datagridviewrowheaderswidthsizemode.autosizetoallheaders);
关于性能: 通过 autosizecolumnsmode 或者 autosizerowsmode 属性所指定的单元格进行自动调整时,如果调整次数过于多那么将可能导致性能下降,尤其是在行和列数比较多的情况下。在这时用 displayedcells 代替 allcells 能减少非所见的单元格的调整,从而提高性能。
⑨ datagridview 冻结列或行 go to top 1) 列冻结 datagridviewcolumn.frozen 属性为 true 时, 该列左侧的所有列被固定, 横向滚动时固定列不随滚动条滚动而左右移动。这对于重要列固定显示很有用。
[vb.net] ' datagridview1的左侧2列固定 datagridview1.columns(1).frozen = true
[c#] // datagridview1的左侧2列固定 datagridview1.columns[1].frozen = true; 但是,datagridview.allowusertoordercolumns = true 时,固定列不能移动到非固定列, 反之亦然。 2) 行冻结 datagridviewrow.frozen 属性为 true 时, 该行上面的所有行被固定, 纵向滚动时固定行不随滚动条滚动而上下移动。 [vb.net] ' datagridview1 的上3行固定 datagridview1.rows(2).frozen = true [c#] // datagridview1 的上3行固定 datagridview1.rows[2].frozen = true;
⑩ datagridview 列顺序的调整 go to top 设定 datagridview 的 allowusertoordercolumns 为 true 的时候, 用户可以自由调整列的顺序。 当用户改变列的顺序的时候,其本身的 index 不会改变,但是 displayindex 改变了。你也可以通过程序改变 displayindex 来改变列的顺序。 列顺序发生改变时会引发 columndisplayindexchanged 事件: [vb.net] ' datagridview1的columndisplayindexchanged事件处理方法 private sub datagridview1_columndisplayindexchanged(byval sender as object, _ byval e as datagridviewcolumneventargs) _ handles datagridview1.columndisplayindexchanged console.writeline("{0} 的位置改变到 {1} 。", _ e.column.name, e.column.displayindex) end sub [c#] // datagridview1的columndisplayindexchanged事件处理方法 private void datagridview1_columndisplayindexchanged(object sender, datagridviewcolumneventargs e) { console.writeline("{0} 的位置改变到 {1} ", e.column.name, e.column.displayindex); } -------------------------------------------------------------------------------- ? datagridview 行头列头的单元格 go to top
[vb.net] ' datagridview1的第一列列头内容 datagridview1.columns(0).headercell.value = "第一列" ' datagridview1的第一行行头内容 datagridview1.rows(0).headercell.value = "第一行" ' datagridview1的左上头部单元内容 datagridview1.topleftheadercell.value = "左上" [c#] // 改变datagridview1的第一列列头内容 datagridview1.columns[0].headercell.value = "第一列"; // 改变datagridview1的第一行行头内容 datagridview1.rows[0].headercell.value = "第一行"; // 改变datagridview1的左上头部单元内容 datagridview1.topleftheadercell.value = "左上"; 另外你也可以通过 headertext 来改变他们的内容。 [vb.net] ' 改变datagridview1的第一列列头内容 datagridview1.columns(0).headertext = "第一列" [c#] // 改变datagridview1的第一列列头内容 datagridview1.columns[0].headertext = "第一列"; -------------------------------------------------------------------------------- ? datagridview 剪切板的操作 go to top datagridview.clipboardcopymode 属性被设定为 datagridviewclipboardcopymode.disable 以外的情况时,「ctrl + c」 按下的时候,被选择的单元格的内容会拷贝到系统剪切板内。格式有: text, unicodetext,html, commaseparatedvalue。可以直接粘贴到 excel 内。 clipboardcopymode 还可以设定 header部分是否拷贝: enablealwaysincludeheadertext 拷贝header部分、enablewithoutheadertext 则不拷贝。默认是 enablewithautoheadertext , header 如果选择了的话,就拷贝。 1) 编程方式实现剪切板的拷贝 clipboard.setdataobject(datagridview1.getclipboardcontent()) 2) datagridview 的数据粘贴 实现剪切板的拷贝比较容易,但是实现 datagridview 的直接粘贴就比较难了。「ctrl + v」按下进行粘贴时,datagridview 没有提供方法,只能自己实现。 以下,是粘贴时简单的事例代码,将拷贝数据粘贴到以选择单元格开始的区域内。 [vb.net] ' 当前单元格是否选择的判断 if datagridview1.currentcell is nothing then return end if dim insertrowindex as integer = datagridview1.currentcell.rowindex ' 获取剪切板的内容,并按行分割 dim pastetext as string = clipboard.gettext() if string.isnullorempty(pastetext) then return end if pastetext = pastetext.replace(vbcrlf, vblf) pastetext = pastetext.replace(vbcr, vblf) pastetext.trimend(new char() {vblf}) dim lines as string() = pastetext.split(vblf) dim isheader as boolean = true for each line as string in lines ' 是否是列头 if isheader then isheader = false else ' 按 tab 分割数据 dim vals as string() = line.split(controlchars.tab) ' 判断列数是否统一
更多详细内容请查看:http://www.111cn.net/net/160/37258.htm