Каков хороший способ выполнить проверку попадания в FormattedText?

StackOverflow https://stackoverflow.com/questions/540002

  •  22-08-2019
  •  | 
  •  

Вопрос

Я визуализирую текст, используя FormattedText, но, похоже, существует какой-либо способ выполнить посимвольное тестирование попаданий на визуализированном выводе.Он доступен только для чтения, поэтому мне нужно только выделение, а не редактирование.

я бы использовал RichTextBox или что-то подобное, но мне нужно выводить текст на основе управляющих кодов, встроенных в сам текст, поэтому они не всегда вложены, что делает построение правильных встроенных элементов очень сложным.Меня также немного беспокоит производительность этого решения;У меня большое количество строк, и новые строки добавляются часто.

я посмотрел GlyphRun, похоже, я мог бы провести тестирование на попадание из него или связанного с ним класса, но мне пришлось бы переопределить множество функций, и кажется, что должен быть более простой способ...

Кто-нибудь знает хороший способ реализовать это?

Это было полезно?

Решение

Лучший способ — разработать хорошую структуру данных для хранения вашего текста, которая также учитывает проверку попадания.Одним из примеров может быть разделение текста на блоки (слова, строки или абзацы в зависимости от того, что вам нужно).Тогда каждый такой блок должен иметь ограничивающую рамку, которая должна пересчитываться при любых операциях форматирования.Также учитывайте положение кареток в своем дизайне.

Если у вас есть такая возможность, проводить тестирование попадания становится очень легко, просто используйте ограничивающие рамки.Это также поможет в последующих операциях, таких как выделение определенной части текста.

Другие советы

Вы можете получить геометрию каждого символа из объекта FormattedText и использовать границы каждого символа для проверки попадания.

var geometry = (GeometryGroup)((GeometryGroup)text.BuildGeometry(new Point(0, 0))).Children[0];
foreach (var c in geometry.Children)
{
  if (c.Bounds.Contains(point))
    return index;
  index++;
}

В OnRender вы можете визуализировать эти геометрические объекты вместо форматированного текста.

Полностью согласен с Сешем - самый простой способ избежать повторной реализации всей нагрузки функциональности FormattedText - это разделить отдельные элементы, которые вы хотите проверить на попадание, на их собственные элементы управления/встроенные строки.

Рассмотрите возможность использования TextBlock и добавления каждого слова как отдельного Inline ( или ), а затем либо привяжите его к свойству Inline IsMouseDirectlyOver, либо добавьте делегатов к событиям MouseEnter и MouseLeave.

Если вы хотите провести проверку попадания реальных глифов на уровне пикселей (т.находится ли мышь точно в точке этого «i»), тогда вам нужно будет использовать GlyphRuns и выполнить ручную проверку нажатия на глифы (читай:тяжелая работа).

Я очень опоздал на вечеринку — если вечеринка еще не закончилась и вам не нужна фактическая геометрия персонажа, я нашел что-то вроде этого полезным:

 for (int i = 0; i < FormattedText.Text.Length; i++)
 {
            characterHighlightGeometry = FormattedText.BuildHighlightGeometry(new Point(), i, 1);
            CharacterHighlightGeometries.Children.Add(characterHighlightGeometry);
 }

BuildGeometry() включает только фактическую геометрию пути персонажа.Buildhighlightgeometry () генерирует внешние границы всех символов, в том числе пространства, поэтому индекс в пространстве может быть расположен путем:

 foreach (var c in CharacterHighlightGeometries.Children)
        {
            if (c.Bounds.Contains(centerpoint))
            {
                q = c;
                cpos = index;
                break;
            }
            index++;
        }

Надеюсь это поможет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top