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

Создание оконных приложений Windows Forms

Размещение в пользовательском окне элементов управления

Будем называть наш класс, наследующий от Form, пользовательским окном. Разместим в окне элемент управления типа кнопки, которая порождается классом Button. Все элементы управления являются визуальными и наследуют от класса Control. В следующей программе показано, как создать объект Button, поместить его на поверхность формы и подключить обработчик к событию Click этой кнопки. Продемонстрированы разные способы настройки и управления кнопками.

using System;
using System.Windows.Forms;
using System.Drawing;
    
namespace MyApp
{
    // Наследует библиотечному классу
    class MyForm : Form
    {
        // Конструктор с настройками
        public MyForm()
        {
            // Начальная настройка окна
            this.Text = "Форма с кнопками";
    
            // Создание и настройка первой кнопки
            Button btn = new Button(); // Создаем первую объект-кнопку
            btn.Text = "Кнопка 1"; // Надпись на первой кнопке
            btn.AutoSize = true; // Подстройка размеров под надпись
            int left = (this.ClientSize.Width - btn.Width) / 2;
            int top = (this.ClientSize.Height - btn.Height) / 2;
            btn.Location = new Point(left, top);   // Координаты кнопки в 
                                                // клиентской области формы
            btn.Click += ButtonOnClick;// Подключение обработчика к событию Click
            btn.Parent = this;  // Присоединяем к форме первую кнопку
                                // и освобождаем ссылочную переменную
    
            // Создание и настройка второй кнопки
            btn = new Button(); // Используем освободившуюся адресную переменную
            btn.Text = "Кнопка 2";
            btn.AutoSize = true;
            top += (this.ClientSize.Height - top) / 2;  // Расположим ниже
            btn.Location = new Point(left, top);
            btn.Click += ButtonOnClick; // Присоединяем тот же обработчик
            btn.Enabled = false;    // Сначала недоступна
            this.Controls.Add(btn); // Другой способ присоединения к форме
            btn = null; // Освобождаем ссылку
        }
    
        // Флаг состояния доступности (закрытое поле класса)
        private bool enableButton = true;
    
        void ButtonOnClick(object sender, EventArgs e)
        {
            if (enableButton)
                MessageBox.Show("Произошел щелчок на первой кнопке!");
            else
                MessageBox.Show("Произошел щелчок на второй кнопке!");
    
            // Перебираем коллекцию из двух кнопок и меняем доступность
            foreach (Control ctrl in this.Controls)
                ctrl.Enabled = !ctrl.Enabled;
    
            enableButton = !enableButton;
        }
    }
}
Листинг 6.15 . Код файла MyForm.cs
using System.Windows.Forms;
// Лишние пространства имен удалили
    
namespace MyApp
{
    class EntryPoint
    {
        public static void Main()
        {
            Application.EnableVisualStyles();
            Application.Run(new MyForm());
        }
    }
}
Листинг 6.16 . Код файла Program.cs

Использованный в функции Main() метод Application.EnableVisualStyles() класса позволяет задать современный внешний вид для некоторых элементов управления. Созданная форма с кнопками будет такой


Размещенные на форме кнопки являются ее дочерними объектами и размещаются в коллекции Controls. Учитывая, что в нашем примере дочерними элементами являются только две кнопки, мы не принимали специальные меры для их распознавания. Но в более сложных случаях элементам нужно присваивать имена в их свойстве Name и распознавать уже по значению этого свойства. Для поиска конкретного объекта Control годится как простой перебор всех элементов коллекции Controls формы, так и метод System.Windows.Forms.Control.ControlCollection.Find(string, bool).

Все дочерние элементы формы располагаются в Z-порядке ( Z -последовательности), определяющим их видимость на экране, и могут перекрывать друг друга. Начальный Z -порядок определается порядком добавления элементов к форме и противоположен индексам элементов в коллекции формы: более поздние элементы отображаются верхними. Для изменения Z -порядка в процессе выполнения программы используются методы BringToFront() и SendToBack() класса Control.

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

В объектно-ориентированном программировании существует два способа передачи кода одного класса другому: это композиция и наследование. Композицией называется создание экземпляра одного класса внутри другого с последующим использованием объекта, а наследование передает код базового класса в производный неявно, сливая вместе два или целую цепочку классов.

Наследование применяют обычно к формам, а композицию - при размещении на форме библиотечных элементов управления. Но библиотечные элементы управления также можно использовать как базовые при наследовании, расширяя их производным классом.

Для примера создадим класс, расширяющий библиотечный класс Button, в котором определим такое поведение кнопки, что если надпись на ней не превышает заданную длину, то она остается недоступной на форме. Для изменения надписи кнопки предусмотрим текстовое поле ввода типа TextBox.

using System;
using System.Windows.Forms;
using System.Drawing;
    
namespace MyApp
{
    // Наследует библиотечному классу
    class MyForm : Form
    {
        // Локальные поля формы
        TextBox txtbox;
        ExtensionButton btn;
    
        // Конструктор с настройками
        public MyForm()
        {
            // Начальная настройка окна
            this.Text = "Форма с \"умной\" кнопкой";
    
            // Создание и настройка объекта TextBox
            txtbox = new TextBox();
            txtbox.Text = "Кнопка";
            txtbox.CharacterCasing = CharacterCasing.Upper;
            txtbox.Width = 150;
            int left = (this.ClientSize.Width - txtbox.Width) / 2;
            int top = (this.ClientSize.Height - txtbox.Height) / 3;
            txtbox.Location = new Point(left, top);
            txtbox.Focus();
            txtbox.Parent = this;
            // Подписка объекта TextBox на событие 
            txtbox.TextChanged += new EventHandler(txtbox_TextChanged);
    
            // Создание и настройка объекта умной кнопки
            btn = new ExtensionButton(); // Создаем умную кнопку
            btn.StrTextBox = txtbox.Text; // Начальная надпись на кнопке
            btn.AutoSize = true; // Подстройка размеров под надпись
            left = (this.ClientSize.Width - btn.Width) / 2;
            top += (this.ClientSize.Height - top) / 2;
            btn.Location = new Point(left, top);
            btn.Parent = this;  // Присоединяем кнопку к форме
        }
    
        void txtbox_TextChanged(object sender, EventArgs e)
        {
            // Меняем значение надписи на кнопке
            // с одновременным контролем доступности
            btn.StrTextBox = txtbox.Text;
        }
    }
    
    // Класс расширения кнопки
    class ExtensionButton : Button
    {
        // Локальное поле-константа
        private const int MIN_DISABLED = 5;
    
        // Публичное свойство
        public string StrTextBox
        {
            set 
            { 
                this.Text = value;
                bool enabled = value != null && 
      value.Length > MIN_DISABLED;
                this.Enabled = enabled;
            }
        }
    }
}
Листинг 6.17 . Код файла MyForm.cs
using System.Windows.Forms;
// Лишние пространства имен удалили
    
namespace MyApp
{
    class EntryPoint
    {
        public static void Main()
        {
            Application.EnableVisualStyles();
            Application.Run(new MyForm());
        }
    }
}
Листинг 6.18 . Код файла Program.cs

Результат выполнения программы будет таким


Автоматическое масштабирование окон

Проектируя приложение, разработчик не знает, на экранах с каким разрешением оно будет работать. Если не принять специальных мер, то при установке малых разрешений окно будет казаться большим, а при установке больших - маленьким относительно экрана. Для автоматического масштабирования окон приложения в зависимости от разрешения экрана в классе Form имеются два свойства: AutoScaleDimensions и AutoScaleMode, наследуемые от класса ContainerControl, которые и решают эту задачу.

Свойства должны задаваться точно в указанном ниже порядке:

AutoScaleDimensions = new Size(4, 8);
AutoScaleMode = AutoScaleMode.Font;

или

AutoScaleDimensions = new SizeF(96, 96);
AutoScaleMode = AutoScaleMode.Dpi

или

AutoScaleDimensions = new SizeF(120, 120);
AutoScaleMode = AutoScaleMode.Dpi

Перечисление AutoScaleMode имеет значения: Dpi, Font, Inherit, None. Значение Font устанавливает привязку к размерам стандартного значения шрифта Windows, значение Dpi - к разрешению экрана.

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

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

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

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

 

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