1

我有一个关于 windows-phone 本地化资源的问题。

假设我的资源文件中有一个字符串,它应该如下所示:

这是一些文字。这个值是粗体的。这个是斜体的。

所有这些都存储在一个字符串字段中。我如何在资源本身中定义粗体或斜体等文本样式?我知道,我可以预定义一些自定义字体,如下所示:

<FontFamily x:Key="CustomBold">...</FontFamily>

然后添加就像{StaticResource CustomBold}在页面中一样,但如果字符串字段中的整个文本都是粗体,这可能是一个解决方案。如果我想在短语中间加粗一个单词怎么办?


我想使用原生 c# 风格的资源(即字符串名称 -> 字符串值),而不是编写不同的实现。

4

2 回答 2

3

当我在 iOS 上需要这样的东西时,我已经实现了非常基本的类似 BBCode 的标记语言,只有几个标签:“[b]”、“[/b]”、“[[”和“]]”(在我的项目我什至不需要斜体,只需要粗体)。

但是,.NET 没有我用来解析语法的 NSScanner 类的模拟。相反,它对解析 XML 数据有更好的支持。因此,在 WP7 上实现一个非常基本的 XML 子集会更容易,只支持 <b> 和 <i> 标签。有关示例代码,请参见本页末尾。

以下是如何将格式化的文本片段添加到 WP7 TextBlock 中。

更新:好的,这是适合您的完整解决方案:

[Flags]
enum eParseState: byte
{
    bold = 1,
    italic = 2,
}

// Sample input: "<txt>This is <i>some</i> text. <b>This value is <i>bold</i>.</b> This one is not.</txt>"
static void parseRichText( TextBlock tb, string xml )
{
    tb.Inlines.Clear();
    XmlReader reader = XmlReader.Create( new StringReader( xml ), new XmlReaderSettings() { ConformanceLevel=ConformanceLevel.Fragment } );
    eParseState state = 0;

    var names = new Dictionary<string, eParseState>()
    {
        { "b", eParseState.bold },
        { "i", eParseState.italic },
    };

    Action<bool> actElement = ( bool isOpening ) =>
    {
        string name = reader.Name.ToLower();
        eParseState flag;
        if( !names.TryGetValue( name, out flag ) ) return;
        if( isOpening )
            state |= flag;
        else
            state &= ( ~flag );
    };

    while( reader.Read() )
    {
        switch( reader.NodeType )
        {
            case XmlNodeType.Element:
                actElement( true );
                break;
            case XmlNodeType.EndElement:
                actElement( false );
                break;
            case XmlNodeType.Text:
                var run = new Run() { Text = reader.Value };
                if( 0 != ( state & eParseState.bold ) ) run.FontWeight = FontWeights.Bold;
                if( 0 != ( state & eParseState.italic ) ) run.FontStyle = FontStyles.Italic;
                tb.Inlines.Add( run );
                break;
        }
    }
}
于 2012-11-26T14:12:23.720 回答
0

好...

我找到了一个解决方案,但它看起来很笨拙。

应该使用的控件是RichTextBox

在 Windows Phone 中 RichTextBox 的工作方式与在本机 .Net 中有所不同

要为部分文本设置不同的样式,我们必须划分我们的单个字符串:

所以,让我们想象一下,我们在 Resources 中有一个字符串字段:

这是一些文字。这个值是粗体的。这个不是。

将它分成三个字符串(是的,这真的很笨拙):

  1. 这是一些文字。
  2. 这个值是粗体的
  3. 这个不是。

然后,在代码中我们使用 RichTextBox rtb

            Paragraph paragraph = new Paragraph();
            Bold bold = new Bold();
            bold.Inlines.Add(new Run() { Text = _string2FromResources });

            Run run = new Run();
            run.Text = _string1FromResources;
            Run run2 = new Run();
            run2.Text = _string3FromResources;

            paragraph.Inlines.Add(run); 
            paragraph.Inlines.Add(bold);
            paragraph.Inlines.Add(run2);

            rtb.Blocks.Add(paragraph);

那真的会奏效。但是实施的质量......嗯,你明白了。因此,如果有人可以添加更好的解决方案示例,我将不胜感激。

于 2012-11-28T07:55:58.077 回答