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

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

Табличная компоновка элементов управления с помощью панели TableLayoutPanel

Панель TableLayoutPanel позволяет размещать дочерние элементы в сетке строк и столбцов, наподобие таблиц в HTML. Свойство AutoSize, установленное в true, позволяет автоматически подгонять ячейки таблицы под размеры размещаемых в ней элементов. Границы ячеек таблицы можно сделать видимыми с помощью ее свойства CellBorderStyle, присвоив одно из значений перечисления TableLayoutPanelCellBorderStyle, но для размещения обычно это не нужно.

Размер сетки задается с помощью свойств RowCount и ColumnCount, которые по умолчанию равны 0, и это то же самое, что задать 1. Для автоматического добавления новых строк или столбцов используется свойство GrowStyle, ожидающее одно из значений перечисления TableLayoutPanelGrowStyle: FixedSize, AddRows (по умолчанию), AddColumns. Если одна координата таблицы добавляется автоматически, то другая координата определяется свойством RowCount или ColumnCount соответственно.

Значение FixedSize нужно присваивать только после того, как будут заданы значения свойств RowCount и ColumnCount. При этом, если количество динамически размещаемых в таблице элементов управления превысит количество ячеек, будет сгенерировано исключение. Ячейки таблицы можно заполнять избирательно. Если предположить, что table - экземпляр таблицы, а ctrl - размещаемый в ячейке ( row, col ) элемент управления, то код будет таким

table.Controls.Add(ctrl, col, row);

Целые числа col и row отсчитываются от нуля. Если при вызове метода Add() в адресуемой ячейке таблицы уже находится элемент управления, то он будет перемещен в следующую ячейку.

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

TableLayoutPanelCellPosition cellPos = table.GetCellPosition(ctrl);

Поля Row и Column структуры TableLayoutPanelCellPosition дают координаты ячейки таблицы:

int row = cellPos.Row;
int col = cellPos.Column;

Для элемента управления ячейка таблицы считается родителем, поэтому размещение в рамках ячейки определяется свойствами элемента Dock или Anchor.

Приведем пример, иллюстрирующий работу элемента TableLayoutPanel.

using System;
using System.Drawing;
using System.Windows.Forms;
    
namespace Test
{
    // Форма приложения
    class MyClass : Form
    {
    // Вынесены в поля для видимости в обработчике
    Panel panelColor;// Ссылка для адресации правой панели SplitContainer
    Label[] arrayLabelValue = new Label[3];// Массив для значений цветов
    
    public MyClass()
    {
    this.Text = "Использование табличной компоновки TableLayoutPanel";
    this.Width *= 2;// Увеличим ширину формы
    
    // Создаем двухпанельный элемент с изменяемой границей
    SplitContainer split = new SplitContainer();
    split.Parent = this;// Привязали к форме
    split.Dock = DockStyle.Fill;// Развернули на всю форму
    split.Orientation = Orientation.Vertical;// По умолчанию
    split.SplitterDistance = this.ClientSize.Width / 2;// Позиция движка
    split.TabStop = false;// Отключаем получение фокуса по клавише Tab
    
    // Создаем в левой панели элемент TableLayoutPanel
    TableLayoutPanel table = new TableLayoutPanel();
    table.Parent = split.Panel1;// Назначили родителя
    table.Dock = DockStyle.Fill;// Развернули на всю левую панель
    table.BackColor = Color.White;// Цвет фона
    // Установили размер таблицы 3x3
    table.RowCount = 3;
    table.ColumnCount = 3;
    
    // Адресуем правую панель полем
    panelColor = split.Panel2;
    
    // Создаем двумерный массив для названий RGB
    string[,] arrayNameColors = {
      {"Красный", "Зеленый", "Синий" },
      {"Red", "Green", "Blue"}
                                        };
    // Создаем массив для числовых значений цветов 
    // и инициализируем начальным цветом фона правой панели
    int[] arrayValueColors ={ 
      panelColor.BackColor.R,     // Red - красный
      panelColor.BackColor.G,     // Green - зеленый
      panelColor.BackColor.B };   // Blue - синий
    
    // Создаем шрифт для текстовых меток
    Font font = new Font("Arial", 10, FontStyle.Bold);
    
    // Заполнение таблицы по столбцам
    for (int col = 0; col < 3; col++)
      {
      // Первая строка с названиями цветов
      Label lbl = new Label();// Создали объект
      lbl.AutoSize = true;// Подстройка метки под текст
      lbl.Anchor = AnchorStyles.None;// Расположиться в центре ячейки
      lbl.Text = arrayNameColors[0, col];// Русское название цвета
      lbl.ForeColor=Color.FromName(arrayNameColors[1, col]);// Цвет метки
      lbl.Font = font;// Установили шрифт
      table.Controls.Add(lbl, col, 0);// Поместить в ячейку таблицы
    
      // Вторая строка с полосами прокрутки
      VScrollBar scroll = new VScrollBar();// Создали объект
      // Растянули по высоте средней строки
      scroll.Anchor = AnchorStyles.Top | AnchorStyles.Bottom;
      // Включили отклик на клавишу Tab для смены фокуса ввода
      scroll.TabStop = true;
      // Установили длину ползунка и шаг скролирования
      scroll.LargeChange = 16;// 16 * 16 = 256 цветов
      // Когда ползунок внизу
      scroll.Maximum = 255 + scroll.LargeChange - 1;
      // Устанавливаем начальное значение ползунка
      scroll.Value = arrayValueColors[col];
      // Подписались на событие при отпускании ползунка 
      scroll.ValueChanged += scroll_ValueChanged;
      table.Controls.Add(scroll, col, 1);// Поместить в ячейку таблицы
    
      // Третья строка со значениями цвета
      arrayLabelValue[col] = new Label();// Создали объект
      arrayLabelValue[col].AutoSize = true;// Подстройка под текст
      arrayLabelValue[col].Anchor = AnchorStyles.None;// В центре ячейки
      // Установим цвет текстовой метки
      arrayLabelValue[col].ForeColor = Color.FromName
    (arrayNameColors[1, col]);
      // Связываем свойство Text метки и свойство Value полосы прокрутки
      arrayLabelValue[col].DataBindings.Add("Text", 
    scroll, "Value");
      arrayLabelValue[col].Font = font;// Установили шрифт
      // Добавляем настроенную текстовую метку значения цвета в ячейку таблицы
      table.Controls.Add(arrayLabelValue[col], col, 2);
    
      // Устанавливаем столбцы таблицы на три равных ширины
      table.ColumnStyles.Add(new ColumnStyle
  (SizeType.Percent, 100.0f / 3));
      }
    
    // Устанавливаем среднюю строку таблицы максимально большой
    table.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // Первая строка
    table.RowStyles.Add(new RowStyle(SizeType.Percent, 
  100.0f));// Вторая строка
    table.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // Третья строка
    }
    
    void scroll_ValueChanged(object sender, EventArgs e)
    {
    // Меняем цвет фона правой панели
    panelColor.BackColor = Color.FromArgb(
      int.Parse(arrayLabelValue[0].Text),// Преобразуем в число
      int.Parse(arrayLabelValue[1].Text),// Преобразуем в число
      int.Parse(arrayLabelValue[2].Text) // Преобразуем в число
    );
    }
    }
    
    // Запуск
    class Program
    {
        static void Main()
        {
            Application.EnableVisualStyles();
            // Создали форму и передали ее в цикл сообщений Windows
            Application.Run(new MyClass());
        }
    }
}
Листинг 16.12 . Иллюстрация работы элемента TableLayoutPanel

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


Поизменяйте размеры формы и разделителя и подивитесь, как автоматически перекомпоновываются элементы управления слева.

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

Объединение ячеек панели TablelayoutPanel можно выполнить ее методами

SetColumnSpan(ctrl, span);SetRowSpan(ctrl, span);
где ctrl - элемент управления, расположенный в первой 
           из объединяемых ячеек
    span - количество объединяемых ячеек

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

GetColumnSpan(ctrl);
GetRowSpan(ctrl);

возвращают количество объединенных ячеек.

Для элемента управления, занимающего несколько строк и столбцов, метод GetPositionFromControl(ctrl) возвращает структуру TableLayoutPanelCellPosition, в которой поля Row и Column дают координаты самой левой и самой верхней из объединенных ячеек таблицы, которую занимает элемент управления ctrl. При адресации к любой из объединенных ячеек таблицы с помощью метода GetControlFromPosition(col, row) можно получить адрес находящегося там элемента управления.

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

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

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

 

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