Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Все что вы хотели узнать о TableLayoutPanel, но боялись спросить 
V
    Опции темы
ivashkanet
  Дата 7.7.2006, 17:52 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



TableLayoutPanel


Введение
Наверное каждый из нас сталкивался с ситуацией, когда несколько часов заботливо расставляешь контролы на форме. Подбираешь размеры контролов. Вычитываешь до миллиметра. Вылизываешь все. Получаешь конфетку, что глаз не оторвать. 
Запускаешь, любуешься. Разворачиваешь форму на весь экран и ... о ужас. Все что ты заботливо расставлял на форме стало напоминать убожество. Появилась куча пустого пространства. Контролы лежат не так как задумано. А если, нечаянно, запустить приложение при другом разрешении, то ... В общем – не красиво.
Хватаешься за голову. Лазишь по свойствам контролов, по MSDN. Раскапываешь, что есть неплохие свойства контрола Dock и Anchor. C помощью них, кое как, приводишь свою форму в более менее приличный вид. 
Но, к своему разочарованию, понимаешь, что докинг и анкоринг не совсем удовлетворяет твоим требованиям. Возникает вопрос как, например, разместить несколько кнопок в ряд. Расстояние между которыми фиксировано, а они сами меняют свои размеры в зависимости от размеров формы. Как?
Можно, конечно, повеситься на событие формы Resize и пересчитывать размеры и положение контролов, но это, честно говоря, геморой. Да и не может в такой продвинутой технологии как .Net отсутствовать возможность автоматического изменения размеров контрола. Пробежался я по списку контролов и ..., довольно скоро, я нашел то что искал. Представляю вам TableLayoutPanel. Прошу любить и жаловать.

Где взять такое чудо и что с ним можно делать? 
Все очень просто: Toolbox --> Containers --> TableLayoutPanel.
user posted image

Хватаем ее и бросаем на форму. Появляется небольшая таблица с двумя колонками и двумя строчками. Попробовали поизменять размер таблицы и, о чудо, колонки и строки ее то же меняются соответственно.
user posted image

Но всего четыре ячейки меня не устраивает. Лезем в заветный правый верхний угол и смотрим что же можно делать с этим контролом. 
user posted image

Оказывается тут тоже все просто. Можно добавлять и удалять столбцы и строки. А можно и редактировать колонки и строки в дизайнере. 
user posted image

Настойка TableLayoutPanel в дизайнере.
Нажимаем Edit Rows and Columns... Появляется окно. С помощью которого можно не только добавлять, но и настраивать нужные колонки и строки. Дальше я буду писать о колонках, но все это будет в равной мере относиться и к строкам.
Всего есть три типа размера колонок (соответственно и строк):
  • абсолютный;
  • процентный;
  • автоматический;

Абсолютный – размер колонки фиксированный, например 30 пикселей. Тогда, что бы мы ни делали с таблицей размер этой колонки так и останется 30 пикселей.
Процентный – задаем размер колонки в зависимости от ширины (для строк – высоты) всей таблицы. Если установить 25% то, что бы мы ни делали, размер колонки будет составлять ровно четверть (25%) ширины таблицы.
Автоматический – ничего задать нельзя, но размер, судя по названию, должен меняться автоматически. Наверное заполнять до конца пустое пространство, подумал я. Решил попробовать. Выбрал тип AutoSize и ... колонка пропала. Вот незадача. Полез я в MSDN, а там написано, что такая колонка будет подстраиваться под размер контролов, расположенных в этой колонке. Попробовал, вернув колонке % размер и кинув кнопку в ячейку колонки, – точно все работает как надо.
 
Как разместить несколько контролов в одной ячейке таблицы?
Ответ: никак! Ну нельзя такое сделать. Попытался кинуть в ячейку второй контрол, он кинулся, но предыдущий контрол из ячейки выпрыгнул. Но не беда. Это не критично –можно добавить еще одну колонку или строку в таблицу.

ColSpan и RowSpan
А что если я хочу чтобы мой контрол заполнил не одну ячейку а 2, 3... Стал лазить по свойствам и... ничего не нашел. Опять полез в MSDN. Нашел нужную статью. Оказывается нужные свойства есть, но не у таблицы, а у контрола, расположенного в таблице. Кто бы мог подумать.

Расположение контролов в таблице
Внутри ячейки (ячеек) контрол может лежать как угодно. Он подчиняется тем же правилам, как и в любой другой ограниченной части формы. Можно использовать докинг, а можно и анкоринг.

Пример: Расположение 6 кнопок в 2 ряда и три колонки. С расстоянием между ними 20 пикселей по горизонтали и 10 пикселей по вертикали.
Значит так. Нам нужна TableLayoutPanel с двумя строками и тремя колонками. Одинаково размера. Ширина ячеек – по 33%, высота – 50%.
Думаю никого не затруднит создать такую таблицу.
user posted image

Кликаем на первую ячейку. И добавляем 6 кнопок. Они сами расположатся по ячейкам (у меня в этом месте конкретно заглючил дизайнер, не хотел обновлять таблицу, переоткрыл дизайнер формы, стало все на свои места).
user posted image

В принципе готово. Пробуем поизменять размеры таблицы. Меняются расстояния между кнопками, а не сами контролы. 
user posted image

Нам это нужно? Нет. Идем дальше.
Выбираем все кнопки (если кто не знает, кликаем на них с зажатой клавишей Shift). Залазим в поле Anchor и выбираем все что видим: лево, право, верх, низ. Ого, наши кнопки заполнили почти всю свою ячейку. Пробуем ресайзить таблицу – все как и нужно было. 
user posted image

Действительно? Нет! Перечитываем условие: 
Цитата
С расстоянием между ними 20 пикселей по горизонтали и 10 пикселей по вертикали
 
Исправляемся: выделяем кнопки, лезем в свойство Margin (открываем его) и выставляем верх-низ по 5, лево-право по 10. 
user posted image

Теперь все. Устанавливаем у таблицы нормальную высоту (ну не нравятся мне эти пузатые кнопки).
В дополнение, установим анкор на саму таблицу (чтобы она ресайзилась вместе с формой). Запускаем приложение и любуемя полодами рук своих.

Это все. Спасибо за внимание. 
C уважением, ваш ivashkanet.
P.S. Жду ваших отзывов. 
PM MAIL WWW ICQ   Вверх
marcusmae
Дата 7.7.2006, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



Это ты по поводу недавно обсуждавшейся темы о кривом докинге? smile)) В итоге я убедился в том, что не так всё с ним плохо. Неадыкватное поведение только "по умолчанию".

Немного похоже на таблицы в HTML. А как с динамическим добавлением контролов? 


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
ivashkanet
Дата 7.7.2006, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Цитата(marcusmae @  7.7.2006,  20:58 Найти цитируемый пост)
 А как с динамическим добавлением контролов?

Как я посмотрю, это твоя больная тема smile 
ОК, добавим 
PM MAIL WWW ICQ   Вверх
ivashkanet
Дата 8.7.2006, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



TableLayoutPanel -- взгляд изнутри
Залез я, значится, в дизайнер форм, а там оказывается все проще пареной репы.
Код

this.tableLayoutPanel1.ColumnCount = 3; // Задаем количесво колонок
// Задаем стили колонок. Кстати, если поставить количество колонок больше количества стилей, то 
// появится новая колонка со стилем по умолчанию (абсолют, 20). Что и следовало ожидать.
// наоборот не работает. 
// Замечание: буква F после числа обначает, что чило типа float, а не какого-либо другого типа.
// В данном случае это излишне. Ведь конструктор принимает только float и неоднозначности 
// быть не может, но раз дизайнер посчитал что надо, значит надо.
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 30F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.AutoSize, 40F));
// Вы считаете, что число после типа AutoSize -- ошибка? Нет, это эксперимент. В котором
// выяснилось, что побарабану какое число стоит после запятой. AutoSize он и есть AutoSize
// Но, по хорошему, его нужжно убрать. Ведь у стиля есть и конструктор с одним параметром.
// В этом случае, значение берется по умолчанию 20 (думал я, а окозалось нет -- берет 0).
// Есть и коструктор совсем без параметров. Его результат -- стиль AutoSize

// Со строками все то же самое
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 34.61538F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 65.38461F));

// Пошло самое интересное. Добавление контролов.
// Все происходит, как и обычно, через метод Add свойства Controls
// Только в данном случае кроме обычного метода, принимающего всавляемый контрол, 
// есть перегруженный метод с тремы параметрами: контрол, номер столбца, номер строки 
// (хотя я бы сделал наоборот: строка, столбец. Ну да ладно...)
// Нумерация, как и везде, идет с нуля.
// Метод с одним параметром добавляет контрол в ячейку (0;0)
this.tableLayoutPanel1.Controls.Add(this.textBox1, 0,0);
this.tableLayoutPanel1.Controls.Add(this.button1, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.radioButton1, 0, 1);
// Дальше как и везде...
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.Size = new System.Drawing.Size(445, 509);
this.tableLayoutPanel1.TabIndex = 0;

P.S. Решил я посмотреть куда запихивает новое свойство контролов RowSpan, оказалось в секцию контрла, но обращается к tableLayoutPanel1
Код

            // 
            // radioButton1
            // 
            this.radioButton1.Location = new System.Drawing.Point(3, 3);
            this.radioButton1.Name = "radioButton1";
            this.tableLayoutPanel1.SetRowSpan(this.radioButton1, 2); // Вот здесь
            this.radioButton1.Size = new System.Drawing.Size(248, 302);
            this.radioButton1.TabIndex = 2;
            this.radioButton1.TabStop = true;
            this.radioButton1.Text = "radioButton1";
            this.radioButton1.UseVisualStyleBackColor = true;

Зачем такой изврат --- неизвесно, но и не столь важно.
P.P.S. Если попытаться добавить два контрола на одно место, то, как говорилось выше, первый выскочит, но его координаты какими были таким и останутся.
А если поставить в ячейку кторой нет, то дизайнер создаст нужное количество строк и столбцов.
В общем, нужно быть ооочень аккуратным с этим контролом и, ИМХО, лучше не настраивать его ручками. 
PM MAIL WWW ICQ   Вверх
dimonomid
Дата 17.12.2008, 02:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 17.1.2006

Репутация: нет
Всего: нет



господа! А как эту штуку оживить в compact framework'е? нету ее там....:(((((
А масштабировать очень надо! подскажите пожалста!
PM MAIL   Вверх
galileopro
Дата 24.10.2009, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 7.6.2009
Где: Харьков

Репутация: нет
Всего: нет



А можно как-то добавить контролы динамически не залазя в дизайнер форм? Ну скажем клацнул на кнопку и у тебя TableLayoutPanel заполнился TextBox - сами? Пожалуйста напишите, если есть время и несложно. Я хочу таким образом сделать табличку из диманически созданных TextBox - ов.

Добавлено через 2 минуты и 12 секунд
Вот типа такого(это пример, а не готовый вариан. Тут не все верно. Поэтому не ругайте меня если что)).
Код
TextBox[,] mtb = new TextBox[n, m];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                {
                    mtb[i, j] = new TextBox();
                    mtb[i, j].Left = 40+i * mtb[i, j].Width;
                    mtb[i, j].Top = 80+j * mtb[i, j].Height;
                    mtb[i, j].Parent = this;
                    mtb[i, j].Text = i.ToString() + " " + j.ToString();
                }

PM MAIL WWW ICQ   Вверх
v1rtu0z
Дата 25.11.2009, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 61
Регистрация: 21.4.2008
Где: Воронеж

Репутация: нет
Всего: нет



Конечно можно. Это есть в 4м посте темы

Это сообщение отредактировал(а) v1rtu0z - 25.11.2009, 12:29
PM MAIL ICQ   Вверх
Blazkovicz
Дата 7.12.2009, 15:06 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 21.11.2007

Репутация: нет
Всего: нет



Надо разместить два контрола, которые будут расширяться процентно и 1 контрол между ними, который имеет автосайз?
Можно ли как-то избежать указания точных цифр для процентов, если расширяться контролы будут одинаково?

Это сообщение отредактировал(а) Blazkovicz - 9.12.2009, 11:21
PM MAIL   Вверх
alexsher
Дата 3.4.2012, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 3.4.2012

Репутация: нет
Всего: нет



Приветствую! Это все хорошо, но у меня на форме 56 таких панелей)) и все это грузится долго и не эстетично) может знает кто, как избежать этого?)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0795 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.