2012-01-10 3 views
3

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

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

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

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

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

(или просто установить \ deftab около 3000 в сыром Rtf).

Это все хорошо и хорошо, пока левый столбец ввода ITSELF не содержит вкладок. Когда это так, все идет грушевидно. Я не против вставлять несколько табуляторов, но это не сработает, когда вход содержит текст, который иногда проходит «мимо» определенной вкладки-остановки. Обнаружение этого и учет его должным образом не просто трудно сделать, но также чревато опасностью из-за «очень-почти-но-не-полностью-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, и, похоже, я ничего не могу с этим поделать. C# RichTextBoxes, похоже, не справляются с таблицами (это было еще одно потенциальное решение). Также есть столбцы Rtf, но даже если они поддерживаются, они, вероятно, не помогут из-за того, что первый столбец переключится на второй столбец на том же листе бумаги, как только он будет заполнен (вместо сохранения в первом столбце и перейдя ко второй странице бумаги, что я бы хотел).

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

---------------- EDIT 1: Это необходимо для работы с шрифтами с фиксированной шириной, поэтому я не могу просто площадку с пробелами.

+1

http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/194f563c-205f-41a1-9582-4f03fd3a53c2/ –

+0

Спасибо, это интересно и может пригодиться в будущем. На данный момент я предоставил свой собственный ответ на основе вкладок (что является kludgy по-своему). –

ответ

4

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

(в текстовом файле Sheesh?)

что это за трюк? обивка!

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

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

Теперь все, что вам нужно сделать, это установить ширинасимволы) из левой колонки, а ширина для правая колонка. предположим, что ширина равна 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); 

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

Работал для меня!

EDIT: Ваш RichTextBox должен использовать равноширинный (он имеет одинаковую ширину для всех персонажей).

+0

Извините, что я забыл упоминание, шрифты, которые я использую, не имеют фиксированной ширины, поэтому он должен учитывать более общий случай. –

+0

Ну, вы можете использовать _use_ шрифт с фиксированной шириной? вы можете найти много онлайн. – Shai

+0

Ну, моя программа использует ряд шрифтов, и мои пользователи ожидают, что смогут использовать любой из них, так что «боюсь, мне тоже нужны шрифты с фиксированной шириной. –

0

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

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

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

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

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

Теперь трюк состоит в том, чтобы «растянуть» каждый таблост не менее чем на 1,03. Я использую 1.05, но 1.1 может быть еще безопаснее. Причина, по которой это требуется, заключается в том, что (по крайней мере, я нахожу) печать растягивает текст по горизонтали очень немного. В большинстве случаев это безвредно, но иногда это наносит ущерб вкладам. Потянув каждое положение табуста на 1.05, вы убедитесь, что текст, заключенный между tabstops, не будет «переполнен» мимо следующего tabstop (таким образом, после этого следующий текст ошибочно перейдет на следующую вкладку).

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

+0

Комментируя мой собственный ответ, я думаю, что ссылка с упоминанием таблиц Ханса Пассана - это путь, так как обертка текста будет работать аккуратно и т. Д. Немного взломать, чтобы получить этот лучший RichTextBox, но пока нет проблем с несовместимостью, он должен стоить усилий. –

Смежные вопросы