4
속성에 연결된 TextBlock이 있습니다. 그러나 나는 텍스트 안에서 특정 단어를 대담하게하고 싶다. 가장 쉬운 방법은 무엇입니까? 참고로 저는 WPF를 처음 사용합니다.바운드 TextBlock의 부분을 어떻게 굵게 표시합니까?
속성에 연결된 TextBlock이 있습니다. 그러나 나는 텍스트 안에서 특정 단어를 대담하게하고 싶다. 가장 쉬운 방법은 무엇입니까? 참고로 저는 WPF를 처음 사용합니다.바운드 TextBlock의 부분을 어떻게 굵게 표시합니까?
개별 단어를 묶는 것은 실제로 더 많은 인라인 요소를 만드는 것과 관련되어 있으므로 문자열을 TextBlock의 텍스트에 바인딩하고 수행 할 수는 없습니다.
내가 과거에해온 것은 내가 바인딩하는 사용자 정의 속성이있는 TextBlock의 하위 클래스를 만든 것입니다. 이 속성이 바인딩되면 기본 TextBlock의 인라인을 지운 다음 일반 문자열, 굵게, 하이퍼 링크 등을 만드는 새 문자열 값을 구문 분석하는 알고리즘을 사용합니다.
실험용 Twitter 클라이언트에 대해 작성한 몇 가지 샘플 코드는 다음과 같습니다 URL, 이메일 및 @ 패턴을 탐지하고 그들에 대한 하이퍼 링크를 생성합니다. 일반 텍스트는 보통 실행으로 인라인됩니다.
[ContentProperty("StatusText")]
public sealed class StatusTextBlock : TextBlock
{
#region Fields
public static readonly DependencyProperty StatusTextProperty = DependencyProperty.Register(
"StatusText",
typeof(string),
typeof(StatusTextBlock),
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.None, StatusTextBlock.StatusTextPropertyChangedCallback, null));
private static readonly Regex UriMatchingRegex = new Regex(@"(?<url>[a-zA-Z]+:\/\/[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,5}(:[0-9]{1,5})?([a-zA-Z0-9_\-\.\~\%\+\?\=\&\;\|/]*)?)|(?<emailAddress>[^\s][email protected][a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,5})|(?<toTwitterScreenName>\@[a-zA-Z0-9\-_]+)", RegexOptions.Compiled);
#endregion
#region Constructors
public StatusTextBlock()
{
}
#endregion
#region Type specific properties
public string StatusText
{
get
{
return (string)this.GetValue(StatusTextBlock.StatusTextProperty);
}
set
{
this.SetValue(StatusTextBlock.StatusTextProperty, value);
}
}
#endregion
#region Helper methods
internal static IEnumerable<Inline> GenerateInlinesFromRawEntryText(string entryText)
{
int startIndex = 0;
Match match = StatusTextBlock.UriMatchingRegex.Match(entryText);
while(match.Success)
{
if(startIndex != match.Index)
{
yield return new Run(StatusTextBlock.DecodeStatusEntryText(entryText.Substring(startIndex, match.Index - startIndex)));
}
Hyperlink hyperLink = new Hyperlink(new Run(match.Value));
string uri = match.Value;
if(match.Groups["emailAddress"].Success)
{
uri = "mailto:" + uri;
}
else if(match.Groups["toTwitterScreenName"].Success)
{
uri = "http://twitter.com/" + uri.Substring(1);
}
hyperLink.NavigateUri = new Uri(uri);
yield return hyperLink;
startIndex = match.Index + match.Length;
match = match.NextMatch();
}
if(startIndex != entryText.Length)
{
yield return new Run(StatusTextBlock.DecodeStatusEntryText(entryText.Substring(startIndex)));
}
}
internal static string DecodeStatusEntryText(string text)
{
return text.Replace(">", ">").Replace("<", "<");
}
private static void StatusTextPropertyChangedCallback(DependencyObject target, DependencyPropertyChangedEventArgs eventArgs)
{
StatusTextBlock targetStatusEntryTextBlock = (StatusTextBlock)target;
targetStatusEntryTextBlock.Inlines.Clear();
string newValue = eventArgs.NewValue as string;
if(newValue != null)
{
targetStatusEntryTextBlock.Inlines.AddRange(StatusTextBlock.GenerateInlinesFromRawEntryText(newValue));
}
}
#endregion
}
이 방법으로 텍스트의 색상을 다르게 지정할 수 있습니까? –
물론, Run 인스턴스의 Foreground 속성을 원하는 브러시로 설정하면됩니다. –
같은 종류의 텍스트 상자를 시도한 적있으세요? 텍스트 상자에는 인라인 속성이 없으므로 텍스트 상자를 사용해야합니다. –