Вы можете использовать провайдера перехвата в string.Format
.
В иллюстративных целях я выбираю формат XAML в качестве выходного, а затем преобразую его в FormattedString
(но также можно использовать более сжатые форматы, такие как JSON).
Сначала давайте реализуем перехватпровайдер - который преобразует ваш string.Format
вывод в Span
(s):
public class InterceptProvider : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
else
return null;
}
public string Format(String format, Object obj, IFormatProvider provider)
{
string spanText;
// Use default for all other formatting.
if (obj is IFormattable)
spanText = ((IFormattable)obj).ToString(format, System.Globalization.CultureInfo.CurrentCulture);
else
spanText = obj.ToString();
return $"</Span><Span ForegroundColor=\"Red\">{spanText}</Span><Span>";
}
}
Добавьте метод расширения для интеграции перехватчика с string.Format
.
public static class FormatExtensions
{
static ColorTypeConverter _typeConverter = new ColorTypeConverter();
static InterceptProvider _interceptor = new InterceptProvider();
public static string InterceptFormat(this string sourceStr, params object[] args)
{
return $"<FormattedString><Span>{string.Format(_interceptor, sourceStr, args)}</Span></FormattedString>";
}
* 1015И, наконец, вспомогательный метод, который преобразует XAML в
FormattedString
объект.
public static FormattedString ToFormattedString(this string xamlStr)
{
var toReturn = new FormattedString();
if (string.IsNullOrWhiteSpace(xamlStr))
return toReturn;
Span span = null;
using(var strReader = new StringReader(xamlStr))
{
using(var xmlReader = XmlReader.Create(strReader))
{
while (xmlReader.Read())
{
if (xmlReader.IsStartElement())
{
switch (xmlReader.Name)
{
case "Span":
span = new Span();
while (xmlReader.MoveToNextAttribute())
{
switch (xmlReader.Name)
{
case "ForegroundColor":
var color = xmlReader.Value;
if (!string.IsNullOrEmpty(color))
span.ForegroundColor = (Color)_typeConverter.ConvertFromInvariantString(color);
break;
}
}
if (xmlReader.IsStartElement() || xmlReader.MoveToContent() == XmlNodeType.Element)
{
span.Text = xmlReader.ReadString();
toReturn.Spans.Add(span ?? new Span());
}
break;
}
}
}
}
}
return toReturn;
}
ИСПОЛЬЗОВАНИЕ:
label.FormattedText = Localize.GetString("instructions", String.Empty)
.InterceptFormat(text).ToFormattedString();
Или
lbl.FormattedText = "{0} It is now {1:d} at {1:t}"
.InterceptFormat("Morning!", DateTime.Now)
.ToFormattedString();