mysql DataGridView的所有单元格中的突出显示特定字符

jjjwad0x  于 2023-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(92)

当我在DataGridView中进行字符搜索时,我希望只选择搜索到的特定字符(我给予它一个红框),而不选择单元格中的所有字符。我该怎么做?
我写了代码,结果看起来像这样:
预期产出:
我希望只选择搜索到的特定字符(我给予它一个红框),而不选择单元格中的所有字符

private void AddCustomer_DataGridView_CellFormatting(object? sender, DataGridViewCellFormattingEventArgs e)
{
    try
    {
        if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
        {
            if (!String.IsNullOrEmpty(AddCustomer_SearchTextBox.Text) && e.Value != null)
            {
                string strValue = (String)e.Value;
                if (strValue.Contains(AddCustomer_SearchTextBox.Text))
                {
                    DataGridViewCellStyle? cellStyle = e.CellStyle;
                    if (cellStyle != null)
                    {
                        // Problem ini here, how to select only specific characters in a cell (not all characters)
                        cellStyle.BackColor = ColorTranslator.FromHtml("#0078D7");
                        cellStyle.ForeColor = ColorTranslator.FromHtml("#FFFFFF");
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        ExLogger.LogException(ex, "");
        MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

//正常工作

public List<Customer>? SearchCustomers(int count, int minOffset, int maxOffset, string keyword, string sortExpression = "ASC")
{
    if (count <= 0)
    {
        return new List<Customer>();
    }

    int limit = 1 + (maxOffset - minOffset);
    if (limit < 0)
    {
        limit = 0;
    }

    int offset = minOffset - 1; // start
    if (offset < 0)
    {
        offset = 0;
    }
    if (offset >= count)
    {
        offset = count - 1;
    }

    string sql = @"SELECT customer.ID, customer.created, customer.name, customer.place_of_birth, customer.date_of_birth, customer.gender_id, customer.address, customer.neighbourhood_hamlet, customer.urban_village, customer.subdistrict, customer.religion_id, customer.marital_status_id, customer.profession, customer.citizenship_id, customer.email, customer.phone_number, customer.send_me 
                    FROM customer 
                        INNER JOIN gender ON gender_id = gender.ID 
                        INNER JOIN religion ON religion_id = religion.ID 
                        INNER JOIN marital_status ON marital_status_id = marital_status.ID 
                        INNER JOIN citizenship ON citizenship_id = citizenship.ID 
                    WHERE customer.ID LIKE @ID OR 
                          customer.created LIKE @created OR 
                          customer.name LIKE @name OR 
                          customer.place_of_birth LIKE @place_of_birth OR 
                          customer.date_of_birth LIKE @date_of_birth OR 
                          gender.gender_name LIKE @gender_id OR 
                          customer.address LIKE @address OR 
                          customer.neighbourhood_hamlet LIKE @neighbourhood_hamlet OR 
                          customer.urban_village LIKE @urban_village OR 
                          customer.subdistrict LIKE @subdistrict OR 
                          religion.religion_name LIKE @religion_id OR 
                          marital_status.marital_name LIKE @marital_status_id OR 
                          customer.profession LIKE @profession OR 
                          citizenship.citizenship_name LIKE @citizenship_id OR 
                          customer.email LIKE @email OR 
                          customer.phone_number LIKE @phone_number OR 
                          customer.send_me LIKE @send_me 
                    ORDER BY STR_TO_DATE(customer.created, '%d/%m/%Y %H:%i:%s') " + sortExpression + " LIMIT " + limit + " OFFSET " + offset;

    object[] parms = { "@ID",  '%'+ keyword + '%',
                       "@created",  '%'+ keyword + '%',
                       "@name",  '%'+ keyword + '%',
                       "@place_of_birth",  '%'+ keyword + '%',
                       "@date_of_birth",  '%'+ keyword + '%',
                       "@gender_id",  '%'+ keyword + '%',
                       "@address",  '%'+ keyword + '%',
                       "@neighbourhood_hamlet",  '%'+ keyword + '%',
                       "@urban_village",  '%'+ keyword + '%',
                       "@subdistrict",  '%'+ keyword + '%',
                       "@religion_id",  '%'+ keyword + '%',
                       "@marital_status_id",  '%'+ keyword + '%',
                       "@profession",  '%'+ keyword + '%',
                       "@citizenship_id",  '%'+ keyword + '%',
                       "@email",  '%'+ keyword + '%',
                       "@phone_number",  '%'+ keyword + '%',
                       "@send_me",  '%'+ keyword + '%'
                     };

    return db.Read(sql, Make, parms).ToList();
}

iyfamqjs

iyfamqjs1#

您可以处理CellPainting事件以 * 突出显示 * DataGridView单元格中的文本部分。
StringFormat.SetMeasurableCharacterRanges()方法可用于创建CharacterRange元素,然后将其馈送到Graphics.MeasureCharacterRanges(),以生成描述这些范围内文本部分边界的Regions。
一些事情要记住:
1.当需要刷新单元格时,需要调用e.PaintBackground()e.PaintContent()来重置单元格的呈现,否则最终会在同一图形表面上多次绘制同一图形
1.绘制自定义图形内容时需要设置e.Handled = true,否则不会呈现
1.需要考虑单元格中文本的对齐方式。它通常垂直居中,但也可以水平居中或其他方式(例如,左/上对齐)。由于它在我们的控制之下,我们可以相应地调整StringFormat的垂直和水平对齐。在本例中,我假定使用默认布局并指定[StringFormat].LineAlignment = StringAlignment.Center;
1.一个或多个单元格的文本可能多次包含搜索字符串,所以最好使用简单的Regex来查找文本的所有匹配部分,这样我们就可以突出显示所有
1.您可以填充Region的内容,但如果您需要Rectangle,因为某些绘图方法不接受Region作为绘图区域,您可以使用[Region].GetBounds([Graphics])将Region转换为RectangleF。使用Rectangle.Round()生成Rectangle
1.始终使用e.CellBounds值来定义要提交给用于测量文本和呈现图形的方法的文本的边界;如果你发现自己在用 * 幻数 * 调整这些界限,那么这个过程就有问题了。如果需要移动Region,请使用[Region].Translate();要移动矩形,请使用[Rectangle].Offset()[Rectangle].Inflate()
1.你需要处理掉所有的一次性物品。这包括(这里)你创建的StringFormat和Brushes/Pens,除非你使用从BrushesPensSystemBrushes类中获得的stock对象。显式释放这些对象非常重要,因为它们包含非托管资源。GC帮不了你

private void someDataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.ColumnIndex < 0 || e.RowIndex < 0) return;
    e.PaintBackground(e.ClipBounds, true);
    e.PaintContent(e.ClipBounds);

    var cellValue = e.FormattedValue?.ToString();
    if (string.IsNullOrEmpty(searchString) || string.IsNullOrEmpty(cellValue)) return;

    var positions = Regex.Matches(cellValue, searchString);
    if (positions.Count == 0) return;

    using (var format = new StringFormat(StringFormatFlags.FitBlackBox)) {
        // The Cell's vertical alignment is usually centered. Adjust as required
        format.LineAlignment = StringAlignment.Center;
        // Generates ranges for all matching strings found 
        format.SetMeasurableCharacterRanges(positions.OfType<Match>()
              .Select(m => new CharacterRange(m.Index, m.Length)).ToArray());
        // Generate Regions that contain the search text
        var regions = e.Graphics.MeasureCharacterRanges(cellValue, e.CellStyle.Font, e.CellBounds, format);

        using (var brush = new SolidBrush(Color.FromArgb(80, Color.Fuchsia))) {
            foreach (var region in regions) {
                e.Graphics.FillRegion(brush, region);
                // And / or draw a rectangle around the claculated box
                e.Graphics.DrawRectangle(Pens.Red, Rectangle.Round(region.GetBounds(e.Graphics)));
            }
        }
    }
    e.Handled = true;
}

您可以订阅TextBox的KeyDown事件来处理Enter键,并在搜索字符串更改时使DataGridView无效:

private string searchString = "";

private void searchTextBox_KeyDown(object sender, KeyEventArgs e) {
    if (e.KeyCode == Keys.Enter) {
        e.SuppressKeyPress = true;
        searchString = (sender as Control).Text;
        someDataGridView.Invalidate();
    }
}

它是这样工作的:

相关问题