#c# #winforms #tabcontrol #autosize
Вопрос:
У меня есть форма Windows с элементом управления вкладками и представлением списка.
Когда я запускаю приложение, я хочу, Width
чтобы элемент управления вкладками увеличивался/уменьшался, чтобы показывать все страницы вкладок без горизонтальной полосы прокрутки и Width
соответственно изменять размер формы, чтобы обеспечить видимость элемента управления вкладками и представления списка.
Ниже приведен скриншот.
Комментарии:
1. Как пользователь, я бы возненавидел эту идею (автоматического изменения размеров форм), так как это будет мешать макету, который я выбрал для своего рабочего стола. И, конечно же, скоро он достигнет ограничений по размеру экрана.
Ответ №1:
Чтобы автоматически изменить размер элемента управления TabControl до размера его заголовков, вам необходимо рассчитать ширину текста каждого заголовка. Это проще в случае, если для TabControl.SizeMode установлено значение Fixed, так как вы можете задать размер элемента.Ширина и все заголовки будут иметь одинаковую ширину.
Если TabControl.SizeMode
установлено значение по умолчанию Normal
, вам нужно измерить текст каждого заголовка, добавив 1px
для границы ( 2px
если это вторая страница вкладки — небольшая ошибка в базовом элементе управления).
В первом случае размер элемента управления TabControl равен:
tabControl1.Width = tabControl1.TabPages.Count * (tabControl1.ItemSize.Width 1);
во втором случае измерьте текст каждого заголовка с помощью TextRendrer.Измерительный текст:
private int MeasureTabPagesWidth(TabControl tc)
{
if (tc.TabPages.Count == 0) return tc.Width;
int newWidth = 0;
int border = tc.TabPages.Count == 2 ? 2 : 1;
var flags = TextFormatFlags.LeftAndRightPadding;
using (var g = tc.CreateGraphics()) {
foreach (TabPage tab in tc.TabPages) {
newWidth = TextRenderer.MeasureText(g, tab.Text, tc.Font,
new Size(int.MaxValue, tc.Font.Height 4), flags).Width border;
}
}
return newWidth;
}
Настройка макета:
- Добавьте панель TableLayoutPanel в свою форму с одной строкой и двумя столбцами (т. Е. Удалите одну строку).
- Добавьте элемент управления TabControl в ячейку слева, а поле списка — в другую ячейку.
- Установите стиль обеих ячеек
AutoSize
равным (после добавления элементов управления). - Установите панель TableLayoutPanel в положение:
AutoSize = true
,AutoSizeMode
= GrowAndShrink
- Таким же образом установите для формы автоматический размер
- Установите минимальный и максимальный размеры формы. Первый обычно устанавливается в размер дизайна, второй зависит от вас; вы можете использовать текущую рабочую область экрана в качестве ссылки.
- Рассчитайте новую ширину элемента управления TabControl при создании или загрузке Формы (т. Е. в его конструкторе или
OnLoad()
илиForm.Load
), чтобы форма автоматически изменяла размер до размера панели TableLayoutPanel, которая, в свою очередь, автоматически изменяла размер своих дочерних элементов управления.
Теперь вы можете добавлять или удалять страницы вкладок во время выполнения, и форма автоматически изменит размер до ширины, рассчитанной в элементе управления вкладками.Controlled и TabControl.Обработчики событий ControlRemoved (также проверяется, имеет ли добавленный элемент управления тип TabPage
).
Пример:
- Этот
MeasureTabPagesWidth()
метод показан выше. - Панель TableLayoutPanel называется
tlp1
- Элемент управления TabControl называется
tabControl1
- Кнопки, используемые в наглядном примере, имеют имена, определяющие их роль.
public partial class AutoSizeForm : Form
{
public AutoSizeForm()
{
InitializeComponent();
tabControl1.Width = MeasureTabPagesWidth(tabControl1);
}
private void tabControl1_ControlAdded(object sender, ControlEventArgs e)
{
// Event notified after the TabPage has been added
if (e.Control is TabPage) {
tabControl1.Width = MeasureTabPagesWidth(tabControl1);
}
}
private void tabControl1_ControlRemoved(object sender, ControlEventArgs e)
{
if (e.Control is TabPage) {
// Use deferred execution, since the TabPage is removed after
// the event handler method completes.
BeginInvoke(new Action(()=> tabControl1.Width = MeasureTabPagesWidth(tabControl1)));
}
}
private void btnAddPage_Click(object sender, EventArgs e)
{
tabControl1.TabPages.Add(new TabPage("New TabpPage Text"));
}
private void btnRemovePage_Click(object sender, EventArgs e)
{
if (tabControl1.TabPages.Count > 0) {
tabControl1.TabPages.RemoveAt(tabControl1.TabPages.Count - 1);
}
}
private void btnAddCtlToTLP_Click(object sender, EventArgs e)
{
tlp1.ColumnCount = 1;
tlp1.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
var mc = new MonthCalendar();
tlp1.SetColumn(mc, tlp1.ColumnCount - 1);
tlp1.Controls.Add(mc);
}
}
Вот как это работает:
Протестировано в Windows 7, так как, похоже, это используемая система
Пример Проекта:
Пример проекта на Google Диске ( .Net Framework 4.8
— C# 7.3
)
Перестройте решение перед запуском
Комментарии:
1. Я скопировал ваш код ver batim в свой проект после просмотра кода вашего проекта и не смог понять, почему размер моей формы изменился неправильно, затем я посмотрел на шрифт элементов управления вкладками, и когда я изменил его на Segio UI 9pt, это сработало для меня. Я согласен… если страниц будет слишком много, форма выйдет из-под контроля. Придется спросить об этом моего руководителя проекта.
2. Тоже Джими… Могу я, пожалуйста, спросить вас, какую программу вы используете для создания анимации захвата экрана, показывающей, как элемент управления вкладками растет и уменьшается? Я надеюсь, что это БЕСПЛАТНО, так как я хотел бы использовать это для будущих снимков экрана. Спасибо
3. Что касается размера формы, вы можете задать это
MaximumSize
свойство.MinimumSize
Свойству обычно присваивается размер дизайна. Я добавил заметку об этом. — Шрифт не проблема: проверьте дальше, в чем была разница. — Анимационная программа здесь создана ScreenToGif и, да, она бесплатная и с открытым исходным кодом (обновляйте ее каждый раз, когда она запрашивает ее).
Ответ №2:
Начиная с этой формы, я собираюсь добавить 8 вкладок во время выполнения, рассчитать ширину текста на вкладках размер заполнения x2 (с обеих сторон вкладок), а затем изменить размер элементов управления по мере необходимости.
public Form1()
{
InitializeComponent();
//Clear our default tabs.
tabControl1.TabPages.Clear();
//Add more tabs than would be visible by default
for (int i=1;i<=8;i )
{
tabControl1.TabPages.Add("Tab " i.ToString());
}
ResizeTabControl();
ResizeListViewControl();
ResizeForm();
}
void ResizeTabControl()
{
int tabCount = tabControl1.TabCount;
float length = 0;
using (Graphics g = CreateGraphics())
{
//Iterate through the tabs and get the length of the text.
for (int i = 0; i <= tabCount - 1; i )
length = g.MeasureString(tabControl1.TabPages[i].Text, tabControl1.Font).Width;
}
//Resize the tab control where X is the length of all text in the tabs plus padding x 2 x total tabs.
tabControl1.Size = new Size(Convert.ToInt32(length) (tabCount * 2 * tabControl1.Padding.X), tabControl1.Width);
}
void ResizeListViewControl()
{
//Move listview 10 pixels away from tabcontrol's edge
listView1.Location = new Point(tabControl1.Location.X tabControl1.Width 10, listView1.Location.Y);
}
void ResizeForm()
{
//Resize form to accomodate changes.
this.Width = listView1.Location.X listView1.Width 20;
}
После того, как все это сказано и сделано, вот как это выглядит:
Комментарии:
1.
using (Graphics g = CreateGraphics())
=> >using (var g = tabControl1.CreateGraphics())
(лучше используйте графику элемента управления, который вы на самом деле измеряете )-Как описано в комментариях, с помощью панели автоматического определения размеров TableLayoutPanel вам просто нужно установитьForm.AutoSize = true
(плюсGrowAndShrink
). Никаких других вычислений не требуется (это лучше из-за изменения размера точек на дюйм на разных экранах, иначе вам тоже пришлось бы это учитывать).2. Кстати, вы должны использовать
TextRenderer.MeasureText()
с.TextFormatFlags.LeftAndRightPadding
Затем вам просто нужно добавить1
в размерWidth
каждого фрагмента текста (чтобы включить рамку размером 1 пиксель).3. Большое спасибо, Микаэль. Ваш код работает, но высота tabControl1 занимает всю высоту формы. Как это можно изменить, чтобы использовать только длину элемента управления вкладкой?
4. Кроме того, после вкладки 8 в вашем примере есть некоторое дополнение к концу. Как это можно удалить?