Problem:
I have WPF TextBlock with dynamically changed text. This text contains words that are color names.
For example:
MyTextBlock.Text = "This is some dynamic text that contains red, green and yellow words inside it.";
Result should be rendered so all "red", "green" and "yellow" words are formatted with their color.
You can take benefit from Inline
collection property inside TextBlock
to customize the content and set it dynamically..
<TextBlock
x:Name="MyTextBlock"
Height="100"
Padding="8"
FontSize="18"
TextWrapping="Wrap" />
You would do something like this in code behind..
{
InitializeComponent();
var input = "This is some dynamic text that contains Red and green and yellow words inside it.";
UpdateTextBoxWithColoredText(MyTextBlock, input, _colors);
}
Where UpdateTextBoxWithColoredText
is
private void UpdateTextBoxWithColoredText(TextBlock textBlock,
string input, List<string> colors)
{
// textBlock.Text = ""; // empty the current text if needed
var list = input
.Split(' ')
.ToList();
var stringBuilder = new StringBuilder();
foreach (var currentString in list)
{
if (colors.Contains(currentString.ToLower()))
{
textBlock.Inlines.Add($"{stringBuilder} ");
stringBuilder.Clear();
var run = new Run(currentString)
{
Foreground = ColorName2Brush(currentString.ToLower())
};
textBlock.Inlines.Add(run);
}
else
stringBuilder.Append(currentString);
textBlock.Inlines.Add(" ");
}
textBlock.Inlines.Add(stringBuilder.ToString());
}
private readonly List<string> _colors = new() { "red", "green", "yellow" };
private Brush ColorName2Brush(string colorName) =>
colorName switch
{
"green" => ToSolidColorBrush("#00FF00"),
"yellow" => ToSolidColorBrush("#FFFF00"),
"red" => ToSolidColorBrush("#FF0000"),
_ => ToSolidColorBrush("#000000")
};
private SolidColorBrush ToSolidColorBrush(string hex)
{
try
{
return (SolidColorBrush)new BrushConverter().ConvertFrom(hex);
}
catch (Exception)
{
return (SolidColorBrush)new BrushConverter().ConvertFrom("#000000");
}
}
Sample output
Note: punctuations are not handled in the solution above, also linebreaks (you can do textblock.Inlines.Add(new LineBreak());
or stringBuilder.AppendLine();
), this is sort of string processing that you can do it in your behalf :)