*如果标题不是很好,请见谅。我不确定如何用几句话来概括这个问题。
我有一个 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
出现在查询之后。
那么如何获取位于查询右侧的字符串部分的宽度?
最佳答案
Note: This is not a direct answer to the question. It's an alternative.
作为一个选项,您可以在 HTML 表格中显示搜索结果并将其显示在 WebBrowser
控件中,并使用 javascript 突出显示搜索文本。
要将搜索结果显示为 HTML,我将使用 T4 运行时文本模板。这样我就可以将数据传递给 html 模板,并通过将模板的输出字符串分配给 WebBrowser
控件的 DocumentText
属性来轻松呈现报告。我已经使用这个想法来创建简单快速的打印文档,例如看看 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(); }
处理
WebBrowser
的DocumentCompleted
事件,调用Document
对象的InvokeScript
方法,调用highlight
我们已经在 html 中创建的 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
,然后按搜索按钮查看结果。
关于c# - 在双向文本中,点右侧的字符串宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54574412/