C #, Windows Forms, Best / min подходит окно к содержанию - PullRequest
4 голосов
/ 14 мая 2009

У меня есть форма с некоторыми элементами управления. (На самом деле, это своего рода постоянная проблема.) Некоторые из форм, которые я имел, имеют изменяемый размер, некоторые нет. Независимо от того, когда форма отображается, было бы хорошо, чтобы она отображалась в необходимом «минимальном» размере. Другие наборы инструментов для работы с окнами, такие как wxWidgets (wxWindow :: GetMinSize) и Qt (QWidget ::imumSize), имеют эту функциональность.

Эта функциональность, если вы с ней не знакомы, позволяет окну изменять размер до минимального размера, который часто является всем необходимым для окна, и выглядит довольно красиво. Если у меня есть два статических текста и два поля редактирования, выложенные таким образом:

Username:
[ Edit/text box for user's password]
Password:
[ Edit/text box for user's password]
              [  Cancel  ][   OK   ]

Затем я могу указать этой форме изменить ее размер до «минимального размера», и она будет выглядеть так же, как указано выше. (Минимальная ширина в текстовом поле частично субъективна - я должен был бы установить это сам в одном / обоих текстовых полях, но форма будет запрашивать дочерние элементы управления и узнавать об этой минимальной ширине) Обычно это сочетается с какими-то макетами. (Который .Net имеет.)

Это дает дополнительное преимущество, заключающееся в том, что форма имеет правильный размер независимо от настроек шрифта, локали, dpi, обложки графического интерфейса и т. Д. (Если все сделано правильно, по крайней мере.)

Существует ли это в .Net, и если да, то где? Если вам нужно больше описания, спросите, и я буду рад предоставить.

Edit: я ищу приведенный выше пример, изменяемый размер только в направлении X (я готов принять оба), но не может быть изменен размер меньше, чем определенный W / H. Элементы управления должны быть привязаны - т.е. текстовые поля становятся больше, кнопки остаются выровненными по правому краю.

Редактировать: я могу делать изображения! Предположительно они стоят тысячи слов: альтернативный текст http://www.freeimagehosting.net/uploads/79e9ee10e5.png

Редактировать: Полагаю, я начну отмечать ответы. От ответа Хенка меня довольно далеко задел диалоговое окно без изменения размера, соответствующее его содержанию. Большинство постов, представленных ниже, являются ценными, но они упускают суть (разве я здесь действительно не в курсе?): Я понимаю, как использовать Anchor / TableLayout и получить элементы управления для потока - в основном это было одно или оба измерения диалог, чтобы соответствовать содержанию диалога. По сути, у вас есть три случая:

  1. Диалог не изменяемого размера - см. Ответ Хенка. В сочетании с TableLayout и Anchors вы получите приличный диалог.

  2. Размер диалогового окна можно изменять только в одном измерении - перейдите с 1 или 3 - Вы можете ограничить измерение с помощью события Resize, но диалоговое окно ужасно мерцает. (Насколько я могу судить, это кажется недостатком в Win32 - есть некоторые вещи о переопределении фонового стирания, которое работает для элементов управления, но не для окон, так как вы получите артефакты на фоне формы (потому что вы не стираю их). Реальный ответ заключается в том, что это, вероятно, должно быть обработано самой Win32 - мне не нужно изобретать колесо двойного буфера просто для того, чтобы получить приличный диалог взгляда ...))

  3. Диалог полностью изменяемого размера. Якоря и TableLayout ваш друг. К сожалению, атрибут MinimumSize кажется фальшивым (по крайней мере, я не знаю, для чего он ...) - например, если вы запрашиваете MinimumSize текстового поля, по умолчанию высота составляет 4 пикселя. Кроме того, свойство MinimumSize, по-видимому, не распространено - элемент управления не запрашивает своих детей. (Я могу изменить размер формы меньше, чем текстовое поле внутри формы, и тогда текстовое поле будет за пределами формы.) Если вам интересно, о чем я болтаю, посмотрите wxWidgets и как работают макеты и минимальный размер.

С тех пор я также обнаружил, что .Net, похоже, не уважает системный шрифт и всегда использует один и тот же шрифт для форм, поэтому изменения шрифта не повлияют на мой диалог (к сожалению), что облегчает большинство моих забот (к счастью) ?). Опять же, обратитесь к тому, как это делает wxWidgets - если системный шрифт 22pt, все wxFrames (формы) уважают и изменяют размеры соответственно. .Net должен попасть в этот поезд ... (И я знаю человека, который ежедневно использует шрифт 22 + pt для своего стандартного шрифта GUI.)

Ответы [ 6 ]

4 голосов
/ 15 мая 2009

Я обрабатываю такие вещи, используя TableLayoutPanel . TableLayoutPanel позволяет вам размещать элементы управления в столбцах и строках. Столбцы и строки имеют три типа размера: AutoSize, Percent и Absolute. AutoSize размеры столбца или строки в соответствии с минимально необходимым значением, Percent размеры столбца или строки в процентах от неиспользуемой области и Absolute размеры столбца или строки в соответствии с абсолютным количеством пикселей.

Дизайнер VisualStudio полезен. Если вы предпочитаете писать весь код вручную, по-прежнему неплохо поиграть с TableLayoutPanel в конструкторе и изучить полученный код конструктора, чтобы узнать, как работать с TableLayoutPanel.

Чтобы получить минимально необходимый размер, необходимо:

  • Док. Заполните таблицу TableLayoutPanel в вашей форме.
  • Док. Заполните элементы управления в ячейках.
  • Обработка расстояния между элементами управления с помощью Control.Margin.
  • Сделать SizeType всех столбцов и строк AutoSize.

Кроме того, вы можете использовать ColumnSpan и RowSpan, чтобы элемент управления занимал несколько ячеек.

После того, как вы настроите все так, как вы хотите, чтобы они выглядели, вы можете использовать TableLayoutPanel.GetPreferredSize (), чтобы определить минимальную необходимую площадь TableLayoutPanel и назначить это значение в Form.ClientSize.

Если пользователь сможет изменить размер вашей формы, после того, как вы определили минимальный требуемый размер, вы должны установить SizeType столбца и строки, которую вы хотите увеличить с формой, на SizeType.Percent и использовать значение 100, например это:

// "columnIndex" is the zero based index of the column
this.tableLayoutPanel.ColumnStyles[columnIndex] = new ColumnStyle(SizeType.Percent, 100);

// "rowIndex" is the zero based index of the row
this.tableLayoutPanel.RowStyles[rowIndex] = new RowStyle(SizeType.Percent, 100);
4 голосов
/ 14 мая 2009

Что-то приближается, попробуйте следующее: создайте свою форму немного большим и избегайте пристыкованных элементов управления справа и снизу. Тогда какой-нибудь код вроде этого:

private void button1_Click(object sender, EventArgs e)
{
    this.AutoSize = true;
    this.Size = new Size(10, 10);
}

AutoSize найдет расширение элементов управления.

3 голосов
/ 14 мая 2009

Вот как я обычно справляюсь с этим случаем с помощью привязки: установите привязку меток на Top, Left (по умолчанию); Текстовые поля сверху, слева, справа; и кнопки внизу, справа. Размер формы в конструкторе до желаемого минимального размера. В конструкторе установите для свойства MinimumSize формы текущий размер.

Во время выполнения пользователь может изменить размер формы. Метки не будут двигаться, текстовые поля будут растягиваться горизонтально, но не вертикально. Кнопки будут двигаться с правым и нижним краями формы. Пользователь не сможет сделать форму (и его элементы управления меньше, чем MinimumSize).

Надеюсь, это поможет.

1 голос
/ 15 мая 2009

Используйте свойства формы MaximumSize и MinimumSize , а также свойства привязки элементов управления.

// make the form 200 pixels high, without possibility to resize the height
// and restrict the minimum width to 200 pixels
this.MinimumSize = new Size(200, 200);
this.MaximumSize = new Size(30000, 200);
0 голосов
/ 07 октября 2009

Вне моей головы (читай: я не проверял это), я думаю, вы можете перебирать все дочерние элементы управления при загрузке формы и определять ее минимальный размер. Затем вы можете установить форму на этот размер и установить ее свойство MinimumSize, чтобы его нельзя было изменить на что-то меньшее.

Примерно так, с использованием LINQ:

OnLoad()
{
    int right = this.Controls.Cast<Control>().Max(c => c.Right);
    int bottom = this.Controls.Cast<Control>().Max(c => c.Bottom);

    // leave a little padding, add maybe 10px or 10%?
    int minWidth = right + 10;
    int minHeight = bottom + 10;

    this.Size = new Size(minWidth, minHeight);
    this.MinimumSize = new Size(minWidth, minHeight);
}

О шрифте WinForms, по-видимому, это ошибка версии 1.0, которая была перенесена для совместимости. (см. здесь и здесь .) Вы можете обойти это, установив this.Font = SystemFonts.DialogFont при загрузке формы. Это, однако, не отображается в режиме разработки. Чтобы обойти это, установите шрифт в BaseForm и извлеките из него все свои формы.

Обновление: я вижу, как это может быть проблемой, если у вас есть правый или нижний элемент управления. Он будет использовать их текущее положение и размер, а не вычислять минимум для размера, когда они не будут сжиматься в другие элементы управления или станут слишком маленькими. Может быть, вы можете установить их привязки программно после того, как вы изменили размер формы.

0 голосов
/ 14 мая 2009

Звучит так, как будто вам нужны свойства Dock и Anchor.

Здесь - первая ссылка от Google.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...