c# - 字符串格式和格式化字符串
问题描述
我正在尝试格式化字符串让我们说
“你好,乔治,你好吗?”
我只想要红色的“乔治”。有什么办法可以并排使用String.Format
吗FormattedString
?
我尝试使用:
var text = new FormattedString();
text.Spans.Add(new Span {
Text = Localize.GetString("irs", String.Empty),
ForegroundColor = Colors.RedColor
});
label.FormattedText = String.Format(
Localize.GetString("instructions", String.Empty),
text
);
但是,这不起作用。有什么正确的方法可以实际做到这一点。我想要本地化,所以我不想将文本拆分为多个本地化字符串。
解决方案
您可以在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>";
}
FormattedString
最后是一个将 XAML 转换为对象的辅助方法。
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();
推荐阅读
- node.js - express.js 项目中的 CORS 问题
- angular7 - Angular 6 无法使用本地参考禁用启用输入
- php - 使用 mysql_data_seek 时 PHP Extra 1 空行
- python - 如何在 Python 中使用 Paramiko 时使 EllipticCurvePublicNumbers.encode_point CryptographyDeprecationWarning 静音
- excel - Excel 条件格式 - 间接地址公式
- javascript - 如何不将点击事件传递给响应的孩子?
- tensorflow - Keras:带有 predict_generator 的混淆矩阵
- php - Laravel / Blade:标签/空格未正确包含
- c# - 为什么我的 Unity 项目会失去与 Git 的脚本和资产的连接?
- javascript - 为什么 SpeechSynthesisUtterance 有时不会在基于 Chromium 的浏览器中触发“结束”事件?