Опубликован: 25.03.2010 | Доступ: свободный | Студентов: 1447 / 157 | Оценка: 4.31 / 4.00 | Длительность: 25:42:00
Лекция 16:

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

Последовательная компоновка элементов управления с помощью панели FlowLayoutPanel

Панель FlowLayoutPanel напоминает окно броузера, компонующего текст и рисунки, только вместо них осуществляется разметка элементов управления. Это тоже контейнер, в котором дочерние элементы панели размещаются последовательно по горизонтали (вертикали) и автоматически перетекают ( flow ) на новые строки (столбцы), если не вмещаются в соответствующие габариты контейнера, если булево свойство WrapContents установлено в true (по умолчанию).

При WrapContents=false автоматический переток дочерних элементов отключается и программисту нужно организовывать его вручную. Независимо от значения свойства WrapContents для принудительного переноса элемента на новую строку (столбец) используется метод контейнера SetFlowBreak() с аргументом true (по аналогии с дескриптором <br> в HTML ). Он же используется и для отмены этого состояния с аргументом false. Для проверки закрепленного состояния принудительного переноса применяется метод GetFlowBreak().

Направление перемещения элементов определяется в свойстве FlowLayoutPanel.FlowDirection значениями одноименного перечисления System.Windows.Forms.FlowDirection:

Таблица 16.3 . Значения перечисления FlowDirection
LeftToRight = 0 Слева направо (по умолчанию)
TopDown = 1 Сверху вниз
RightToLeft = 2 Справа налево
BottomUp = 3 Снизу вверх

Рассмотренные ранее свойства Dock и Anchor дочерних элементов управления используются в рассматриваемой панели для их выравнивания по вертикали или горизонтали. Если элементы управления размещаются построчно, то размеры условного ограничивающего прямоугольника по высоте определяются самым высоким элементом строки. Тогда значение взаимоисключающих свойств Anchor или Dock элемента определяет его верикальное положение в этом условном прямоугольнике, а именно:

  • AnchorStyles.Top (или DockStyle.Top ) - выравнивание по верхней границе (по умолчанию)
  • AnchorStyles.Bottom (или DockStyle.Bottom ) - выравнивание по нижней границе
  • AnchorStyles.None (или DockStyle.Fill, или DockStyle.Left, или DockStyle.Right ) - выравнивание по центру (с помощью свойства Dock это выполнить нельзя)
  • AnchorStyles.Top | AnchorStyles.Bottom - растяжение по вертикали до достижения границ
  • Значения AnchorStyles.Left и AnchorStyles.Right (или DockStyle.None ) - игнорируются панелью

При вертикальном размещении элементы по умолчанию выравниваются по левой границе, но свойства Anchor или Dock позволяют этим выравниванием управлять по той же самой схеме:

  • AnchorStyles.Left - выравнивание по левой границе
  • AnchorStyles.Right - выравнивание по правой границе
  • AnchorStyles.None - выравнивание по центру
  • AnchorStyles.Left | AnchorStyles.Right - растяжение по горизонтали до достижения границ
  • AnchorStyles.Top и AnchorStyles.Bottom - игнорируются панелью

Пример использования элемента FlowLayoutPanel для динамического размещения кнопок

Вот простая программа, иллюстрирующая использование компонующей панели FlowLayoutPanel

using System;
using System.Drawing;
using System.Windows.Forms;
    
namespace Test
{
    // Класс приложения
    class MyClass : Form
    {
        public MyClass()
        {
        // Настраиваем форму
        this.Text = "Компоновочная панель FlowLayoutPanel";
    
        // Создаем и настраиваем компоновочную панель
        FlowLayoutPanel flow = new FlowLayoutPanel();// Создали
        flow.Parent = this;// Привязали к форме
        flow.Dock = DockStyle.Fill;// Растянули по форме
        // Задаем направление размещения дочерних элементов
        flow.FlowDirection = FlowDirection.LeftToRight;
        flow.AutoScroll = true;// Включаем полосы прокрутки
        flow.Name = "flow";// Просто назначаем имя
        // Регистрируем обработчик компоновочной панели
        flow.Click += elementClick;
    
        // Создаем и инициализируем генератор случайных чисел
        // текущим значением секунд в диапазоне от 0 до 59
        Random rand = new Random(DateTime.Now.Millisecond);
    
        // Создаем btnCount кнопок случайных размеров
        const int btnCount = 10;
        for (int i = 0; i < btnCount; i++)
          {
          Button btn = new Button();// Создали кнопку
          btn.Parent = flow;// Привязали к панели
          btn.Text = "Кнопка " + Convert.ToString(i + 1);// Подписали
          btn.AutoSize = true;// Подстроили под текст
          // Регистрируем общий с компоновочной панелью обработчик кнопок
          btn.Click += elementClick;
          // Создаем структуру и инициализируем начальным размером
          Size btnSize = btn.PreferredSize;// Предпочтительный размер
          // Корректируем структуру случайным образом в сторону увеличения
          btnSize.Width = (int)(btnSize.Width * (1 + 2 * 
    rand.NextDouble()));
          btnSize.Height = (int)(btnSize.Height * (1 + 2 * 
    rand.NextDouble()));
          // Задаем размер кнопки
          btn.Size = btnSize;
          // Маркируем
          btn.Name = "btn" + (i + 1);
          // Центрируем построчно
          btn.Anchor = AnchorStyles.None;
          }
        }
    
        // Общий обработчик для кнопок и панели
        void elementClick(object sender, EventArgs e)
        {
            Form frm = new Form();// Создаем вспомогательную форму
            frm.Owner = this;// Отображать поверх владельца
    
            // Формируем заголовок вспомогательного окна
            string title = sender.GetType().Name;// Имя типа
            // Повышаем полномочия ссылки для адресации к свойству Text
            Control ctrl = (Control)sender;
            if (ctrl.Name.Length > 0)
                title += " (" + ctrl.Name + 
      ")";// Имя объекта, если есть
            if (ctrl.Text.Length > 0)
                title += " - " + 
    ctrl.Text;// Надпись, если есть
            frm.Text = title;
    
            // Создаем панель отображения свойств выделенного объекта
            PropertyGrid properties = new PropertyGrid();
            properties.Parent = frm;// Привязать
            properties.Dock = DockStyle.Fill;// Распахнуть
            properties.SelectedObject = sender;// Чьи свойства отображать
            properties.PropertySort = PropertySort.Alphabetical;// Сортировать
    
            frm.Show();// Показать окно
        }
    }
    
    // Запуск
    class Program
    {
        static void Main()
        {
            Application.EnableVisualStyles();
            // Создали форму и передали ее в цикл сообщений Windows
            Application.Run(new MyClass());
        }
    }
}
Листинг 16.7 . Демонстрация компоновочной панели FlowLayoutPanel

Вот примерный результат


При горизонтальном направлении размещения кнопки выравниваются по горизонтали, но по вертикали они пристыковываются друг к другу на равных расстояниях и не подлежат выравниванию. Расстоянием между пристыкованными в строке элементами можно управлять с помощью свойств Padding (внутри) и Margin (снаружи), которые являются структурами, ждущими соответствующих настроек.

Пример использования элемента FlowLayoutPanel для формирования окна About

Приведем еще пример использования элемента управления FlowLayoutPanel для формирования интерфейса простого окна About.

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;// для класса Process
    
namespace Test
{
    // Класс приложения
    class MyClass : Form
    {
        public MyClass()
        {
        // Настраиваем форму
        this.Text = "Компоновка окна About";
        //Включили способность менять размеры
        this.AutoSize = true;
        // Разрешить растягиваться и сжиматься
        this.AutoSizeMode = AutoSizeMode.GrowAndShrink;
        // Запретить интерактивное изменение и настроить вид
        this.FormBorderStyle = FormBorderStyle.FixedDialog;
    
        // Создаем контейнер для рисунка
        PictureBox photo = new PictureBox();
        photo.Parent = this;// Привязываем к форме
        photo.Size = new Size(200, 200);// Размер контейнера
        photo.Image = Image.FromFile("MyPhoto.jpg");// Закачали
        // Распахнуть по контейнеру с соблюдением пропорций
        photo.SizeMode = PictureBoxSizeMode.Zoom;
    
        // Создаем и настраиваем компоновочную панель
        FlowLayoutPanel flow = new FlowLayoutPanel();// Создали
        flow.Parent = this;// Привязали к форме
        flow.AutoSize = true;// Пусть подстраивается
        // Направление размещения по столбцам
        flow.FlowDirection = FlowDirection.TopDown;
        // Стыковка к рисунку справа
        flow.Location = new Point(photo.Right, 0);
    
        // Создаем и настраиваем текстовую метку
        Label lbl = new Label();
        lbl.Parent = flow;// Привязали к панели
        lbl.AutoSize = true;// Подстройка под текст
        lbl.Anchor = AnchorStyles.None;// Центрировать в столбце
        lbl.Margin = new Padding(this.Font.Height);// Окаймление
        lbl.Text = "AboutBox Version 1.0";// Содержимое надписи
        lbl.Font = new Font(FontFamily.GenericSansSerif, 
    24, FontStyle.Italic);
    
        // Создаем и настраиваем метку-ссылку
        LinkLabel lnk = new LinkLabel();
        lnk.Parent = flow;// Привязали к панели
        lnk.AutoSize = true;// Подстройка под текст
        lnk.Anchor = AnchorStyles.None;// Центрировать в столбце
        lnk.Margin = new Padding(this.Font.Height);// Окаймление
        lnk.Text = "\x00A9 2007 СФУ";// Значок и текст авторских прав
        lnk.Font = new Font(FontFamily.GenericSansSerif, 16);
        // Область интерактивности ссылки
        lnk.LinkArea = new LinkArea(lnk.Text.Length - 
    3, lnk.Text.Length);
        // Подписываем на событие анонимный обработчик
lnk.LinkClicked += delegate { Process.Start(@"http://www.gold.krasu.ru"); };
    
        // Создаем и настраиваем кнопку
        Button btn = new Button();
        btn.Parent = flow;// Привязали к панели
        btn.AutoSize = true;// Подстройка под текст
        btn.Anchor = AnchorStyles.None;// Центрировать в столбце
        btn.Margin = new Padding(this.Font.Height);// Окаймление
        btn.Text = "Выход";// Надпись на кнопке
        // Регистрируем анонимный обработчик для закрытия формы
        btn.Click += delegate { this.Close(); };
    
        // Создаем и настраиваем всплывающие подсказки
        ToolTip tips = new ToolTip();
        tips.SetToolTip(photo, "Это значок");
        tips.SetToolTip(lnk, "Зайти на сайт");
        tips.SetToolTip(btn, "Закрыть окно");
        }
    }
    
    // Запуск
    class Program
    {
        static void Main()
        {
            Application.EnableVisualStyles();
            // Создали форму и передали ее в цикл сообщений Windows
            Application.Run(new MyClass());
        }
    }
}
Листинг 16.8 . Пример формирования окна About

Файл рисунка нужно добавить к проекту командой Add оболочки и настроить его свойства Properties через контекстное меню:

  • Build Action = Embedded Resource - назначить внедренным ресурсом
  • Copy to Output Directory = Copy always - копировать в рабочий каталог всегда при каждой компиляции

Вот результат выполнения программы


Максим Филатов
Максим Филатов

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

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

 

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