Печать календаря на C#

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

В программе используются несколько методов, включая метод, описанный в сообщении Получить имя первого дня недели на C# .

Одна из больших проблем заключается в том, что разные страны начинают неделю с разных дней. Например, в Соединенных Штатах неделя начинается с воскресенья, но в Германии и Австралии начинается с понедельника.

Программа использует следующие две переменные для хранения информации о календаре.

В переменной FirstOfMonth хранится первая дата месяца, который должен быть напечатан. Массив CalendarData содержит текст для отображения в каждой из дат месяца. В этом примере вы можете выбрать месяц и год. Программа инициализирует этот массив случайным образом, хотя в реальном приложении вы хотели бы использовать напоминания о назначении и другой полезный текст.

При нажатии кнопки «Предварительный просмотр» программа считывает выбранную дату и создает случайные данные. Затем он вызывает метод ShowDialog для диалогового окна предварительного просмотра, который я создал во время разработки. Также во время разработки я создал PrintDocument и установил для него свойство Document диалогового окна.

Когда программа вызывает ShowDialog, в диалоговом окне используется PrintDocument, чтобы сгенерировать распечатку, подняв некоторые события. Первым событием, используемым в этом примере, является QueryPageSettings, который обрабатывается следующим обработчиком событий.

Этот код просто выводит распечатку в альбомном режиме. Если вы хотите печатать в портретном режиме, просто закомментируйте эту строку.

После завершения этого события PrintDocument вызывает событие PrintPage, чтобы сделать рисунок. Этот обработчик событий PrintPage этого примера просто вызывает следующий метод DrawCalendar.

Этот метод делает календарь максимально возможным, вставляя его в прямоугольник, который он получает в качестве параметра. Для этого он делит ширину области на семь четных столбцов.

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

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

Затем метод вызывает DrawDateData, чтобы нарисовать ячейки даты. Он заканчивается рисованием окна вокруг всего календаря.

Следующий код показывает метод NumberOfWeekRows.

Этот метод использует DateTime.DaysInMonth, чтобы узнать, сколько дней в этом месяце. Затем он использует метод DateColumn, описанный ниже, чтобы получить номер столбца в первый день месяца и добавляет его к числу дней в месяце. В основном это добавляет день к месяцу для каждого дня, который предшествует первому дню месяца.

Например, предположим, что неделя начинается с воскресенья, а первый день месяца - вторник. Затем код добавляет 2 дня (номера столбцов - воскресенье = 0, понедельник = 1, вторник = 2), чтобы освободить место для воскресенья и понедельника, которые выходят до первого дня.

После добавления дополнительных поддельных дней метод просто делит на 7, округляет и возвращает результат.

В следующем коде показан метод DateColumn.

Метод DateColumn возвращает номер столбца для определенной даты. Сначала он получает дату DayOfWeek. Этот номер является индексом даты в массиве имен дня в культуре и этот массив всегда начинается с воскресенья в позиции массива 0. Например, если днем является вторник, то это число равно 2.

Но неделя не обязательно начинается с воскресенья, в зависимости от локали, поэтому код вычитает индекс первого дня недели.

Например, предположим, что вы находитесь в Австралии, поэтому первый день недели - понедельник с индексом 1. Тогда, если дата - вторник, номер столбца 2 - 1 = 1. Это имеет смысл, потому что в Австралии первая колонка проходит в понедельник, а вторая - во вторник.

Теперь, если дата была в воскресенье, а неделя начинается в понедельник, номер столбца равен -1. В этом случае код добавляет 7, чтобы получить столбец номер 6, то есть эта дата принадлежит в последнем столбце недели.

Теперь, если дата была в воскресенье, а неделя начинается в понедельник, номер столбца равен -1. В этом случае код добавляет 7, чтобы получить столбец номер 6, то есть эта дата принадлежит в последнем столбце недели.

...

Этот метод сначала превращает объект StringFormat в центр текста.

Затем он использует массив MonthNames текущей культуры, чтобы получить название выбранного месяца. Вот потенциальная добыча. Свойство DateTime структуры DateTime дает номер месяца от 1 до 12. Как и почти каждый другой массив в C#, массив имен месяцев начинается с индекса 0, поэтому код вычитает 1 от номера месяца, чтобы получить правильное имя месяца. Затем он использует имя месяца и год даты для создания строки заголовка календаря.

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

После того, как он нашел размер шрифта, метод рисует заголовок календаря.

Следующий код показывает, как метод DrawWeekdayNames рисует имена дней недели по столбцам календаря.

Сначала код получает массив DayNames текущей культуры, который содержит имена будних дней. Он создает шрифт и затем перебирает имена, измеряя каждый, чтобы увидеть, что является самым широким, когда нарисовано в шрифте.

Затем код вызывает FindFontSize, чтобы увидеть, насколько большой он может нарисовать наибольшее имя дня недели, чтобы он помещался в пространство над столбцом.

Далее код перебирает имена и рисует их по столбцу. Массив целых дней в буддизме всегда содержит имена в порядке: воскресенье, понедельник, вторник, ..., суббота. Значение DateTimeFormat.FirstDayOfWeek в культуре дает вам индекс в этом массиве первого дня недели. Например, это значение равно 0 в Соединенных Штатах и 1 в Австралии.

Программа начинается с переменной index, равной культуре FirstDayOfWeek, а затем отображает 7 значений, при необходимости обертывая индекс 0.

(Обратите внимание, что в программе предполагается, что есть семь дней в неделю. Это похоже на каждую культуру, поддерживаемую .NET. Это одна из немногих вещей, о которых каждая страна согласна.)

Следующий код показывает метод DrawDateData.

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

Затем код создает прямоугольник data_rectf для хранения данных даты ниже прямоугольника date_rectf.

Далее код использует метод FindFontSize, чтобы найти самый большой шрифт, который он может использовать, чтобы соответствовать тексту «30» в прямоугольнике числа.

Затем код вызывает DateColumn (описанный ранее), чтобы увидеть, какой столбец должен содержать первый день месяца.

Далее код создает шрифты, чтобы нарисовать даты и текст даты. Он создает объект StringFormat, который помещает текст в верхний левый угол прямоугольника форматирования. Он устанавливает свойства объекта Обрезка и FormatFlags, чтобы текст заканчивался эллипсисом после последнего слова, которое может поместиться, и новая строка не запускается, если она не будет полностью соответствовать в прямоугольнике форматирования.

Затем код получает число дней в этом месяце и готов начать рисовать даты.

Переменная day_num пересекает от 0 до единицы меньше, чем число дней в месяце. Для каждого дня код устанавливает положение прямоугольника cell_rectf. Его координата X задается числом столбцов col, умноженным на ширину столбца. Его позиция Y сохраняется в переменной y. После того, как он задает позицию прямоугольника для ячейки, код очерчивает ее.

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

После того, как он закончил рисовать эту дату, код добавляет 1 к номеру столбца, обертывая обратно до 0, если строка календаря заполнена.

Источник: http://csharphelper.com/blog/2016/01/print-a-calendar-in-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)

Add a Comment

Ваш e-mail не будет опубликован. Обязательные поля помечены *