C#:DataGridView技巧:文本TextChanged事件、日期控件、标题图标等

目录

一、编辑单元格时TextChanged事件获取文本

二、DataGridView中添加自定义日期字段

三、DataGridView行标题显示图标

附:代码中用到的几个方法:


一、编辑单元格时TextChanged事件获取文本

DataGridView自带的文本框在输入文字时无法实时触发事件,只能在按回车或者转移光标结束编辑时才能触发事件,以下代码利用TextChanged事件实现。比如输入拼音码时同步筛选字典操作,如下图,输入首拼实时筛选药品列表:

/// <summary>
/// 当前单元格编辑控件
/// </summary>
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);
}

二、DataGridView中添加自定义日期字段

DateTimePicker dtp;
/// <summary>
/// 初始化日期控件
/// </summary>
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();
}

三、DataGridView行标题显示图标

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);//绘制图标
    }
}

附:代码中用到的几个方法:

/// <summary>
/// 生成圆形带文字图片
/// </summary>
/// <param name="width">外径</param>
/// <param name="innerWidth">圆环内径</param>
/// <param name="txt">文字</param>
/// <param name="foreColor">文字颜色</param>
/// <param name="backColor">背景色</param>
/// <param name="innerBackColor">圆环内部颜色</param>
/// <param name="font">文字字体</param>
/// <param name="backSmoothingMode">背景圆形是否平滑</param>
/// <param name="foreSmoothingMode">文字是否平滑</param>
/// <returns></returns>
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;
}
/// <summary>
/// 获取绘制文字尺寸以及DrawString时的xy偏移量
/// </summary>
/// <param name="txt"></param>
/// <param name="font"></param>
/// <param name="smoothingMode"></param>
/// <returns></returns>
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;
}

 

  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值