双向文本中字符串右侧的字符串宽度

问题描述 投票:3回答:1

*如果标题不是很好,请抱歉。我不知道如何用几句话来概括这个问题。


我有一个DataGridView和一个搜索框。当用户键入查询时,会突出显示DataGridView单元格中的任何匹配结果。为了达到这个目的,我使用CellPaintingDataGridView事件并在结果后面画一个矩形。

一些细胞从右到左定向:

enter image description here

有些是从左到右的:

enter image description here

当方向是RTL时,我使用以下公式来计算高亮矩形X坐标:

e.CellBounds.Right - queryWidth - stringBeforeQueryWidth;

stringBeforeQueryWidth指的是这样的:

enter image description here

当方向是LTR时,我使用以下公式:

e.CellBounds.Left + stringBeforeQueryWidth;

stringBeforeQueryWidth指的是这样的:

enter image description here

我计算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文本的字符串时,问题就开始了。例如:enter image description here

假设查询是13。要计算stringBeforeQueryWidth,我需要רחוב ישראל ישראלי的宽度和/5的宽度。我不能使用cellValue.Substring(0, cellValue.IndexOf(query))来检索它们,就像我只有一个方向时那样,因为רחוב ישראל ישראלי在查询之前出现,而/5在查询之后出现。

enter image description here

那么如何获得位于查询右侧的字符串部分的宽度?

c# string winforms right-to-left left-to-right
1个回答
1
投票

注意:这不是问题的直接答案。这是另一种选择。

作为选项,您可以在HTML表格中显示搜索结果并将其显示在WebBrowser控件中,并使用javascript突出显示搜索文本。

要将搜索结果显示为HTML,我将使用T4运行时文本模板。通过这种方式,我可以将数据传递给html模板,并通过将模板的输出字符串分配给DocumentText控件的WebBrowser属性来轻松呈现报表。我已经用这个想法来创建简单快速的打印文档,例如看看this post

要突出显示文本,您可以使用一些JavaScript代码或插件。例如,你可以看看this post

以下是我将在这篇文章中分享的示例的结果:

enter image description here

  1. 创建一个Form并放下一个WebBrowser控件和一个ToolStrip控件,就像你在上面的图片中看到的那样。
  2. 将以下.cs文件添加到项目中,并将以下代码粘贴到文件中: namespace Sample { public class ReportModel { public string RTL { get; set; } public string LTR { get; set; } } }
  3. 将新的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>
  4. 处理表单的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 متن" } , }; }
  5. 处理搜索按钮和搜索的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(); }
  6. 处理DocumentCompletedWebBrowser事件并调用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 }); }
  7. 运行应用程序并在文本框中键入123,然后按搜索按钮查看结果。
© www.soinside.com 2019 - 2024. All rights reserved.