如果字体不支持符号,如何在WPF文本框中插入版权,商标,服务标记等

Ser*_*ioL 6 c# wpf textbox symbols

我们有一个WPF应用程序,显示包含各种公司符号的文本; 如商标,注册商标,版权和服务标志.

数据库包含一些包含标准公司符号的字段.最初,数据标记如下:

Example Corp(TM) or Example Plan (SM)

我们可以轻松地将占位符更改为各自的Unicode等价物; 实际上在大多数情况下都有.

我们遇到的问题是应用程序使用的字体不支持服务标记符号(它只是一个上标的SM).有可能我们无法替换字体或编辑它.

字段可以是带有符号末尾的简单产品名称,也可以是带有0次或更多次符号的长描述.我们将TextBoxes或Labels直接绑定到ViewModel和/或业务对象(通常通过DataTemplates).应用程序中的所有数据都是只读的.

所以,假设我们必须通过代码解决这个问题(在C#和WPF中),我的选择是什么?

Joe*_*ant 4

编辑:我在另一个答案中发现,TextBlock还有Inlines一个可以添加Runs 的集合。Anvaka 的答案巧妙地使用附加属性作为一种转换器。

\n\n
\n\n

关于如何解决这个问题,我有一些想法。只有一种可以正确处理自动换行并处理不同字体的字符运行。

\n\n

使用 aFlowDocumentScrollViewer并使用 a 将字符串绑定到它ValueConverter,将字符串转换为 a FlowDocument

\n\n
<FlowDocumentScrollViewer\n    HorizontalScrollBarVisibility="Hidden"\n    VerticalScrollBarVisibility="Hidden"\n    Document="{Binding MyString, Converter={StaticResource MyConverter}}" />\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以在转换器上创建属性来设置常规字体属性,这些属性不能在转换器上设置FlowDocumentScrollViewer,而必须在FlowDocument转换器创建的字体上设置。您可能还需要一些 Font 属性来表示需要不同 Font (并且可能不同大小)的异常子字符串。另一种选择是为其中一些属性创建Bindings ( )。FlowDocumentRelativeSource

\n\n

以下是FlowDocument在代码中创建的方法:

\n\n
FlowDocument doc = new FlowDocument();\ndoc.FontFamily = new FontFamily( "Our Own Font" );\nParagraph par = new Paragraph();\ndoc.Blocks.Add( par );\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后,您需要将传入的字符串拆分为特殊子字符串,同时保持这些子字符串完整。您必须滚动自己的拆分器,并在转换器中拥有一组子字符串或提供给转换器。

\n\n

将普通子字符串添加到段落中:

\n\n
Run r = new Run( substring );\npar.Inlines.Add( r );\n
Run Code Online (Sandbox Code Playgroud)\n\n

使用不同的字体向段落添加特殊的子字符串:

\n\n
Run r = new Run( substring );\nr.FontFamily = new FontFamily( "Arial" );\npar.Inlines.Add( r );\n
Run Code Online (Sandbox Code Playgroud)\n\n

以上只是一些小片段。我不知道你想如何分割字符串或迭代子字符串,因为我不熟悉数据,所以我没有提供我拼凑在一起的方法只是为了看看我的想法是否可行。您还可以使用 aDictionary来检测一个子字符串并在输出中使用替换,例如检测"(SM)"并将其替换为"\xe2\x84\xa0"

\n\n

如果您有任何问题或者有什么我可以详细说明的,请告诉我。

\n\n

(很好,你说它是只读的。 ARichTextBox不起作用,因为它的Document属性不是 a DependencyProperty,因此不能成为 a 的目标Binding。尽管如此,人们可能可以使用Mode=OneWayToSource它来反转它,实现ConvertBack代替Convert。)

\n\n
\n\n
\n

“我认为你遗漏的部分(迭代字符串并创建这些运行)是棘手的部分。”

\n
\n\n

关于将字符串拆分为特殊子字符串,我确实非常简短。当我说“我不知道你将如何分割字符串”时,我并不是说我根本不知道如何做到这一点(我重新表述了它),而是我不知道你如何分割字符串。会想要处理它。我认为你解决这个问题并不难,因为这是我会让潜在员工解决的那种字符串操作问题。您可能会发现数据中的边缘情况需要改变处理方式。

\n\n

我将向您描述一个使用IndexOf()和 的相对粗糙的版本Substring()

\n\n

所以这就是问题中的问题:你有很多字符串(例如"Company Name(R), makers of Product(TM)"),其中包含 0 个或多个特殊子字符串。这些子串很少且已知,并且输入字符串需要分成几个字符串,其中特殊子串和非特殊子串已彼此隔离(例如,{"Company Name", "(R)", ", makers of Product", "(TM)"})。

\n\n

特殊子字符串很少且已知,因此您需要一个包含这些子字符串的数组。您可以通过返回值知道.IndexOf()是否找到子字符串。循环遍历已知的特殊子字符串,您可以通过索引比较找到其中任何一个的第一个实例,同时也保留子字符串的长度。

\n\n

每次在字符串(如果有)中找到最早的特殊子字符串时S,都会生成派生字符串ABCB是特殊子串,AC之前和之后。A将and附加B到 a 后ListC就会成为新的S,然后再重复一次。除非您发现其中没有特殊子字符串S并且它不为空,在这种情况下您只需将其整个附加即可。

\n\n

现在,每个奇数索引字符串都是List一个特殊的子字符串。您可能需要参考我Dictionary在本答案的前一部分中提到的 a ,以用作查找,以在您找到的子字符串为 时Run添加a 。"\xe2\x84\xa0""(SM)"

\n