2017-01-24 1 views
0

UWP 앱에서 일부 콘텐츠로 채워지는 RichTextBlock을 사용하고 있습니다. 단어 줄 바꿈 기능이 설정되어 있고 내용의 길이에 관계없이 특정 수의 서식있는 텍스트 만 표시 할 수 있도록 최대 줄이 설정되어 있습니다.RichTextBlock에서 보이는 텍스트 가져 오기

보이는 텍스트가 무엇인지 알아낼 방법이 있는지 알고 싶습니다.

그래서 내가있는 경우 :

<RichTextBlock TextWrapping="Wrap" MaxLines="2"> 
    <RichTextBlock.Blocks> 
     <Paragraph> 
      <Paragraph.Inlines> 
       A bunch of runs go in here with text that are several lines 
      </Paragraph.Inlines> 
     </Paragraph> 
    </RichTextBlock.Blocks> 
</RichTextBlock> 

실제로 볼 얼마나 텍스트의 많은 알고 싶습니다.

텍스트가 설정된 줄 수보다 길고 마지막 줄 끝에 "... 자세히보기"를 추가하려고합니다 (마지막 13자를 "...로 바꿉니다. Read More ")

+0

:

여기에 (당신이 필요로하는 다른 유형을 처리하기 위해 수정해야하므로에만 실행 및 하이퍼 링크 인라인을 처리) 내 코드입니까? "..."괜찮겠습니까? – Scavenger

+0

네, "... 더 읽기"여야합니다. 그렇지 않으면 TextTrimming = CharacterEllipsis를 사용했을 것입니다. 불행히도 TextTrimming을 사용할 때 "..."대신 사용할 사용자 지정 텍스트를 제공하는 방법이 없습니다. 내 문제를 해결했을거야. –

답변

1

그래서 내가 원하는 동작을 얻기 위해 코드를 작성했지만, 불행히도 이것은 느리고 비효율적입니다. 따라서 많은 텍스트를 많이 포함하는 ListView와 같이 잘릴 필요가있는 텍스트를 주로 표시하는 앱에서이 텍스트를 사용하는 경우 앱 퍼포먼스가 느려집니다. 나는 아직도 이것을하기위한 더 좋은 방법이 있는지 알고 싶다. 당신은 "자세히보기 ..."사용할 필요가

private static void TrimText_Slow(RichTextBlock rtb) 
{ 
    var paragraph = rtb?.Blocks?.FirstOrDefault() as Paragraph; 
    if (paragraph == null) { return; } 

    // Ensure RichTextBlock has passed a measure step so that its HasOverflowContent is updated. 
    rtb.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); 
    if (rtb.HasOverflowContent == false) { return; } 


    // Start from end and remove all inlines that are not visible 
    Inline lastInline = null; 
    var idx = paragraph.Inlines.Count - 1; 
    while (idx >= 0 && rtb.HasOverflowContent) 
    { 
     lastInline = paragraph.Inlines[idx]; 
     paragraph.Inlines.Remove(lastInline); 
     idx--; 
     // Ensure RichTextBlock has passed a measure step now with an inline removed, so that its HasOverflowContent is updated. 
     rtb.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); 
    } 

    // The last inline could be partially visible. The easiest thing to do here is to always 
    // add back the last inline and then remove characters from it until everything is in view. 
    if (lastInline != null) 
    { 
     paragraph.Inlines.Add(lastInline); 
    } 

    // Make room to insert "... Read More" 
    DeleteCharactersFromEnd(paragraph.Inlines, 13); 

    // Insert "... Continue Reading" 
    paragraph.Inlines.Add(new Run { Text = "... " }); 
    paragraph.Inlines.Add(new Run { Text = "Read More", Foreground = new SolidColorBrush(Colors.Blue) }); 

    // Ensure RichTextBlock has passed a measure step now with the new inlines added, so that its HasOverflowContent is updated. 
    rtb.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); 

    // Keep deleting chars until "... Continue Reading" comes into view 
    idx = paragraph.Inlines.Count - 3; // skip the last 2 inlines since they are "..." and "Read More" 
    while (idx >= 0 && rtb.HasOverflowContent) 
    { 
     Run run; 

     if (paragraph.Inlines[idx] is Hyperlink) 
     { 
      run = ((Hyperlink)paragraph.Inlines[idx]).Inlines.FirstOrDefault() as Run; 
     } 
     else 
     { 
      run = paragraph.Inlines[idx] as Run; 
     } 

     if (string.IsNullOrEmpty(run?.Text)) 
     { 
      paragraph.Inlines.Remove(run); 
      idx--; 
     } 
     else 
     { 
      run.Text = run.Text.Substring(0, run.Text.Length - 1); 
     } 

     // Ensure RichTextBlock has passed a measure step now with the new inline content updated, so that its HasOverflowContent is updated. 
     rtb.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); 
    } 
} 

private static void DeleteCharactersFromEnd(InlineCollection inlines, int numCharsToDelete) 
{ 
    if (inlines == null || inlines.Count < 1 || numCharsToDelete < 1) { return; } 

    var idx = inlines.Count - 1; 

    while (numCharsToDelete > 0) 
    { 
     Run run; 

     if (inlines[idx] is Hyperlink) 
     { 
      run = ((Hyperlink)inlines[idx]).Inlines.FirstOrDefault() as Run; 
     } 
     else 
     { 
      run = inlines[idx] as Run; 
     } 

     if (run == null) 
     { 
      inlines.Remove(inlines[idx]); 
      idx--; 
     } 
     else 
     { 
      var textLength = run.Text.Length; 
      if (textLength <= numCharsToDelete) 
      { 
       numCharsToDelete -= textLength; 
       inlines.Remove(inlines[idx]); 
       idx--; 
      } 
      else 
      { 
       run.Text = run.Text.Substring(0, textLength - numCharsToDelete); 
       numCharsToDelete = 0; 
      } 
     } 
    } 
} 
관련 문제