Опубликован: 25.03.2010 | Уровень: для всех | Доступ: платный
Лекция 16:

Динамическая компоновка формы

Большой пример разработки диалогового окна выбора шрифта

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

using System.Windows.Forms;
    
namespace Test
{
    // Запуск
    class Program
    {
        static void Main()
        {
            // Создаем объект окна стандартного диалога выбора шрифта
            FontDialog fontDialog = new FontDialog();
            // Показать дополнительные части диалогового окна
            fontDialog.ShowEffects = true;
            fontDialog.ShowColor = true;
            //fontDialog.ShowApply = true;// Кнопка "Применить"
            //fontDialog.ShowHelp = true; // Кнопка "Справка"
    
            // Показать само окно
            fontDialog.ShowDialog();
        }
    }
}
Листинг 16.13 . Программа вызова стандартного диалога FontDialog

Вот так примерно должен выглядеть наш диалог выбора шрифта


Можно заметить, что элементы управления стандартного диалогового окна размещены в таблице, которая имеет 3 строки и 4 столбца. Код каждой сложной части диалога изолируем в отдельные классы и поместим в отдельные одноименные файлы. Ниже приведены все составляющие данного примера.

Самоподстраивающийся контейнер GroupPanel

Приведем рассмотренный ранее код компоновочного контейнера с рамкой. Предварительно удалим из него свойство Check, связанное с размещением радиокнопок и организацией их согласованной работы. Хотя можно это свойство и не удалять - все равно мы его использовать в данном примере не будем. Вот код панели, который нужно разместить в отдельном файле GroupPanel.cs

using System;
using System.Drawing;
using System.Windows.Forms;
    
namespace Test
{
    // Класс расширения стандартной панели размещения
    class GroupPanel : FlowLayoutPanel
    {
        // Поля класса для видимости в методах
        int xDpi, yDpi;
        new public string Text; // Скрываем наследуемое поле 
        // Надпись в рамке
    
        // Конструктор
        public GroupPanel()
        {
            // Перетекание по столбцам
            this.FlowDirection = FlowDirection.TopDown;
            // Отключаем автоматический переток элементов
            this.WrapContents = false;
            //Включили способность менять размеры
            this.AutoSize = true;
            // Разрешить панели растягиваться и сжиматься
            this.AutoSizeMode = AutoSizeMode.GrowAndShrink;
    
            // Создаем временный контекст устройства
            Graphics gr = this.CreateGraphics();
            // Извлекаем текущее разрешение экрана
            xDpi = (int)gr.DpiX;
            yDpi = (int)gr.DpiY;
            // Освобождаем критичный ресурс - контекст устройства
            gr.Dispose();
            // Устанавливаем отступы внутри рамки контейнера
            this.Padding = new Padding(xDpi / 10, yDpi / 10 + 
    Font.Height, xDpi / 10, yDpi / 10);
        }
    
        // Переопределяем виртуальный обработчик изменения шрифта
        protected override void OnFontChanged(EventArgs e)
        {
            base.OnFontChanged(e);// Базовый обработчик
            this.Padding = new Padding(this.Padding.Left,
                yDpi / 10 + this.Font.Height,
                this.Padding.Right, this.Padding.Bottom);
        }
    
        // Переопределяем виртуальный обработчик перерисовки формы
        // Сами перекомпоновываем элементы и перерисовываем результат
        protected override void OnPaint(PaintEventArgs e)
        {
            // Извлекаем контекст устройства
            Graphics gr = e.Graphics;
            // Смещение 
            int yIdent = yDpi / 25 + this.Font.Height / 2;
            int xIdent1 = xDpi / 10;
            int xIdent2;// Пока просто объявили
    
            // Отображаем надпись внутри рамки, если она задана
            if (this.Text != null && this.Text.Length > 0)
            {
                gr.DrawString(
                    " " + this.Text + " ",
                    this.Font,
                    new SolidBrush(this.ForeColor),
                    xIdent1, yDpi / 25
                    );
                xIdent2 = xIdent1 + (int)(gr.MeasureString(
                    " " + this.Text + " ",
                    this.Font).Width) + 7;// Увеличили отступ справа
            }
            else
            {
                xIdent2 = xIdent1;
            }
    
            // Создаем перья стандартного цвета и рисуем рамку
            Pen pnDark = new Pen(ControlPaint.Dark
    (BackColor));// Темный
            Pen pnLight = new Pen(ControlPaint.Light
    (BackColor));// Светлый
    
            // Рисуем темную рамку
            gr.DrawLine(pnDark, xIdent1, yIdent, 0, yIdent);
            gr.DrawLine(pnDark, 0, yIdent, 0, this.Height - 2);
            gr.DrawLine(pnDark, 0, this.Height - 2, 
    this.Width - 2, this.Height - 2);
            gr.DrawLine(pnDark, this.Width - 2, this.Height - 2, 
    this.Width - 2, yIdent);
            gr.DrawLine(pnDark, this.Width - 2, yIdent, 
    xIdent2, yIdent);
    
            // Рисуем светлую рамку
            gr.DrawLine(pnLight, xIdent1, yIdent + 1, 1, yIdent + 1);
            gr.DrawLine(pnLight, 1, yIdent + 1, 1, this.Height - 3);
            gr.DrawLine(pnLight, 0, this.Height - 1, 
    this.Width - 1, this.Height - 1);
            gr.DrawLine(pnLight, this.Width - 1, this.Height - 1, 
    this.Width - 1, yIdent);
            gr.DrawLine(pnLight, this.Width - 3, yIdent + 1, 
    xIdent2, yIdent + 1);
        }
    }
}
Листинг 16.14 . Код модифицированного контейнера GroupPanel
Максим Филатов
Максим Филатов

Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет:

Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.

 

Как активировать код?

Денис Пашков
Денис Пашков
Россия
Татьяна Ковалюк
Татьяна Ковалюк
Украина