在上一章内容《C#Winform的DataGridView控件使用详解1-七种DataGridViewColumn类型使用方法》中,我们介绍了6种DataGridView列对象,在本章内容部中,我们将详细介绍DataGridViewTextBoxColumn对象的Cell设置(表头、表格内容、行序号)、右键弹出行操作(新建行、删除行、清空内容、复制、粘贴)。
DataGridView的表格样式包括表头(ColumnHeadersDefaultCellStyle)和表格内容(RowsDefaultCellStyle)的样式,此处我们对其的字体、对齐方式、点击自动排序和宽度可调节来进行设置:
1、字体与对齐方式设置
// 设置表头居中,其对齐方式一共有10种,包含竖向的顶中底和水平的左中右以及NotSet
this.dtLineHCurvePara.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
//设置表头字体样式
this.dtLineHCurvePara.ColumnHeadersDefaultCellStyle.Font = new Font("宋体", 11);
//设置单元格cell内容居中
this.dtLineHCurvePara.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
//设置单元格cell字体样式
this.dtLineHCurvePara.RowsDefaultCellStyle.Font = new Font("宋体",
设置各种居中和字体样式后,结果如下显示:
2、对齐与表格排序的相互影响
但是当我们设置了表头和单元格均居中后,但发现表头并没有出现居中效果,如下图:
这里,我们需要调整一下表格列的参数,将排序模式设置为无排序:
设置了表头居中并没有显示居中效果的原因在于,该列排序模式为自动排序,所有该表头位置会出现一个便于排序点击的倒三角,会占据表头位置。
3、表格宽度调节
Excel表格的行高和列宽都能手动拉,为了满足一定的需求,我们需要设置是否可以调整行列尺寸(False:不能手动调整,True:可手动调整)。
我们直接使用并填充数据的DataGridView默认是没有行号的,这里我们要利用表格的RowPostPaint函数,对表格进行重绘:
#region 显示行号
private void dtLineHCurvePara_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
var grid = sender as DataGridView;
var rowidx = (e.RowIndex + 1).ToString();
var centerFormat = new StringFormat()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
var headerBuunds = new System.Drawing.Rectangle(e.RowBounds.Left, e.RowBounds.Top, grid.RowHeadersWidth, e.RowBounds.Height);
e.Graphics.DrawString(rowidx, new Font("宋体", 11), SystemBrushes.ControlText, headerBuunds, centerFormat);
}
#endregion
对表格进行重绘后,表格每添加一行,均会显示每行的行号,行号的字体也可以在代码中设置,表现如下:
为实现表格的会操作,给DataGridView绑定contextMenuStrip控件,然后在右键弹出菜单里面添加新建行、删除行、清除选中内容、复制和粘贴操作
首先在软件界面登录的时候,将表格与右键弹出框绑定。
#region 编辑平曲线界面的Load事件
private void sFrmLineHCurveParaEdit_Load(object sender, EventArgs e)
{
this.dtLineHCurvePara.ContextMenuStrip = this.contextMenuStrip1;
}
右键弹出框,点击【新建行】按钮,即可在表格最后新增一行
#region 新建行
private void btnNewRow_Click(object sender, EventArgs e)
{
this.dtLineHCurvePara.Rows.Add();
}
#endregion
右键弹出框,点击【删除行】按钮,即可删除指定行号的行,如果要删除选中行,需要循环遍历DataGridView的SelectedRows对象,获取选中行的行序号,删除即可。
#region 删除行
private void btnDeleteRow_Click(object sender, EventArgs e)
{
int RowIndex = 1;//需要删除行的行序号
this.dtLineHCurvePara.Rows.RemoveAt(RowIndex);
}
#endregion
右键弹出框,点击【清除】按钮,即可将选中单元格的内容清空
#region 清除选中内容
private void btnClear_Click(object sender, EventArgs e)
{
//根据选中的datagridview单元格,对其内容赋值为""
int cellsCount = this.dtLineHCurvePara.SelectedCells.Count; //选中的单元格数量
for (int i = 0; i < cellsCount; i++)//循环选中的单元格
{
dtLineHCurvePara.SelectedCells[i].Value = "";
}
}
#endregion
右键弹出框,点击【复制】按钮,即可将选中表格内容按照一定格式写入电脑剪切板,后续可直接在Excel表中粘贴即可,会保留一样的数据格式。
#region 复制选中的单元格内容
private void btnCopy_Click(object sender, EventArgs e)
{
try
{
Clipboard.SetText(this.dtLineHCurvePara.GetClipboardContent().GetData(DataFormats.Text).ToString());
}
catch{}
}
#endregion
右键弹出框,点击【粘贴】按钮,即可将剪切板上的内容按照格式依序粘贴到DataGridView的单元格内。它可以自动判断需要的行,然后行自增,可以判断需要的列。列数不够会弹出提示。可以实现直接将Excel表格内容粘贴进来。
#region 粘贴剪切板内表格内容到DataGridView
private void btnPaste_Click(object sender, EventArgs e)
{
try
{
string clipboardText = Clipboard.GetText(); //获取剪贴板中的内容
if (string.IsNullOrEmpty(clipboardText))//检测是否为空
{
return;
}
int colnum = 0; //获取剪切板列数量
int rownum = 0; //获取剪切板行数量
for (int i = 0; i < clipboardText.Length; i++)
{
if (clipboardText.Substring(i, 1) == "\t") //每列
{
colnum++;
}
if (clipboardText.Substring(i, 1) == "\n") //每行
{
rownum++;
}
}
//粘贴板上的数据来源于EXCEL时,每行末尾都有\n,来源于DataGridView是,最后一行末尾没有\n
if (clipboardText.Substring(clipboardText.Length - 1, 1) == "\n") //剪切板最后一位
{
rownum--;
}
//此时,行数列数均比真实行列内容对象少1
colnum = colnum / (rownum + 1); //?????
object[,] data; //定义object类型的二维数组
data = new object[rownum + 1, colnum + 1]; //根据剪贴板的行列数实例化数组
//根据创建的data数组的行列数,检测是否当前datagridview行数大于等于data数组行数,少于则新建行
while (rownum > this.dtLineHCurvePara.RowCount - this.dtLineHCurvePara.SelectedCells[this.dtLineHCurvePara.SelectedCells.Count - 1].RowIndex - 1) //每次创建五行,直到数量足够
{
for (int i = 0; i < 5; i++)
{
this.dtLineHCurvePara.Rows.Add();
}
}
// 检查剪切板内的列是否多于datagridview2内的列
if ((colnum + 1) > this.dtLineHCurvePara.ColumnCount)
{
MessageBox.Show("复制列数大于当前表格列数\n,请重新复制!");
return;
}
string rowStr = "";
//对数组各元素赋值
for (int i = 0; i <= rownum; i++)
{
for (int j = 0; j <= colnum; j++)
{
//一行中的其它列
if (j != colnum)
{
rowStr = clipboardText.Substring(0, clipboardText.IndexOf("\t"));
clipboardText = clipboardText.Substring(clipboardText.IndexOf("\t") + 1); //将前面使用过的部分裁剪
}
//一行中的最后一列(最后一个不为\r)
if (j == colnum && clipboardText.IndexOf("\r") != -1)
{
rowStr = clipboardText.Substring(0, clipboardText.IndexOf("\r"));
}
//最后一行的最后一列(最后一个为\r)
if (j == colnum && clipboardText.IndexOf("\r") == -1)
{
rowStr = clipboardText.Substring(0);
}
data[i, j] = rowStr;
}
//截取下一行及以后的数据
clipboardText = clipboardText.Substring(clipboardText.IndexOf("\n") + 1);
}
clipboardText = Clipboard.GetText();
int cellsCount = this.dtLineHCurvePara.SelectedCells.Count; //选中的单元格数量
int r1 = (this.dtLineHCurvePara.SelectedCells[cellsCount - 1].RowIndex); //选中的第一个的行下标
int r2 = (this.dtLineHCurvePara.SelectedCells[0].RowIndex); //选中最后一个的行下标
int c1 = (this.dtLineHCurvePara.SelectedCells[cellsCount - 1].ColumnIndex); //选中的第一个的列下标
int c2 = (this.dtLineHCurvePara.SelectedCells[0].ColumnIndex); //选中的最后一个的列下表
int rowIndex = Math.Abs(r2 - r1) + 1; //选中单元格的行数量
int colIndex = Math.Abs(c2 - c1) + 1; //选中但换个的列数量
if (colIndex != colnum + 1 || rowIndex != rownum + 1) //选中的行列数量与剪切板内的行列数量不一致
{
//如果区域不一致,选取选中的第一格单元格作为锚点
for (int i = 0; i <= rownum; i++) //遍历行
{
for (int j = 0; j <= colnum; j++) //遍历列
{
this.dtLineHCurvePara.Rows[i + r1].Cells[j + c1].Value = data[i, j];
}
}
}
else
{
for (int i = 0; i <= rownum; i++) //遍历行
{
for (int j = 0; j <= colnum; j++) //遍历列
{
this.dtLineHCurvePara.Rows[i + r1].Cells[j + c1].Value = data[i, j];
}
}
}
}
catch { }
}
#endregion