*如果标题不是很好,请抱歉。我不知道如何用几句话来概括这个问题。
我有一个DataGridView
和一个搜索框。当用户键入查询时,会突出显示DataGridView
单元格中的任何匹配结果。为了达到这个目的,我使用CellPainting
的DataGridView
事件并在结果后面画一个矩形。
一些细胞从右到左定向:
有些是从左到右的:
当方向是RTL时,我使用以下公式来计算高亮矩形X坐标:
e.CellBounds.Right - queryWidth - stringBeforeQueryWidth;
和stringBeforeQueryWidth
指的是这样的:
当方向是LTR时,我使用以下公式:
e.CellBounds.Left + stringBeforeQueryWidth;
和stringBeforeQueryWidth
指的是这样的:
我计算stringBeforeQueryWidth
的方式如下:
var stringBeforeQuery = cellValue.Substring(0, cellValue.IndexOf(query));
var stringBeforeQueryWidth =
e.Graphics.MeasureString(stringBeforeQuery, font, e.CellBounds.Width, format).Width;
因此,当方向是RTL时,我使用的事实是查询本身之前的所有字符都将被绘制到它的右侧,当方向是LTR时,我使用的事实是查询之前的所有字符它本身将被绘制在它的左侧。
当单元格包含组合LTR和RTL文本的字符串时,问题就开始了。例如:
假设查询是13
。要计算stringBeforeQueryWidth
,我需要רחוב ישראל ישראלי
的宽度和/5
的宽度。我不能使用cellValue.Substring(0, cellValue.IndexOf(query))
来检索它们,就像我只有一个方向时那样,因为רחוב ישראל ישראלי
在查询之前出现,而/5
在查询之后出现。
那么如何获得位于查询右侧的字符串部分的宽度?
注意:这不是问题的直接答案。这是另一种选择。
作为选项,您可以在HTML表格中显示搜索结果并将其显示在WebBrowser
控件中,并使用javascript突出显示搜索文本。
要将搜索结果显示为HTML,我将使用T4运行时文本模板。通过这种方式,我可以将数据传递给html模板,并通过将模板的输出字符串分配给DocumentText
控件的WebBrowser
属性来轻松呈现报表。我已经用这个想法来创建简单快速的打印文档,例如看看this post。
要突出显示文本,您可以使用一些JavaScript代码或插件。例如,你可以看看this post。
以下是我将在这篇文章中分享的示例的结果:
例
Form
并放下一个WebBrowser
控件和一个ToolStrip
控件,就像你在上面的图片中看到的那样。.cs
文件添加到项目中,并将以下代码粘贴到文件中:
namespace Sample
{
public class ReportModel
{
public string RTL { get; set; }
public string LTR { get; set; }
}
}
RunTime Text Template
项添加到项目中并将其命名为ReportTemplate.tt
。打开文件并粘贴以下内容。在这里,我使用this plugin突出显示文本。并将模型传递给t4模板以轻松生成HTML:
<#@ template language="C#"#>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ parameter name="Model" type="System.Collections.Generic.List<Sample.ReportModel>"#>
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=11" />
<title></title>
<style type="text/css">
body { font-family: Calibri;}
table { text-align:center; border-collapse: collapse;}
table, th, td { border: 1px solid black; }
th {background-color: #EEEEEE;}
th , td {padding: 2px;}
.container { width:100%; height:100%; }
.highlight { background: yellow; }
.rtl {direction: rtl; text-align: right;}
.ltr {direction: ltr; text-align: left;}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://johannburkard.de/resources/Johann/jquery.highlight-5.js"></script>
<script>
function highlight(text) {
$('#container').highlight(text);
}
</script>
</head>
<body>
<div id ="container" class="container">
<table style="width:100%">
<tr>
<th style="width:50%">LTR</th>
<th style="width:50%">RTL</th>
</tr>
<#
foreach(var item in Model)
{
#>
<tr>
<td class="ltr"><#=item.LTR#></td>
<td class="rtl"><#=item.RTL#></td>
</tr>
<#
}
#>
</table>
<div>
</body>
</html>
Load
事件并关闭脚本错误并初始化示例数据:
List<ReportModel> list;
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.ScriptErrorsSuppressed = true;
list = new List<ReportModel>()
{
new ReportModel(){ LTR = "Text 123 text", RTL = "متن 123 متن" } ,
new ReportModel(){ LTR = "Text 123 text", RTL = "متن 123 متن" } ,
new ReportModel(){ LTR = "Text 456 text", RTL = "متن 456 متن" } ,
new ReportModel(){ LTR = "Text 456 text", RTL = "متن 456 متن" } ,
new ReportModel(){ LTR = "Text 456 text", RTL = "متن 456 متن" } ,
new ReportModel(){ LTR = "Text 456 text", RTL = "متن 456 متن" } ,
};
}
Click
事件,并将搜索结果传递给模板并运行模板并在WebBrowser
控件中显示结果:
private void searchButton_Click(object sender, EventArgs e)
{
var txt = searchTextBox.Text;
var rpt = new ReportTemplate();
rpt.Session = new Dictionary<string, object>();
rpt.Session["Model"] = list.Where(x => x.LTR.Contains(txt) ||
x.RTL.Contains(txt)).ToList();
rpt.Initialize();
webBrowser1.DocumentText = rpt.TransformText();
}
DocumentCompleted
的WebBrowser
事件并调用InvokeScript
对象的Document
方法并调用我们已经在html中创建的highlight
javascript函数:
private void webBrowser1_DocumentCompleted(object sender,
WebBrowserDocumentCompletedEventArgs e)
{
var txt = searchTextBox.Text;
if (!string.IsNullOrEmpty(txt))
webBrowser1.Document.InvokeScript("highlight",
new object[] { txt });
}
123
,然后按搜索按钮查看结果。