C# 字符串格式和格式化字符串

C# 字符串格式和格式化字符串,c#,xamarin.forms,string-formatting,C#,Xamarin.forms,String Formatting,我正在尝试格式化一个字符串,比如说 “你好,乔治,你好吗?” 我只想要红色的“乔治”。有什么方法可以同时使用String.Format和FormattedString吗 我尝试使用: var text = new FormattedString(); text.Spans.Add(new Span { Text = Localize.GetString("irs", String.Empty), ForegroundColor = Colors.RedColor }); l

我正在尝试格式化一个字符串,比如说

“你好,乔治,你好吗?”

我只想要红色的“乔治”。有什么方法可以同时使用
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)

首先,让我们实现intercept provider,它将把
字符串.Format
的输出转换为
Span
(s):

最后是一个助手方法,它将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;
    }
用法: 或者


如果我使用span结束它的工作正常,我会尝试将该fomatiig添加到中间,我的问题是是否有任何选项,不使用HTML渲染,您可以使用自定义渲染器并在iOS中设置AttributedString,在Android中设置spannablesting。
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>";
    }
    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();