Ширина строки справа от точки в двунаправленном тексте
* Извините, если название не велико. Я не уверен, как обобщить этот вопрос в несколько слов.
у меня есть 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
приходит после запроса.
Так, как я могу получить ширину части строки, которая расположена справа от запроса?
1 ответ
Примечание: это не прямой ответ на вопрос. Это альтернатива.
Как вариант, вы можете отобразить результат поиска в таблице HTML и отобразить его в WebBrowser
контролировать и выделять текст поиска с помощью JavaScript.
Чтобы отобразить результат поиска в формате HTML, я буду использовать текстовые шаблоны времени выполнения T4. Таким образом, я могу передать данные в шаблон HTML и легко отобразить отчет, назначив выходную строку шаблона DocumentText
собственность WebBrowser
контроль. Я использовал эту идею для создания простого и быстрого документа для печати, например, посмотрите на этот пост.
Чтобы выделить текст, вы можете использовать некоторый код JavaScript или плагины. Например, вы можете взглянуть на этот пост.
Вот результат примера, которым я поделюсь в этом посте:
пример
Создать
Form
и бросьWebBrowser
контроль иToolStrip
контролировать его, как то, что вы видите на изображении выше.Добавьте следующее
.cs
файл в проект и вставьте следующий код в файл:namespace Sample { public class ReportModel { public string RTL { get; set; } public string LTR { get; set; } } }
Добавить новый
RunTime Text Template
пункт к проекту и назовите егоReportTemplate.tt
, Откройте файл и вставьте следующий контент. Здесь я использовал этот плагин, чтобы выделить текст. И передал модель в шаблон 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
объект и вызовhighlight
Функция JavaScript, которую мы уже создали в HTML:private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { var txt = searchTextBox.Text; if (!string.IsNullOrEmpty(txt)) webBrowser1.Document.InvokeScript("highlight", new object[] { txt }); }
Запустите приложение и введите
123
в текстовом поле и нажмите кнопку поиска, чтобы увидеть результат.