Два столбца в Winforms RichTextBox - PullRequest
       28

Два столбца в Winforms RichTextBox

3 голосов
/ 10 января 2012

В C # мне нужно иметь возможность по крайней мере создать впечатление двух столбцов в одном RichTextBox.Для моих целей это может выглядеть так:

1+1             2
70*8+5          565
1000000-300000  700000
76-10           66

Для каждого «вопроса» в левом столбце будет соответствующий ответ.

«Очевидное» решение состоит в использованиивкладки, подобные этой:

SelectionTabs = new int[] { 0, 500 };

(или просто установите \ deftab на 3000 в необработанном Rtf).

Это все хорошо, пока ввод левой колонки САМ не содержит вкладок.Когда это так, все становится грушевидным.Я не возражаю против вставки нескольких табуляций, но это не будет хорошо работать, когда ввод содержит текст, который иногда проходит мимо определенной табуляции.Обнаружение этого и учет его должным образом не только трудно сделать, но и сопряжено с опасностью из-за результатов «очень почти, но не совсем WYSIWIG», которые возникают при печати, и того, как влияют вкладки.

Другая идея состоит в том, чтобы иметь глобальный размер вкладки (используя \ deftab в Rtf), а затем вычислить, сколько вкладок должно автоматически вставляться после каждой строки в левом столбце (на основе самой длинной строки в левом столбце).Проблема этого подхода заключается в том, что, хотя на экране все выглядит отлично, когда дело доходит до печати, в правой колонке есть некоторые глюки.Под «глюками» я подразумеваю, что примерно 1 из каждых 20 строк будет иметь «потерянную» или «лишнюю» вкладку.Это связано с тем, что печать не совсем WYSIWIG, даже после того, как я следовал этому уроку: http://msdn.microsoft.com/en-us/library/ms996492.aspx

Достаточно сказать, что даже несколько пикселей / точек при печати могут сильно повлиять на расположение вкладокпо сравнению с представлением RichTextBox на экране.

Я также пытался изменить положение табуляции на полпути через строку в Rtf, но, к сожалению, такой управляющий код применяется с начала строки, несмотря наего местоположение в Rtf.

Я также прочесывал спецификацию Rtf из http://www.biblioscape.com/rtf15_spec.htm,, и, похоже, я мало что могу с этим поделать.RichTextBox в C #, кажется, не ладит с таблицами (что было еще одним потенциальным решением).Есть также столбцы Rtf, но даже если они поддерживаются, они, вероятно, не помогут из-за того, как первый столбец переключится на второй столбец на том же листе бумаги после его заполнения (вместо сохранения первого столбца ипереходя ко второй странице статьи, что я и хотел бы.

Я уделил этой проблеме много времени, и я в полном недоумении.Что-то очень простое на самом деле невероятно сложно сделать правильно.Если я не пропустил что-то очевидное ...

---------------- РЕДАКТИРОВАТЬ 1: Это должно работать со шрифтами не фиксированной ширины, поэтому я могу 'т просто заполнить пробелами.

Ответы [ 2 ]

4 голосов
/ 10 января 2012

Хитрость проста: я недавно сделал то же самое (ну, почти) - мне пришлось создать текстовый файл создается впечатление, что он имеет несколько столбцов (в текстовом файле? sheesh)

Что за хитрость? обивка!

Предположим, у вас есть значения, которые вы указали ранее

1+1             2
70*8+5          565
1000000-300000  700000
76-10           66

Теперь все, что вам нужно сделать, это установить width символов ) левого столбца и width для правого столбца. скажем, обе ширины 30 символов.

все, что вам нужно сделать сейчас, это создать строку, как показано в следующем псевдокоде:

BEGIN-BUILD-TEXT
     FOR EACH PAIR X, Y
         STRING S1 = X.PADRIGHT(30);
         STRING S2 = Y.PADRIGHT(30);
         WRITE_LINE_TO_TEXTBOX(S1 + S2);

Таким образом, столбцы будут выровнены по левому краю с фиксированной шириной.

У меня сработало!

РЕДАКТИРОВАТЬ: Ваш RichTextBox должен использовать шрифт фиксированной ширины (он имеет одинаковой ширины для всех символов).

0 голосов
/ 12 января 2012

Это решение некрасиво, но оно работает.Чтобы иметь 2 столбца в RichTextBox, где выравнивание должно быть правильным даже при печати И где сам левый столбец может содержать вкладки, необходимо сделать следующее.(Может существовать другое решение, но после исследования в течение почти нескольких дней ничего не вышло.)

Общая идея заключается в создании новой строки Rtf из существующего Rtf / Text в RichTextBox.Новый Rtf должен определять различный набор позиций табуляции в каждой строке.Чтобы понять, что такое табуляции, откройте Wordpad и посмотрите, как вы можете щелкнуть линейку, чтобы определить их.В любом случае каждая позиция табуляции измеряется от исходного ввода RichTextBox с использованием GetPositionFromCharIndex (charIndex).Вы можете сохранить их в двумерном массиве целых чисел (строка, номер табуляции).Поскольку позиции вкладок Rtf измеряются в твипах, необходимо преобразовать значение GetPositionFromCharIndex (), возвращающее (в пикселях), в твипы, используя следующую формулу:

Graphics g = this.CreateGraphics();
double twips = pixels * 1440.0 / g.DpiX; // usually g.DpiX is 96
g.Dispose();

Если в левом столбце указано, например, 3 вкладки, вынужно вставить 3 табуляции соответственно (\ tx).По умолчанию эти значения должны быть кратны 720 (+1 для поля пикселей).Затем вам нужно установить последнюю позицию табуляции (остановку 4-й вкладки) на желаемую позицию 2-го столбца, а также добавить дополнительную последнюю вкладку в Rtf (используя \ tab).Это значение табуляции выводится путем взятия позиции конца самой длинной строки во всем левом столбце + небольшого отступа.После последней вкладки в Rtf вставьте наш правый столбец 'answer' для этой строки.Убедитесь, что вы вставили «\ pard» и для этой строки, иначе табуляция не будет работать.Каждая строка оканчивается на «\ par», и для более легкого кодирования я думаю, что табуляция может быть где угодно в этой строке Rtf.

Хорошо, как только вы выполнили приведенные выше инструкции, хотя выглядит хорошо наэкран (2 идеальных столбца), иногда он по-прежнему не будет работать должным образом при распечатке (используйте предварительный просмотр для проверки), из-за почти RTB-печати, но не полностью.Тем не менее, есть (клудый) обходной путь.Прежде всего, следуйте этому руководству, чтобы начать печатать в первую очередь: http://msdn.microsoft.com/en-us/library/ms996492.aspx

Теперь хитрость заключается в том, чтобы «растянуть» каждую вкладку с шагом не менее 1,03.Я использую 1.05, но 1.1 может быть еще безопаснее.Причина, по которой это требуется, заключается в том, что (по крайней мере, я нахожу) печать очень немного растягивает текст по горизонтали.В большинстве случаев это безвредно, но иногда это наносит ущерб вкладкам.Растягивая каждую позицию табуляции на 1,05, вы гарантируете, что текст, содержащийся между табуляции, не будет «переполнен» после следующей табуляции (таким образом, следующий текст будет ошибочно переходить на следующую вкладку после этого).Убедитесь, что при отладке вышеприведенного кода вы создаете независимую тестовую программу размера прикуса, которая позволяет вам сразу же видеть результаты Rtf при вводе (создайте 2 полноразмерных текстовых поля, левое - это сам подробный код Rtf, иправый - ДИСПЛЕЙ вышеупомянутого кода Rtf).Вы можете сразу увидеть изменения в любую сторону, если вы используете событие TextChanged для обоих RichTextBoxes.В двух словах, введите слева, посмотрите, как вывод магически корректируется справа.Или введите справа и волшебным образом увидите результирующий текст Rtf слева.Я не могу не подчеркнуть, сколько времени это спасло меня, когда я вообще работаю с форматом Rtf.

...