我知道可以使用 C# 代码和 XAML 标记来格式化 TextBlock 元素的文本(斜体、粗体、下划线等),这非常方便。这是来自 MSDN 站点的示例。
<TextBlock FontFamily="Arial">
<Run Foreground="Blue" FontWeight="Light" Text="This text demonstrates "></Run>
<Span FontWeight="SemiBold">
<Run FontStyle="Italic">the use of inlines </Run>
<Run Foreground="Red">with formatting.</Run>
</Span>
</TextBlock>
但问题是我无法在 XAML 标记中执行此操作,因为文本将在单击按钮时更新,而且文本量很大。我必须在 C# 代码中执行此操作,但我又无法手动调整每一行,因为确实有很多文本。我已经提前准备好了,标签已经以这种风格写在那里:
“WinUI 3 将 WinRT XAML 从操作系统中{b}解耦{/b}为一个单独的...”
之前,我在 RenPy 中使用了此文本,这些标签由引擎处理。我想在WinUI 3中实现同样的目标。将标签本身更改为其他标签对我来说并不困难,但无论如何,我想实现即时解析这些标签和文本的效果是根据这些标签进行修改的。是否有可能以某种方式实现这种行为?或者也许还有一些替代方案?请告诉我对此可以采取什么措施。
当然,我想到了编写一些算法来解析标签并将其内容包装在必要的类中,例如粗体,斜体,下划线等。但是如何实现它,我不知道
您可以使用
RichTextBlock
。像这样的东西应该有效:
<Grid ColumnDefinitions="*,*">
<TextBox
Grid.Column="0"
VerticalAlignment="Top"
Text="WinUI 3 {b}decouples{/b} WinRT XAML from the {i}operating system{/i} as a separate..."
TextChanged="InputTextBox_TextChanged" />
<RichTextBlock
x:Name="OutputRichTextBlock"
Grid.Column="1" />
</Grid>
private static IEnumerable<string> TokenizeString(string input)
{
List<string> tokens = new();
string pattern = @"(\{[^{}]*\})";
Regex regex = new(pattern);
MatchCollection matches = regex.Matches(input);
int lastIndex = 0;
foreach (Match match in matches.Cast<Match>())
{
if (match.Index > lastIndex)
{
tokens.Add(input[lastIndex..match.Index]);
}
tokens.Add(match.Value);
lastIndex = match.Index + match.Length;
}
if (lastIndex < input.Length)
{
tokens.Add(input[lastIndex..]);
}
return tokens;
}
private void InputTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (sender is not TextBox senderTextBox)
{
return;
}
FontWeight fontWeight = FontWeights.Normal;
FontStyle fontStyle = FontStyle.Normal;
Paragraph paragraph = new();
foreach (string token in TokenizeString(senderTextBox.Text))
{
if (token == "{b}" || token == "{/b}")
{
fontWeight = token == "{b}" ? FontWeights.Bold : FontWeights.Normal;
continue;
}
if (token == "{i}" || token == "{/i}")
{
fontStyle = token == "{i}" ? FontStyle.Italic : FontStyle.Normal;
continue;
}
Run run = new()
{
Text = token,
FontWeight = fontWeight,
FontStyle = fontStyle,
};
paragraph.Inlines.Add(run);
}
this.OutputRichTextBlock.Blocks.Add(paragraph);
}