Назад Вперед Зміст

Багатовіконний інтерфейс

Додаток, який використовує кілька вікон, називається багатовіконним.

З точки зору програмування, кожне вікно є формою. Тобто, багатовіконний інтерфейс - це інтерфейс з кількох пов'язаних форм.

Для Windows-додатка за замовчуванням створюється клас Form1, який є похідним від класу Form. Якщо в проект додається нова форма, використовуючи пункт меню Проект, Додати форму, то створюється об'єкт класу Form2, Form3,... Усі ці класи також є похідними від класу Form.

Додавання ще однієї форми

Щоб додати ще одну форму до проекту, потрібно виконати наступну команду:

Отримуємо:

Вказуємо ім'я форми або залишаємо запропоноване та натискаємо "Додати".

Дії з вікнами (формами)

Форму можна:

Можливі помилки

Якщо ми хочемо, щоб у кожний поточний момент була відкрита тільки одна форма, потрібно вжити певні заходи, щоб при закритті (приховуванні) форми відкривалась інша форма.

В іншому випадку можлива неприємна ситуація, коли всі форми закриті, і нічого не можна зробити, але додаток не завершений.

Звичайно, завжди є вихід - завжди можна натиснути комбінацію клавіш CTRL + ALT + DEL і завершити будь-який додаток за допомогою Диспетчера завдань.

Види вікон

Головне вікно

Кожне додаток містить одне головне вікно - клас Form1. Клас головного вікна додатку містить точку входу в додаток (статичний метод Main у класі Program).

При закритті головного вікна, закриваються всі інші вікна, і додаток завершує роботу. Зазвичай головна форма проекту завжди відкрита, тоді як інші форми проекту відкриваються і закриваються (приховуються). Завершити додаток програмно можна за допомогою статичного методу Exit класу Application.

Головне вікно створюється автоматично при створенні додатка.

Діалогові вікна

Діалогові вікна використовуються для введення деякої інформації.

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

Для відображення форми як модального вікна використовується метод ShowDialog, а також встановлюються наступні властивості:

Інформаційні вікна

Інформаційні вікна - це немодальні вікна.

Вони використовуються в тих випадках, коли користувач сам обирає - залишити на екрані певну інформацію чи ні.

Для відкриття такої форми використовується метод Show.

Передача даних з вікна в вікно

При створенні багатовіконних додатків доводиться передавати деякі дані з одного вікна в інше. Розглянемо два способи передачі даних:

  1. Дані, які потрібно передати, зберігаються в допоміжному статичному класі. Дані цього класу можуть використовуватися в будь-якому іншому класі.
  2. При створенні об'єкта за допомогою конструктора можна передати форму як параметр.

Приклад

Створимо додаток з чотирма вікнами. Для передачі даних з одного вікна в інше, скористаємося допоміжним статичним класом.

  1. Form1 - Головне вікно, що містить три кнопки: "Введення даних", "Результати" і "Про розробника".

  2. Form2 - Діалогове вікно, яке створюється при натисканні кнопки "Введення даних". У цьому класі здійснюється введення даних і обчислення. Результати обчислень зберігаються в статичному класі.

  3. Form3 - Інформаційне вікно, яке створюється при натисканні кнопки "Результати". У цьому вікні виводяться результати. Результати зчитуються зі статичного класу.

  4. Form4 - Інформаційне вікно, яке створюється при натисканні кнопки "Про розробника" і в яке виводиться прізвище та ім'я розробника.

У класі Form1

Елементи форми:

Обробники події Click для кожної кнопки:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        
        // Налаштування властивостей форми
        this.Text = "Головне меню";
        this.Size = new Size(400, 300);
        this.StartPosition = FormStartPosition.CenterScreen;
        this.BackColor = Color.LightGray;
        
        // Налаштування кнопок
        button1.Text = "Калькулятор параметрів";
        button2.Text = "Перегляд результатів";
        button3.Text = "Інформація про розробника";
        
        // Додаткові налаштування стилів
        foreach (Button btn in this.Controls.OfType<Button>())
        {
            btn.Font = new Font("Arial", 10, FontStyle.Bold);
            btn.Size = new Size(250, 50);
            btn.BackColor = Color.LightBlue;
            btn.ForeColor = Color.DarkBlue;
        }
        
        // Центрування кнопок
        CenterButtons();
    }
    private void CenterButtons()
    {
        int startY = 50;
        int spacing = 20;
        
        button1.Location = new Point(
            (this.ClientSize.Width - button1.Width) / 2,
            startY);
            
        button2.Location = new Point(
            (this.ClientSize.Width - button2.Width) / 2,
            button1.Bottom + spacing);
            
        button3.Location = new Point(
            (this.ClientSize.Width - button3.Width) / 2,
            button2.Bottom + spacing);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // Відкриття форми калькулятора у модальному режимі
        using (Form2 calculatorForm = new Form2())
        {
            calculatorForm.ShowDialog();
        }
    }
    private void button2_Click(object sender, EventArgs e)
    {
        // Відкриття форми результатів
        Form3 resultsForm = new Form3();
        resultsForm.Show();
    }
    private void button3_Click(object sender, EventArgs e)
    {
        // Відкриття форми з інформацією про розробника
        Form4 aboutForm = new Form4();
        aboutForm.Show();
    }
}

У кожному обробнику створюється відповідна форма і вона показується за допомогою методу Show або ShowDialog.

Статичний клас для передачі даних з Form2 до Form3

Створимо статичний клас Class1, який буде містити три поля:

  1. Площа кола s,
  2. Довжина кола l,
  3. Число n, що визначає, яка радіокнопка з кольором вибрана.

А також властивості для доступу до цих полів:

/// 
/// Статичний клас для зберігання результатів обчислень параметрів кола
/// 
public static class Class1
{
    private static double area;          // Площа круга
    private static double circumference; // Довжина кола
    private static int backgroundColor;  // Вибір кольору фону (0 - червоний, 1 - бірюзовий)

    /// 
    /// Властивість для доступу до площі круга
    /// 
    public static double S
    {
        get { return area; }
        set 
        { 
            if (value >= 0)
                area = value; 
            else
                throw new ArgumentOutOfRangeException("Площа не може бути від'ємною");
        }
    }

    /// 
    /// Властивість для доступу до довжини кола
    /// 
    public static double L
    {
        get { return circumference; }
        set 
        { 
            if (value >= 0)
                circumference = value; 
            else
                throw new ArgumentOutOfRangeException("Довжина не може бути від'ємною");
        }
    }

    /// 
    /// Властивість для доступу до вибору кольору фону
    /// 
    public static int N
    {
        get { return backgroundColor; }
        set 
        { 
            if (value == 0 || value == 1)
                backgroundColor = value; 
            else
                throw new ArgumentOutOfRangeException("Допустимі значення: 0 або 1");
        }
    }

    /// 
    /// Скидання всіх значень до початкового стану
    /// 
    public static void Reset()
    {
        area = 0;
        circumference = 0;
        backgroundColor = 0;
    }
}

У класі Form2

Елементи форми:

Оскільки це вікно буде модальним, то встановимо такі властивості форми:

Обробник події Click для кнопки button1 присвоює значення полям s, l, n статичного класу.

Обробник події Click для кнопки button2 очищує поля форми Form2.

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
        
        // Налаштування форми
        this.Text = "Обчислення параметрів кола";
        this.StartPosition = FormStartPosition.CenterScreen;
        this.Size = new Size(350, 250);
        
        // Налаштування елементів керування
        button1.Text = "Обчислити";
        button2.Text = "Очистити";
        label1.Text = "Введіть радіус:";
        checkBox1.Text = "Обчислити площу";
        checkBox2.Text = "Обчислити довжину";
        radioButton1.Text = "Червоний фон";
        radioButton2.Text = "Бірюзовий фон";
    }

    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            // Отримання радіусу з текстового поля
            double radius = Convert.ToDouble(textBox1.Text);
            
            // Перевірка на додатнє значення радіусу
            if (radius <= 0)
            {
                MessageBox.Show("Радіус повинен бути більше нуля!", "Помилка", 
                              MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // Скидання попередніх результатів
            Class1.S = 0; 
            Class1.L = 0; 
            Class1.N = 0;

            // Обчислення площі, якщо обрано
            if (checkBox1.Checked) 
            {
                Class1.S = Math.PI * Math.Pow(radius, 2);
            }

            // Обчислення довжини кола, якщо обрано
            if (checkBox2.Checked) 
            {
                Class1.L = 2 * Math.PI * radius;
            }

            // Вибір кольору фону
            Class1.N = radioButton1.Checked ? 0 : 1;

            MessageBox.Show("Обчислення виконано успішно!", "Результат", 
                          MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        catch (FormatException)
        {
            MessageBox.Show("Будь ласка, введіть коректне числове значення радіусу!", 
                          "Помилка вводу", 
                          MessageBoxButtons.OK, 
                          MessageBoxIcon.Error);
        }
        catch (Exception ex)
        {
            MessageBox.Show($"Сталася помилка: {ex.Message}", 
                          "Помилка", 
                          MessageBoxButtons.OK, 
                          MessageBoxIcon.Error);
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        // Очищення форми
        textBox1.Text = "";
        checkBox1.Checked = false; 
        checkBox2.Checked = false;
        radioButton1.Checked = true; // Встановлення значення за замовчуванням
    }

    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        // Дозволяємо тільки цифри, крапку та керуючі символи
        if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '.')
        {
            e.Handled = true;
        }

        // Перевірка на наявність лише однієї крапки
        if (e.KeyChar == '.' && (sender as TextBox).Text.IndexOf('.') > -1)
        {
            e.Handled = true;
        }
    }
}

У класі Form3

У конструкторі на формі Form3 розмістимо 4 порожні елементи label. В них помістимо результати обчислень.

В обробнику події Load для Form3 зчитуємо значення полів s, l, n статичного класу і виводимо в порожні елементи Label.

public partial class Form3 : Form
{
    public Form3()
    {
        InitializeComponent();
        
        // Налаштування форми
        this.Text = "Результати обчислень";
        this.StartPosition = FormStartPosition.CenterScreen;
        this.Size = new Size(350, 200);
    }

    private void Form3_Load(object sender, EventArgs e)
    {
        // Встановлення кольору фону форми
        this.BackColor = (Class1.N == 0) ? Color.Red : Color.DarkCyan;
        
        // Налаштування шрифту для всіх міток
        Font labelFont = new Font("Arial", 10, FontStyle.Bold);
        
        // Відображення площі круга, якщо вона обчислена
        if (Class1.S != 0)
        {
            label1.Text = "Площа круга:";
            label1.Font = labelFont;
            label1.ForeColor = Color.White;
            
            label2.Text = Class1.S.ToString("F3") + " кв.од.";
            label2.Font = labelFont;
            label2.ForeColor = Color.White;
        }
        
        // Відображення довжини кола, якщо вона обчислена
        if (Class1.L != 0)
        {
            label3.Text = "Довжина кола:";
            label3.Font = labelFont;
            label3.ForeColor = Color.White;
            
            label4.Text = Class1.L.ToString("F3") + " од.";
            label4.Font = labelFont;
            label4.ForeColor = Color.White;
        }
        
        // Центрування міток на формі
        CenterLabels();
    }

    private void CenterLabels()
    {
        // Центрування пар міток (текст + значення)
        int startY = 30;
        int spacing = 30;
        
        if (Class1.S != 0)
        {
            label1.Location = new Point(50, startY);
            label2.Location = new Point(180, startY);
            startY += spacing;
        }
        
        if (Class1.L != 0)
        {
            label3.Location = new Point(50, startY);
            label4.Location = new Point(180, startY);
        }
    }
}

У класі Form4

У класі Form4 в елемент label поміщаємо прізвище та ім'я розробника:

public partial class Form4 : Form
{
    public Form4()
    {
        InitializeComponent();
        
        // Додаткові налаштування форми при ініціалізації
        this.Text = "Інформація про розробника";
        this.StartPosition = FormStartPosition.CenterScreen;
        this.Size = new Size(400, 200);
    }

    private void Form4_Load(object sender, EventArgs e)
    {
        // Налаштування мітки з інформацією про розробника
        label1.Text = "Розробник: Коваленко Петро";
        label1.Font = new Font("Arial", 12, FontStyle.Bold);
        label1.ForeColor = Color.DarkBlue;
        label1.AutoSize = true;
        label1.Location = new Point(
            (this.ClientSize.Width - label1.Width) / 2, 
            (this.ClientSize.Height - label1.Height) / 2
        );
        
        // Додаткові елементи інтерфейсу
        var versionLabel = new Label();
        versionLabel.Text = "Версія: 1.0";
        versionLabel.Font = new Font("Arial", 10);
        versionLabel.AutoSize = true;
        versionLabel.Location = new Point(
            (this.ClientSize.Width - versionLabel.Width) / 2,
            label1.Bottom + 20
        );
        this.Controls.Add(versionLabel);
    }
}

Назад Вперед Зміст