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에서는 형식 텍스트 대신 이러한 형상 객체를 렌더링 할 수 있습니다.

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++;
        }

도움이 되었기를 바랍니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top