我正在创建一个从DataGridView派生的自定义控件。我希望有一个搜索功能,它可以突出显示对单元格文本的搜索结果。下面是我目前所拥有的功能:
protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
if ((e.RowIndex <= -1) || (e.ColumnIndex <= -1) || string.IsNullOrWhiteSpace(HighlightedText) ||
(e.Value is null) || (e.Value == DBNull.Value) || e.Value.GetType().IsImage())
{
base.OnCellPainting(e);
return;
}
var cellText = e.FormattedValue.ToString();
var ind = cellText.IndexOf(HighlightedText, StringComparison.OrdinalIgnoreCase);
if (ind < 0)
{
base.OnCellPainting(e);
return;
}
var newLineInd = cellText.IndexOf(Environment.NewLine);
var rect = new Rectangle { Y = e.CellBounds.Y + 2 };
var before = cellText[..ind];
var flags = TextFormatFlags.TextBoxControl;
//I tried this but doesn't seem to work
var pos = e.CellStyle.Alignment switch
{
DataGridViewContentAlignment.TopLeft => TextFormatFlags.Top | TextFormatFlags.Left,
DataGridViewContentAlignment.TopCenter => TextFormatFlags.Top | TextFormatFlags.HorizontalCenter,
DataGridViewContentAlignment.TopRight => TextFormatFlags.Top | TextFormatFlags.Right,
DataGridViewContentAlignment.MiddleLeft => TextFormatFlags.VerticalCenter | TextFormatFlags.Left,
DataGridViewContentAlignment.MiddleCenter => TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter,
DataGridViewContentAlignment.MiddleRight => TextFormatFlags.VerticalCenter | TextFormatFlags.Right,
DataGridViewContentAlignment.BottomLeft => TextFormatFlags.Bottom | TextFormatFlags.Left,
DataGridViewContentAlignment.BottomCenter => TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter,
DataGridViewContentAlignment.BottomRight => TextFormatFlags.Bottom | TextFormatFlags.Right,
_ => TextFormatFlags.Left,
};
flags |= pos;
var match = cellText.Substring(ind, HighlightedText.Length);
var sizeBefore = TextRenderer.MeasureText(e.Graphics, before, e.CellStyle.Font, e.CellBounds.Size, flags);
var sizeMatch = TextRenderer.MeasureText(e.Graphics, match, e.CellStyle.Font, e.CellBounds.Size, flags);
if (sizeBefore.Width > 5)
{
rect.X = e.CellBounds.X + sizeBefore.Width - 5;
rect.Width = sizeMatch.Width - 6;
//if match is on the new line
if ((newLineInd != -1) && (ind > newLineInd))
{
var cellRow2Index = ind - newLineInd;
var breakWord = cellText.Substring(newLineInd, cellRow2Index);
var s3 = TextRenderer.MeasureText(e.Graphics, breakWord, e.CellStyle.Font, e.CellBounds.Size,
TextFormatFlags.TextBoxControl);
rect.X = e.CellBounds.X + 2 + s3.Width - 7;
rect.Y = e.CellBounds.Y + sizeMatch.Height + 2;
}
}
else
{
rect.X = e.CellBounds.X + 2;
rect.Width = sizeMatch.Width - 6;
}
if (newLineInd == -1)
{
var sizeCell = TextRenderer.MeasureText(e.Graphics, cellText, e.CellStyle.Font, e.CellBounds.Size,
TextFormatFlags.TextBoxControl);
if (sizeCell.Width < e.CellBounds.Width)
{
rect.Y = e.CellBounds.Y + ((e.CellBounds.Height - sizeCell.Height) / 2);
}
}
rect.Height = sizeMatch.Height;
e.Handled = true;
e.PaintBackground(e.CellBounds, true);
e.Graphics.FillRectangle(_highlightBrush, rect);
e.PaintContent(e.CellBounds);
}
正如你所看到的,计算并不精确,而且添加了很多随机数,这些随机数对不同的DPI不起作用。最重要的是,我不知道如何解释不同的文本位置。我试着使用e.CellStyle.Alignment
来修改flags
变量,但它不起作用。在下面的图片中,我突出显示了“19”:
1条答案
按热度按时间jq6vz3qz1#
谢谢@dr.null.根据您提供的链接,我写了以下内容: