Автоматичне масштабування форми

Припустимо, ви створювали форму при розмірі системного шрифту,
встановленого через аплет Display (Екран) панелі управління в Normal
(Звичайний) (96 DPI). Що буде, якщо користувач змінить шрифт на Large
(Великий) (120 DPI) або вибере якесь нестандартне значення?
Очевидно, вам хотілося б, щоб форма кшталт наведеної на рис. 1
правильно показувалася за будь-яких розмірах шрифту.

Рис. 1. Приклад форми при звичайному розмірі шрифту

Якщо ви проведете тест, змінивши розмір з шрифту з звичайного на великий
у Display (Microsoft Windows ® XP вимагатиме перезавантаження), то виявите,
що форма з новим шрифтом виглядає, як показано на рис. 2, причому
повторна компіляція програми не знадобиться.

Рис. 2. Приклад форми з великими шрифтами

Весь секрет у властивості форми AutoScale. Якщо AutoScale дорівнює true (за
замовчуванням), при першому завантаженні форми зчитується інша властивість –
AutoScaleBaseSize. Воно встановлюється дизайнером і містить середню
ширину і висоту символів у шрифті форми. Шрифт за замовчуванням – 8.25 pt MS
Sans Serif при установці звичайного розміру шрифту в Windows XP – має
середню ширину і висоту 5×13. Ця інформація записується у функції
InitializeComponent так:

this.AutoScaleBaseSize = new Size(5, 13);

При використанні великих шрифтів (шрифт за замовчуванням – 7.8 pt MS
Sans Serif) середня ширина і висота виявляються рівні 6×15 (саме
тому такі шрифти називаються "великими"). При завантаженні форма, викликавши
Form.GetAutoScaleSize, виявить зміна масштабу, в якому вона
створювалася, у порівнянні з поточним і змінить як свою висоту і ширину,
так і висоту і ширину всіх елементів управління (в тому числі їхніх
позиції). Завдяки цьому форма виглядає приблизно однаково поза
залежно від системних параметрів шрифтів.

Прив'язка (Anchoring)

Звичайно, одного масштабування системних параметрів шрифтів
недостатньо для підтримки підстроювання форми під запити користувачів.
Так, якщо користувач в нашому прикладі захоче ввести в текстове поле
більш довгий рядок, він може спробувати розтягнути форму, як показано
на рис. 3.

Рис. 3. Всі елементи управління прив'язані до верхньої лівої точці

На жаль, користувач навряд чи зрадіє тому, що форма стане більше, а
містяться на ній елементи управління – немає. В ідеалі текстове поле
повинно розширюватися одночасно з формою. Цього можна домогтися приблизно
так:

int delta = 0;

void Form1_Load(object sender, EventArgs e) {
  delta = ClientRectangle.Width - textBox1.Width;
}

void Form1_SizeChanged(object sender, EventArgs e) {
  textBox1.Width = ClientRectangle.Width - delta;
}

Під час події Load форми ми запам'ятовуємо різницю між шириною
текстового поля і шириною клієнтської прямокутної області, а при
зміні розміру форми встановлюємо ширину поля так, щоб різниця
залишалася постійною. А значить, відстань від правого краю текстового
поля до правого краю форми залишається незмінним. Цей процес називається
прив'язкою (anchoring). За замовчуванням всі елементи управління прив'язані до
лівим і верхніх краях свого контейнера (форми чи елементу керування,
містить інші елементи). Ми звикли, що операційна система
переміщує дочірні елементи керування так, що ті залишаються на
постійній відстані від лівого і верхнього країв контейнера. Проте це
все, на що здатна операційна система. Тому що вона не в змозі
змінити розмір наших елементів управління, прив'язуючи їх до інших
краях, для зміни розміру потрібно писати код. Або, як роблять частіше,
використовувати стилі з фіксованими розмірами форми. На щастя, в
Windows Forms вбудована підтримка прив'язки, що повністю позбавляє від
необхідність написання такого коду.

Щоб змінити краю, до яких прив'язується елемент управління,
змініть властивість Anchor на будь-яку побітове комбінацію значень з
перечислимого AnchorStyles:

enum AnchorStyles {
  None,
Left, / / за замовчуванням
Top, / / за замовчуванням
  Bottom,
  Right,
}

У нашому прикладі для зміни розміру текстового поля у відповідності
зі зміною розміру форми необхідно включити до властивість Anchor правий,
а також лівий і верхній краю. Property Browser навіть дозволяє
використовувати вельми незвичайний редактор, наведений на рис. 4.

Рис. 10. TabControl з двома елементами управління TabPage

Нестандартна розмітка форми

Поєднуючи прив'язку, стиковку, поділ і группіровваніе можна вирішити
переважна більшість завдань, пов'язаних з розміткою форм. Але не всі.
Так, автоматичне розтягування елементів управління пропорційно
клієнтської області, в якій розміщено таблицю або сітка (як показано
на рис. 11), реалізувати за допомогою цих способів не вдасться.

Рис. 11. Приклад нестандартної розмітки

Щоб створити форму, як на рис. 11, краще всього вичавити максимум
можливого з вже описаних способів, а решту зробити в обробнику
події Layout форми або елементів-контейнерів. Наприклад, наступний
обробник цієї події розміщує дев'ять кнопок у відповідності з
змінюються розмірами форми:

void GridForm_Layout(object sender, LayoutEventArgs e) {
/ / Розмістити кнопки в сітці на формі
  Button[] buttons = new Button[] { button1, button2, ..., };
  int cx = ClientRectangle.Width/3;
  int cy = ClientRectangle.Height/3;
  for( int row = 0; row != 3; ++row ) {
    for( int col = 0; col != 3; ++col ) {
      Button button = buttons[col * 3 + row];
      button.SetBounds(cx * row, cy * col, cx, cy);
    }
  }
}

Висновок

Масштабування дозволяє розміщувати елементи управління на формі на
етапі розробки при використанні одних налаштувань системних шрифтів і в
той же час добитися коректного відображення форми при інших настройках
системних шрифтів у період виконання. Наприклад, навіть якщо на етапі
розробки встановлено системний шрифт звичайного розміру, форма буде
правильно виглядати і при використанні великих шрифтів. Прив'язка
дозволяє змінювати розміри і переміщати елементи управління з фіксацією
їх по відношенню до певних краях форми. Стиковка фіксує елемент
управління на конкретному краї. Поділ дає можливість змінювати
розміри пристикованим елементів управління, а групування – розбивати
елементи керування на невеликі групи, якими легше управляти. Якщо
ж нічого з цього не допомагає, зайдіть з "чорного ходу" –
скористайтеся подією Layout, який дозволяє досягти функціональності,
недосяжною з допомогою вищезгаданого арсеналу засобів.

Примітка Цей
матеріал взято з підготовлюваної до публікації у видавництві Addison-Wesley
книги Кріса Селлза "Programming Windows Forms Applications with C #"
(0321116208). Наведений тут матеріал – чернетка того, що з'явиться в
опублікованій книзі.

Кріс Селлз (Chris
Sells) – незалежний консультант і викладач в DevelopMentor.
Спеціалізується на розподілених додатках ст. NET і COM. Автор
кількох книг, у тому числі "ATL Internals", яка в даний час
переробляється для обліку змін, що з'явилися в ATL7. Крім того,
працює над книгами "Essential Windows Forms" (Addison-Wesley) і
"Mastering Visual Studio. NET" (O "Reilly). У вільний час Кріс
підтримує Web-сервіси DevCon і керує Genghis – проектом з
відкритим вихідним кодом. Більш докладну інформацію про нього і про його
численних проектах див. на сайті
http://www.sellsbrothers.com.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*