FormattedText에서 히트 테스트를 수행하는 좋은 방법은 무엇입니까?
문제
나는 텍스트를 사용하고 있습니다 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에서는 형식 텍스트 대신 이러한 형상 객체를 렌더링 할 수 있습니다.
SESH와 완전히 동의하십시오-형식의 전체로드를 재 구현하지 않으면 서 빠져 나가는 가장 쉬운 방법은 테스트를 원하는 개별 항목을 자신의 컨트롤/인라인으로 나누는 것입니다.
텍스트 블록을 사용하고 각 단어를 자체 인라인 (또는)으로 추가 한 다음 인라인의 ismousedirectallyVerover 속성에 바인딩하고, 마우스 센터 및 Mouseleave 이벤트에 대의원을 추가하십시오.
실제 글리프의 픽셀 레벨 히트 테스트를 원한다면 (즉,이 'I'의 점에 정확히 마우스입니다) 글리프 런을 사용하고 글리프에서 수동 히트 테스트를 수행해야합니다 (읽기 : Hard. 일하다).
파티에 매우 늦었습니다. 파티가 끝나지 않았고 실제 캐릭터 지오메트리가 필요하지 않으면 이와 같은 유용한 것을 발견했습니다.
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++;
}
도움이 되었기를 바랍니다.