当我在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();
}
1条答案
按热度按时间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,除非你使用从
Brushes
,Pens
和SystemBrushes
类中获得的stock对象。显式释放这些对象非常重要,因为它们包含非托管资源。GC帮不了你您可以订阅TextBox的
KeyDown
事件来处理Enter
键,并在搜索字符串更改时使DataGridView无效:它是这样工作的: