Книга: C# для профессионалов. Том II
Вычисление размеров объектов и размера документа
Вычисление размеров объектов и размера документа
Мы возвращаемся теперь к примеру CapsEditor
и разбираем методы CalculateLineWidths()
и CalculateDocumentSize()
, которые вызываются из метода LoadFile()
:
private void CalculateLineWidths() {
Graphics dc = this.CreateGraphics();
foreach (TextLineInformation nextLine in documentLines) {
nextLine.Width = (uint)dc.MeasureString(nextLine.Text, mainFont).Width;
}
}
Этот метод просто выполняется на каждой прочитанной строке и использует метод Graphics.MeasureString()
для определения и сохранения значения величины горизонтального пространства экрана, которое требуется строке. Мы сохраняем значение, так как MeasureString()
является весьма интенсивным с вычислительной точки зрения. Так как в нашем примере CapsEditor
не слишком легко определить высоту и положение каждого элемента, то этот метод почти наверняка будет реализован, чтобы вычислить все эти величины.
Теперь, когда мы знаем размер каждого элемента на экране и можем вычислить приблизительное его положение, определим реальный размер документа. Высота, по существу, равна числу строк, умноженному на высоту каждой строки. Ширину необходимо определить просмотром всех строк, чтобы выявить самую длинную и взять ширину этой строки. Для высоты и ширины также желательно допустить небольшие поля вокруг выводимого документа, чтобы приложение выглядело более привлекательно. (Нежелательно, чтобы текст прикасался к одному из углов клиентской области.) Вот метод, который вычисляет размер документа:
private void CalculateDocumentSize() {
if (!documentHasData) {
documentSize = new Size(100, 200);
} else {
documentSize.Height = (int)(nLines*lineHeight) + 2*(int)margin;
uint maxLineLength = 0;
foreach (TextLineInformation nextWord in documentLines) {
uint tempLineLength = nextWord.Width + 2*margin;
if (tempLineLength > maxLineLength) maxLineLength = tempLineLength;
}
documentSize.Width = (int)maxLineLength;
}
this.AutoScrollMinSize = documentSize;
}
Этот метод сначала проверяет, есть ли данные для вывода. Если данных нет, мы слегка схитрим и зададим жестко кодированный размер документа такой величины, чтобы хватило места для выведения большими красными буквами предупреждения <Empty Document>. В противном случае необходимо воспользоваться методом MeasureString()
для определения реального размера документа.
После этого размер документа сообщается экземпляру класса Form, задавая свойство Form.AutoScrollMinSize
. Когда это сделано, за сценой происходит кое-что интересное. В процессе задания этого свойства клиентская область становится недействительной и инициируется событие Paint
в связи с тем, что изменение размера документа означает необходимость добавить или изменить панели прокрутки, а также, что вся клиентская область почти наверняка будет перерисована. Это в полной мере иллюстрирует то, что было сказано ранее об использовании метода Form.Invalidate()
. Если вернуться назад к коду LoadFile()
, то станет понятно, что вызов метода Invalidate()
в этом методе является на самом деле излишним. Клиентская область будет объявлена недействительной в любом случае, когда задается размер документа. Явный вызов метода Invalidate()
в реализации метода LoadFile()
оставлен для иллюстрации. Фактически в этом случае все, что будет делать вызванный метод Invalidate()
, является ненужным запросом повторного события Paint
. Однако это в свою очередь подтверждает, что Invalidate()
дает Windows возможность оптимизировать производительность. Второе событие Paint не будет фактически инициировано: Windows увидит, что в очереди уже находится событие Paint
, и сравнит запрошенные недействительные области, чтобы попробовать объединить их. В этом случае оба события Paint будут определять всю клиентскую область, поэтому ничего не нужно делать, и Windows спокойно удалит второй запрос Paint
. Конечно, это действие займет какое-то процессорное время, но оно будет ничтожным по сравнению с тем, сколько времени потребуется для реального выполнения рисования.
- Иерархия объектов в InterBase
- Уменьшение размера, занимаемого индексами
- 1.2.2. Комментарии и встроенная документация
- Имена объектов длиной 68 символов
- Создание объектов Collection
- Создание корня документа:
- Как уменьшить размер документа Microsoft Word?
- Глава 2 Вычисление
- Работа с документами в режиме оффлайн
- Использование информационной панели документа
- Использование панели задач Управление документами в приложениях Office 2007
- Публикация документа в библиотеке