datagridview绑定与详细说明
1、实现一个用于处理数据库教程数据检索的详细信息的方法。下面的代码示例实现一个 getdata 方法,该方法对一个 sqldataadapter 组件进行初始化,并使用该组件填充 datatable。然后,将 datatable 绑定到 bindingsource 组件。请确保将 connectionstring 变量的值设置为与数据库相应的值。
private void getdata(string selectcommand)
{
try
{
string connectionstring =
"integrated security=sspi;persist security info=false;" +
"initial catalog=northwind;data source=localhost";
dataadapter = new sqldataadapter(selectcommand, connectionstring);
sqlcommandbuilder commandbuilder = new sqlcommandbuilder(dataadapter);
datatable table = new datatable();
table.locale = system.globalization.cultureinfo.invariantculture;
dataadapter.fill(table);
bindingsource1.datasource = table;
datagridview1.autoresizecolumns(
datagridviewautosizecolumnsmode.allcellsexceptheader);
}
catch (sqlexception)
{
messagebox.show("to run this example, replace the value of the " +
"connectionstring variable with a connection string that is " +
"valid for your system.");
}
}
2、在窗体的 load 事件处理程序中,将 datagridview 控件绑定到 bindingsource 组件,并调用 getdata 方法从数据库中检索数据
private void form1_load(object sender, system.eventargs e)
{
datagridview1.datasource = bindingsource1;
getdata("select * from customers");
}
① 取得或者修改当前单元格的内容
② 设定单元格只读
③ 不显示最下面的新行
④ 判断新增行
⑤ 行的用户删除操作的自定义
⑥ 行、列的隐藏和删除
⑦ 禁止列或者行的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 来设定选定行。
/**////
/// 向下遍历
///
///
///
private void button4_click(object sender, eventargs e)
...{
int row = this.datagridview1.currentrow.index + 1;
if (row > this.datagridview1.rowcount - 1)
row = 0;
this.datagridview1.currentcell = this.datagridview1[0, row];
}
/**////
/// 向上遍历
///
///
///
private void button5_click(object sender, eventargs e)
...{
int row = this.datagridview1.currentrow.index - 1;
if (row < 0)
row = this.datagridview1.rowcount - 1;
this.datagridview1.currentcell = this.datagridview1[0, row];
}
* 注意: 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 事件处理方法
private sub datagridview1_cellbeginedit(byval sender as object, _
byval e as datagridviewcellcanceleventargs) _
handles datagridview1.cellbeginedit
dim dgv as datagridview = ctype(sender, datagridview)
' 是否可以进行编辑的条件检查
if dgv.columns(e.columnindex).name = "column1" andalso _
not cbool(dgv("column2", e.rowindex).value) then
' 取消编辑
e.cancel = true
end if
end sub
[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).minimum
' 第一行的最小行高设定为 50
datagridview1.rows(0).minimum
[c#]
// 第一列的最小列宽设定为 100
datagridview1.columns[0].minimum;
// 第一行的最小行高设定为 50
datagridview1.rows[0].minimum;
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)
' 判断列数是否统一