本地化资源中的文本样式
我对windows-phone的本地化资源有疑问。
比方说,我的Resources文件中有一个字符串,它应该如下所示:
这是一些文字。 该值为粗体。 这个是斜体。
并且所有存储在单个字符串字段中。 我怎么能在参考资料本身中定义像粗体或斜体这样的文本样式? 我知道,我可以预定义一些自定义字体,如下所示:
...
然后在页面中添加为{StaticResource CustomBold}
,但如果字符串字段中的整个文本为粗体,则可以是解决方案。 如果我想在短语的中间加粗一个单词怎么办?
我想使用原生的c#-style Resources(即字符串名称 – >字符串值),而不是编写不同的实现。
当我需要这样的东西用于iOS时,我已经实现了非常基本的BBCode相似的标记语言,只有几个标签:“[b]”,“[/ b]”,“[[”和“]]”(在我的项目我甚至不需要斜体,只有粗体)。
但是,.NET没有我用来解析语法的NSScanner类的模拟。 相反,它对解析XML数据有更好的支持。 因此,在WP7上,只需支持和标记,就可以更轻松地实现XML的基本子集。 有关示例代码,请参见本页末尾。
以下是如何将格式化文本片段添加到WP7 TextBlock中。
更新:好的,这是完整的解决方案:
[Flags] enum eParseState: byte { bold = 1, italic = 2, } // Sample input: "This is some text. This value is bold. This one is not. " 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() { { "b", eParseState.bold }, { "i", eParseState.italic }, }; Action 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; } } }
好…
我找到了解决方案,但看起来很笨拙。
应该使用的控件是RichTextBox 。
在Windows Phone中,RichTextBox的工作方式与原生.Net相比有所不同
要为部分文本设置不同的样式,我们必须划分单个字符串:
所以,让我们想象一下,我们在Resources中有一个字符串字段:
这是一些文字。 该值为粗体 。 这个不是。
将它分成三个字符串(是的,这真的很笨拙):
- 这是一些文字。
- 该值为粗体
- 这个不是。
然后,在代码中我们使用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);
那真的有用。 但是实施的质量……嗯,你明白了。 所以我真的很感激,如果有人可以添加一个更好的解决方案的例子。