1
Vote

Multiline fields with Right-Align destroys layout

description

The root cause appears to be in RenderForm.cs, SubstituteTokens. When there are multiple items for a Token, it executes this code:
// If the token has more than one values, they will each be placed on a new text line
if (tokenValues.Length > 1)
{
  // This calculates the position of the token's first character relative to the text box.
  // The method uses the plain text for character index, not the RTF text
  Point position = _infoTextBox.GetPositionFromCharIndex(tokenRegex.Match(_infoTextBox.Text).Index);
  // Converting the pixel position into twips which is what RTF uses
  int indent = twipPerPixel * (position.X - 1);

  // Next we loop over the token values and build a string
  StringBuilder sb = new StringBuilder();
  foreach (string value in tokenValues)
  {
    // \par closes a paragraph and \pard opens a new one, \li sets the indentation to the specified number of twips
    if (sb.Length > 0) sb.Append(@"\par\pard\li" + indent + " ");
    sb.Append(value);
  }

  // Get the information text length before replacing the token
  int oldLength = _infoTextBox.Rtf.Length;

  // Replace the token with its values
  _infoTextBox.Rtf = tokenRegex.Replace(_infoTextBox.Rtf, sb.ToString(), 1, match.Index);

  // Finding the next line break in order to reset the indentation, we have to look right after the newly added values
  Match nextLineMatch = nextLineRegex.Match(_infoTextBox.Rtf, match.Index + match.Value.Length + (_infoTextBox.Rtf.Length - oldLength));
  if (nextLineMatch.Success)
  {
    // If the line break is found, add a zero indentation right after it
    _infoTextBox.Rtf = nextLineRegex.Replace(_infoTextBox.Rtf, nextLineMatch.Groups[1].Value + @"\li0 ", 1, nextLineMatch.Index);
  }
Given the layout below (all right-aligned) with 2 IPs:
                                            <% Host Name %>

                                        <% IP4 Addresses %>

                                            <% User Name %>
The output looks something akin to this
                                                  MYPC

                                            10.4.9.105
                                 10.4.9.139

BobUser
If I comment out this code that attempts to make sure the format and indent are correct (here's the changed pieces) it seems to work:
    // if (sb.Length > 0) sb.Append(@"\par\pard\li" + indent + " ");
    if (sb.Length > 0) sb.Append(@"\par ");
...
// if (nextLineMatch.Success)
// {
//   // If the line break is found, add a zero indentation right after it
//   _infoTextBox.Rtf = nextLineRegex.Replace(_infoTextBox.Rtf, nextLineMatch.Groups[1].Value + @"\li0 ", 1, nextLineMatch.Index);
// }
Obviously the existing code was written for a reason, but my test cases can't see it, and I don't know enough about RTF to figure out what it really should have been.

comments