Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Edit: I discovered in a different answer that the <code>TextBlock</code> also has an <code>Inlines</code> collection to which one can add <code>Run</code>s. <a href="https://stackoverflow.com/questions/2290812/wpf-display-formatted-multiline-text-using-data-binding/2290905#2290905">Anvaka's answer</a> ingeniously uses an attached property as a sort of converter.</p> <hr> <p>I had a couple ideas about how to approach this. Only one would handle word wrap correctly and handle character runs with different fonts.</p> <p>Use a <code>FlowDocumentScrollViewer</code> and bind the string to it using a <code>ValueConverter</code> that converts the string to a <code>FlowDocument</code>.</p> <pre><code>&lt;FlowDocumentScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" Document="{Binding MyString, Converter={StaticResource MyConverter}}" /&gt; </code></pre> <p>You can create properties on the converter to set the regular Font properties, which can't be set on the <code>FlowDocumentScrollViewer</code> and has to be set on the <code>FlowDocument</code> that the converter creates. You'll probably also need some Font properties for the exception substrings that need a different Font (and possibly different size). Another option is to create <code>Binding</code>s on the <code>FlowDocument</code> for some of those properties (<code>RelativeSource</code>).</p> <p>And here's how you create a <code>FlowDocument</code> in code:</p> <pre><code>FlowDocument doc = new FlowDocument(); doc.FontFamily = new FontFamily( "Our Own Font" ); Paragraph par = new Paragraph(); doc.Blocks.Add( par ); </code></pre> <p>Then you'll need to split the incoming string on the special substrings while keeping those substrings intact. You'll have to roll your own splitter and have a collection of substrings in the converter or supplied to the converter.</p> <p>Add a normal substring to the paragraph:</p> <pre><code>Run r = new Run( substring ); par.Inlines.Add( r ); </code></pre> <p>Add a special substring to the paragraph with a different Font:</p> <pre><code>Run r = new Run( substring ); r.FontFamily = new FontFamily( "Arial" ); par.Inlines.Add( r ); </code></pre> <p>The above are just little snippets. I don't know how you want to approach splitting the string or iterating over the substrings since I'm not familiar with the data, so I didn't supply the method I slapped together just to see if my idea would work. You could also use a <code>Dictionary</code> in order to detect one substring and use a replacement in the output, such as detecting <code>"(SM)"</code> and replacing it with <code>"℠"</code>.</p> <p>Let me know if you have any questions or if there's anything I can elaborate on.</p> <p>(It's good that you said it is read-only. A <code>RichTextBox</code> would not work because its <code>Document</code> property is not a <code>DependencyProperty</code> and therefore can't be the target of a <code>Binding</code>. Although, one might be able to use <code>Mode=OneWayToSource</code> to reverse it, implementing <code>ConvertBack</code> instead of <code>Convert</code>.)</p> <hr> <blockquote> <p>"I think what you left out (iterating over the string and creating those Runs) is the tricky part."</p> </blockquote> <p>I was indeed very brief about splitting the string on the special substrings. When I said, "I don't know how you'll split the string," I was not saying that I had no idea how to do it at all (I rephrased it), but that I had no idea how you would want to handle it. I assumed it would not be hard for you to figure that part out because it's the kind of string manipulation problem I would have potential hires figure out. That, and you may discover edge cases amongst your data that require changes in how you handle it. </p> <p>I'll describe to you a relatively crude version using <code>IndexOf()</code> and <code>Substring()</code>.</p> <p>So here's the problem-within-the-problem: You have many strings (e.g., <code>"Company Name(R), makers of Product(TM)"</code>) that contain 0 or more special substrings. These substrings are few and known, and the input string needs to be split into several strings where the special and nonspecial substrings have been isolated from each other (e.g., <code>{"Company Name", "(R)", ", makers of Product", "(TM)"}</code>).</p> <p>The special substrings are few and known, so you need an array of those. You know by the return value of <code>.IndexOf()</code> whether it found a substring or not. Looping over the known special substrings, you can find the first instance of any of them with an index comparison, setting aside the length of the substring, too.</p> <p>Each time you find the earliest special substring in string <code>S</code> (if any), you make derived strings <code>A</code>, <code>B</code>, and <code>C</code>. <code>B</code> is the special substring, <code>A</code> and <code>C</code> are the before and after. Append <code>A</code> and <code>B</code> to a <code>List</code> and <code>C</code> becomes the new <code>S</code> and you do it again. Except when you find no special substrings in <code>S</code> and it isn't empty, in which case you just append it whole.</p> <p>Now every odd-indexed string in the <code>List</code> is a special substring. You may want to refer to my mention of a <code>Dictionary</code> in the previous portion of this answer for use as a lookup to add a <code>Run</code> of <code>"℠"</code> when the substring you found was <code>"(SM)"</code>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload