目录
一、编辑单元格时TextChanged事件获取文本
二、DataGridView中添加自定义日期字段
三、DataGridView行标题显示图标
附:代码中用到的几个方法:
DataGridView自带的文本框在输入文字时无法实时触发事件,只能在按回车或者转移光标结束编辑时才能触发事件,以下代码利用TextChanged事件实现。比如输入拼音码时同步筛选字典操作,如下图,输入首拼实时筛选药品列表:
///
/// 当前单元格编辑控件
///
private Control cntObject;
private void textBox_TextChanged(object sender, EventArgs e)
{
label1.Text += cntObject.Text;//实时获取文本
}
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView1.CurrentCell.ColumnIndex == 0)//假设第一列需要TextChanged事件
{
cntObject = e.Control;
cntObject.TextChanged += new EventHandler(textBox_TextChanged);
}
}
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (cntObject != null)
cntObject.TextChanged -= new EventHandler(textBox_TextChanged);
}
DateTimePicker dtp;
///
/// 初始化日期控件
///
private void InitDate()
{
dtp = new DateTimePicker();
dtp.Leave += new EventHandler(dtp_Leave);
dtp.VisibleChanged += new EventHandler(dtp_VisibleChanged);
dtp.Format = DateTimePickerFormat.Custom;
dtp.CustomFormat = "yyyy-MM-dd";
dtp.Value = DateTime.Now;
//dtp.ShowUpDown = true;
dtp.Hide();
dtp.Parent = dataGridView1;
}
private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.CurrentCell.ColumnIndex == dataGridView1.Columns["date"].Index)//假设date列需要显示控件
{//点击日期列时显示日期控件
dtp.Location = dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true).Location;
dtp.Size = dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true).Size;
if (dataGridView1[e.ColumnIndex, e.RowIndex].Value != DBNull.Value)
dtp.Value = Convert.ToDateTime(dataGridView1[e.ColumnIndex, e.RowIndex].Value);//单元格值赋值给控件
dtp.Tag = dataGridView1.CurrentCell;//用于dtp_VisibleChanged事件中从控件获取日期
dtp.Show();
dtp.Focus();
}
}
private void dtp_Leave(object sender, EventArgs e)
{
dtp.Hide();//焦点从日期控件离开时隐藏
}
private void dtp_VisibleChanged(object sender, EventArgs e)
{//改变日期时将日期赋值给单元格
if (dtp.Tag != null)
{
DataGridViewCell cell = (DataGridViewCell)dtp.Tag;
if (dtp.Value == dtp.MinDate)
cell.Value = DBNull.Value;
else
cell.Value = dtp.Value.ToString("yyyy-MM-dd");
}
if (dtp.Visible == false)
dataGridView1.Focus();
}
private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{//绘制行时发生的事件
DataRowView dr = (DataRowView)dataGridView1.Rows[e.RowIndex].DataBoundItem;
if (Convert.ToInt32(dr["未执行数量"]) > 0)
{
int width = 15;
Image img = GetNumImage(width, 0, Math.Min(99, Convert.ToInt32(dr["未执行数量"])).ToString(), Color.White, Color.Red, Color.Black,
new Font("宋体", 9, FontStyle.Regular), true, false);
e.Graphics.DrawImage(img, e.RowBounds.Left + dataGridView1.RowHeadersWidth - width - 2, e.RowBounds.Top + (dataGridView1.RowTemplate.Height - width) / 2);//绘制图标
}
if (dr["医保颜色"]!=DBNull.Value)
{
int width = 15;
Image img = GetNumImage(width, 0, dr["医保"].ToString().Substring(0,1), Color.Black, Color.FromArgb(Convert.ToInt32(dr["医保颜色"])), Color.Black,
new Font("宋体", 9, FontStyle.Regular), true, false);
e.Graphics.DrawImage(img, e.RowBounds.Left + dataGridView1.RowHeadersWidth - width - 2 - 17 - 17, e.RowBounds.Top + (dataGridView1.RowTemplate.Height - width) / 2);//绘制图标
}
}
///
/// 生成圆形带文字图片
///
/// 外径
/// 圆环内径
/// 文字
/// 文字颜色
/// 背景色
/// 圆环内部颜色
/// 文字字体
/// 背景圆形是否平滑
/// 文字是否平滑
///
public static Bitmap GetNumImage(float width, float innerWidth, string txt, Color foreColor, Color backColor, Color innerBackColor, Font font, bool backSmoothingMode, bool foreSmoothingMode)
{
Bitmap bmp = null;
if (width > 0)
{
bmp = new Bitmap((int)width, (int)width);
}
else if (string.IsNullOrEmpty(txt) == false)
{
RectangleF recTxt = GetStringSize(txt, font, foreSmoothingMode);
bmp = new Bitmap((int)recTxt.Width + 1, (int)recTxt.Height + 1);
}
Graphics g = Graphics.FromImage(bmp);
//g.Clear(Color.Green);
if (width > 0)
{
if (backSmoothingMode)
{
g.SmoothingMode = SmoothingMode.HighQuality; //图片柔顺模式选择
g.InterpolationMode = InterpolationMode.HighQualityBicubic;//高质量
g.CompositingQuality = CompositingQuality.HighQuality;//再加一点
g.FillEllipse(new SolidBrush(backColor), 0, 0, width - 1, width - 1);//抗锯齿尺寸会增加一个像素
if (innerWidth > 0)
{
g.FillEllipse(new SolidBrush(innerBackColor), (width - innerWidth) / 2f, (width - innerWidth) / 2f, innerWidth - 1, innerWidth - 1);//抗锯齿尺寸会增加一个像素
}
}
else
{
g.FillEllipse(new SolidBrush(backColor), 0, 0, width, width);
if (innerWidth > 0)
{
g.FillEllipse(new SolidBrush(innerBackColor), (width - innerWidth) / 2f, (width - innerWidth) / 2f, innerWidth, innerWidth);//抗锯齿尺寸会增加一个像素
}
}
}
if (string.IsNullOrEmpty( txt)==false)
{
RectangleF recTxt = GetStringSize(txt, font, foreSmoothingMode);
if (foreSmoothingMode)
{
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
}
PointF tPoint = new PointF();
tPoint.X = Math.Abs(bmp.Width - recTxt.Width) / 2f;
tPoint.Y = Math.Abs(bmp.Width - recTxt.Height) / 2f;
g.DrawString(txt, font, new SolidBrush(foreColor), tPoint.X - recTxt.X, tPoint.Y - recTxt.Y);
}
//return null;
return bmp;
}
///
/// 获取绘制文字尺寸以及DrawString时的xy偏移量
///
///
///
///
///
unsafe public static RectangleF GetStringSize(string txt, Font font, bool smoothingMode)
{
string[] lines = txt.Split(new string[] { "\r\n", "\r" }, StringSplitOptions.RemoveEmptyEntries);
Bitmap bmp = new Bitmap(1, 1);
Graphics g = Graphics.FromImage(bmp);
SizeF tSize = g.MeasureString(txt, font);
bmp = new Bitmap((int)tSize.Width + 2, (int)tSize.Height + 2);
g = Graphics.FromImage(bmp);
//g.Clear(Color.Black);
if (smoothingMode)
{
g.SmoothingMode = SmoothingMode.HighQuality; //图片柔顺模式选择
g.InterpolationMode = InterpolationMode.HighQualityBicubic;//高质量
g.CompositingQuality = CompositingQuality.HighQuality;//再加一点
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
}
g.DrawString(txt, font, Brushes.Black, 0, 0);
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
Rectangle recNew = new Rectangle();
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
int step = bmpData.Stride - bmpData.Width * 4;
byte* pRgb = (byte*)bmpData.Scan0;
int i = 0;
int j = 0;
//string t = "";
bool brk = false;
for (int r = 0; r < bmp.Height; r++)//上边距
{
for (int c = 0; c < bmp.Width; c++)
{
int ov = r * bmpData.Stride + c * 4;
//t +=pRgb[ov]+"," + pRgb[ov + 1] + "," + pRgb[ov + 2] + "," + pRgb[ov + 3] + "|";
if (pRgb[ov] + pRgb[ov + 1] + pRgb[ov + 2] + pRgb[ov + 3] > 0)
{
recNew.Y = r;
brk = true;
break;
}
}
if (brk)
break;
//t += "\r\n";
}
brk = false;
for (int r = bmp.Height - 1; r >= 0; r--)//下边距
{
for (int c = 0; c < bmp.Width; c++)
{
int ov = r * bmpData.Stride + c * 4;
if (pRgb[ov] + pRgb[ov + 1] + pRgb[ov + 2] + pRgb[ov + 3] > 0)
{
recNew.Height = r + 1 - recNew.Y;
brk = true;
break;
}
}
if (brk)
break;
}
brk = false;
for (int c = 0; c < bmp.Width; c++)//左边距
{
for (int r = 0; r < bmp.Height; r++)
{
int ov = r * bmpData.Stride + c * 4;
if (pRgb[ov] + pRgb[ov + 1] + pRgb[ov + 2] + pRgb[ov + 3] > 0)
{
recNew.X = c;
brk = true;
break;
}
}
if (brk)
break;
}
brk = false;
for (int c = bmp.Width - 1; c >= 0; c--)//右边距
{
for (int r = 0; r < bmp.Height; r++)
{
int ov = r * bmpData.Stride + c * 4;
if (pRgb[ov] + pRgb[ov + 1] + pRgb[ov + 2] + pRgb[ov + 3] > 0)
{
recNew.Width = c + 1 - recNew.X;
brk = true;
break;
}
}
if (brk)
break;
}
bmp.UnlockBits(bmpData);
return recNew;
}