업데이트 : 원래는 RichTextBox
이 아니라 TextBlock
에 대해 이야기하고 있었던 것 같습니다. 솔루션에 RichTextBox
이 절대적으로 필요한 경우 어딘가에서 유용한 RTF 파서를 찾아야합니다.
할 수있는 한 가지는 RTF 또는 HTML 컨트롤을 사용하는 것입니다.
또는 다음 코드를 사용하여 머리에 총을 썼습니다 (실제로 내가 할 수 있는지 알아보기 위해 썼습니다). 아마 MVVM에 대한 죄이지만, 눈을 감고 <Bold>
태그 등은 XAML이 아닌 임의의 마크 업 언어 일뿐입니다.
아무튼 : 서식을 지정할 범위가 변경되면 FormattedText
속성을 업데이트하고 PropertyChanged
을 올립니다.
C#
namespace HollowEarth.AttachedProperties
{
public static class TextProperties
{
#region TextProperties.XAMLText Attached Property
public static String GetXAMLText(TextBlock obj)
{
return (String)obj.GetValue(XAMLTextProperty);
}
public static void SetXAMLText(TextBlock obj, String value)
{
obj.SetValue(XAMLTextProperty, value);
}
/// <summary>
/// Convert raw string into formatted text in a TextBlock:
///
/// @"This <Bold>is a test <Italic>of the</Italic></Bold> text."
///
/// Text will be parsed as XAML TextBlock content.
///
/// See WPF TextBlock documentation for full formatting. It supports spans and all kinds of things.
///
/// </summary>
public static readonly DependencyProperty XAMLTextProperty =
DependencyProperty.RegisterAttached("XAMLText", typeof(String), typeof(TextProperties),
new PropertyMetadata("", XAMLText_PropertyChanged));
// I don't recall why this was necessary; maybe it wasn't.
public static Stream GetStream(String s)
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
private static void XAMLText_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TextBlock)
{
var ctl = d as TextBlock;
try
{
// XAML needs a containing tag with a default namespace. We're parsing
// TextBlock content, so make the parent a TextBlock to keep the schema happy.
// TODO: If you want any content not in the default schema, you're out of luck.
var strText = String.Format(@"<TextBlock xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">{0}</TextBlock>", e.NewValue);
TextBlock parsedContent = System.Windows.Markup.XamlReader.Load(GetStream(strText)) as TextBlock;
// The Inlines collection contains the structured XAML content of a TextBlock
ctl.Inlines.Clear();
// UI elements are removed from the source collection when the new parent
// acquires them, so pass in a copy of the collection to iterate over.
ctl.Inlines.AddRange(parsedContent.Inlines.ToList());
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(String.Format("Error in HollowEarth.AttachedProperties.TextProperties.XAMLText_PropertyChanged: {0}", ex.Message));
throw;
}
}
}
#endregion TextProperties.XAMLText Attached Property
}
}
다른 C#을
// This `SpanStyle` resource is in scope for the `TextBlock` I attached
// the property to. This works for me with a number of properties, but
// it's not changing the foreground. If I apply the same style conventionally
// to a Span in the real XAML, the foreground color is set. Very curious.
// StaticResource threw an exception for me. I couldn't figure out what to give
// XamlReader.Load for a ParserContext.
FormattedText = "Text <Span Style=\"{DynamicResource SpanStyle}\">Span Text</Span>";
XAML
<TextBlock
xmlns:heap="clr-namespace:HollowEarth.AttachedProperties"
heap:TextProperties.XAMLText="{Binding FormattedText}"
/>
<TextBlock
xmlns:heap="clr-namespace:HollowEarth.AttachedProperties"
heap:TextProperties.XAMLText="This is <Italic Foreground="Red">italic and <Bold>bolded</Bold></Italic> text"
/>
은 이미지와 설명하려고합니다. RTB에서 이미 텍스트 선택을 이동하는 것이 가능합니다. – AnjumSKhan