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

Вкладені елементи Controls

Задача

Розробити додаток, який дозволяє здійснити покупку взуття:

Форма в конструкторі форм:

На формі знаходяться:

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

1 спосіб

Обробники подій:

  1. Для кнопок button1 і button2 спільний обробник події Click. Ім'я обробника button1_Click
  2. Для кнопки button3 обробник події Click. Ім'я обробника button3_Click

Опис обробника button1_Click

Обробник підключається до кнопок «Помістити в кошик» і «Очистка форми». В першому випадку він зчитує дані з форми і поміщає результат в кошик, в другому випадку очищає форму.

Було вирішено зробити спільний обробник, щоб було менше коду, що повторюється при перегляді масива Controls цієї форми.

Для того, щоб не допустити поміщення товару в кошик, якщо форма заповнена не повністю, використовуються три прапорці: чи заповнено текстове поле, чи вибрана радіокнопка в groupBox1 і чи вибрана радіокнопка в groupBox2.

Опис змінних:


private void button1_Click(object sender, EventArgs e)
{
    string tx = (sender as Button).Name; //назва кнопки, яка викликала подію
    //Якщо назва button1 - вибираємо значення з форми
    //Якщо назва button2 - очищаємо форму
    TextBox tp = null; //об'єкт класу TextBox
    string tov = ""; //вміст текстового поля
    RadioButton r = null; //об'єкт класу RadioButton
    GroupBox gr = null; //об'єкт класу GroupBox
    bool f1 = false; //чи заповнене текстове поле
    bool f2 = false; //чи вибрана радіокнопка у groupBox1
    bool f3 = false; //чи вибрана радіокнопка у groupBox2
    string ss = ""; //результуючий рядок

Переглядаємо всі елементи форми: Це кнопки, групбокси, текстове поле і написи.


// Перебір всіх елементів управління на формі
for (int i = 0; i < Controls.Count; i++)
{
    // Перевірка, чи елемент є текстовим полем
    if (Controls[i] is TextBox)
    {
        // Отримання посилання на текстове поле
        TextBox textBox = (TextBox)Controls[i];
        
        // Обробка залежно від натиснутої кнопки
        if (tx == "button1")
        {
            // Зчитування вмісту текстового поля
            string товар = textBox.Text;
            
            // Якщо поле не порожнє
            if (!string.IsNullOrEmpty(товар))
            {
                // Додаємо назву товару до результату
                ss += товар + ", ";
                fl = true;  // Позначаємо, що поле заповнене
            }
        }
        else
        {
            // Очищення текстового поля
            textBox.Text = string.Empty;
        }
    }
}

Якщо поточний елемент — це текстове поле, то виконується одна з двох дій:

  1. Якщо подія Click викликала кнопка button1, то зчитується tov назва товару з цього поля, накопичується в кінцевий рядок ss і прапорець f1 встановлюється в true.
  2. Якщо подія Click викликала кнопка button2, то поле очищується.

Але радіокнопки, які знаходяться всередині групбоксів, не потрапляють в перегляд.


// Перевірка, чи елемент є GroupBox (контейнером елементів)
if (Controls[i] is GroupBox groupBox)
{
    // Додаємо заголовок групи до результуючого рядка
    ss += groupBox.Text + " ";  // "Розмір" або "Колір" з заголовка
    
    // Перебір всіх елементів усередині групи
    foreach (Control innerControl in groupBox.Controls)
    {
        // Перевірка, чи елемент є RadioButton
        if (innerControl is RadioButton radioButton)
        {
            // Обробка для кнопки "Зберегти" (button1)
            if (tx == "button1")
            {
                if (radioButton.Checked)
                {
                    // Додаємо вибране значення (розмір/колір) до рядка
                    ss += radioButton.Text + " ";
                    
                    // Встановлюємо прапорці для валідації
                    if (groupBox.Name == "groupBox1") 
                        f2 = true;  // Вибрано елемент у групі "Розмір"
                    else 
                        f3 = true;  // Вибрано елемент у групі "Колір"
                }
            }
            // Обробка для кнопки "Скинути" (button2)
            else
            {
                radioButton.Checked = false;  // Скидаємо вибір радіокнопки
            }
        }
    }
}

Тому, якщо поточний елемент — це групбокс, то виконуються такі дії:

Зчитується заголовок групбокса (слово розмір або колір) і накопичується в кінцевий рядок ss;

Організовується вкладений цикл по елементах всередині цього групбокса. Якщо поточний елемент — радіокнопка, то виконується одна з двох дій:

  1. Якщо подію Click викликала кнопка button1 і радіокнопка вибрана, то зчитується підпис до цієї радіокнопки і накопичується в кінцевий рядок ss. Якщо ця радіокнопка з groupBox1, то в true встановлюється прапорець f2. Якщо ця радіокнопка з groupBox2, то в true встановлюється прапорець f3.
  2. Якщо подію Click викликала кнопка button2, то знімається виділення радіокнопки.

Після перегляду всіх елементів форми і якщо подія викликалася кнопкою button1, перевіряються всі три прапорці, які визначають правильність заповнення форми.


/* Після обробки всіх елементів форми */

// Якщо була натиснута кнопка "Зберегти" (button1)
if (tx == "button1")
{
    // Перевірка, чи всі обов'язкові поля заповнені
    if (f1 && f2 && f3)
    {
        // Додаємо сформований рядок до списку
        listBox1.Items.Add(ss.TrimEnd());  // Видаляємо зайві пробіли в кінці
    }
    else
    {
        // Повідомлення про помилку заповнення форми
        MessageBox.Show("Будь ласка, заповніть всі обов'язкові поля", 
                      "Помилка заповнення", 
                      MessageBoxButtons.OK, 
                      MessageBoxIcon.Warning);
    }
}
} // Кінець методу

Якщо всі три прапорці рівні true, то накопичений кінцевий рядок ss додається в кінець списку listBox1.

Опис обробника button3_Click

Обробник підключається до кнопки «Очистити кошик» і виконує очищення списку listBox1


private void ClearCartButton_Click(object sender, EventArgs e)
{
    // Очищення всього вмісту списку товарів (кошика)
    listBox1.Items.Clear();
}

2 спосіб

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

Обробники подій:

  1. Для кнопки button1 обробник події Click. Ім'я обробника button1_Click
  2. Для кнопки button2 обробник події Click. Ім'я обробника button2_Click
  3. Для кнопки button3 обробник події Click. Ім'я обробника button3_Click.

Опис обробника button1_Click

Обробник підключається до кнопки «Помістити в кошик». Він зчитує дані з форми і поміщає результат в кошик.

Для того, щоб не допустити поміщення товару в кошик, якщо форма заповнена не повністю, використовуються три прапорці: чи заповнено текстове поле, чи вибрана радіокнопка в groupBox1 і чи вибрана радіокнопка в groupBox2.

Опис змінних:


private void button1_Click(object sender, EventArgs e)
{
    // Оголошення змінних для роботи з елементами форми
    TextBox tp = null;     // об'єкт текстового поля
    string tow = "";       // текст з текстового поля
    GroupBox gr = null;    // об'єкт групи елементів
    RadioButton r = null;  // об'єкт радіокнопки
    
    // Прапорці для перевірки заповнення форми
    bool f1 = false;  // чи заповнене текстове поле
    bool f2 = false;  // чи вибрана радіокнопка у групі 1
    bool f3 = false;  // чи вибрана радіокнопка у групі 2
    
    string ss = "";   // результуючий рядок даних

Переглядаємо всі елементи форми: Це кнопки, групбокси, текстове поле і написи.

Якщо поточний елемент — це текстове поле, то зчитується tov назва товару з цього поля, накопичується в кінцевий рядок ss і прапорець f1 встановлюється в true.


// Перебір всіх елементів управління на формі
for (int i = 0; i < Controls.Count; i++)
{
    // Перевірка, чи елемент є текстовим полем (TextBox)
    if (Controls[i] is TextBox)
    {
        // Отримуємо посилання на текстове поле
        tp = Controls[i] as TextBox;
        
        // Зберігаємо вміст текстового поля
        tov = tp.Text; // Назва товару
        
        // Перевірка, чи поле не є порожнім
        if (tov != "")
        {
            // Додаємо назву товару до результуючого рядка
            ss = ss + tov + " ";
            
            // Встановлюємо прапорець, що поле заповнене
            f1 = true;
        }
    }
}

Але радіокнопки, які знаходяться всередині групбоксів, не потрапляють в перегляд.

Тому, якщо поточний елемент — це групбокс, то виконуються такі дії:


// Якщо елемент є GroupBox (групою елементів)
if (Controls[i] is GroupBox)
{
    gr = Controls[i] as GroupBox;
    ss = ss + gr.Text + " "; // Додаємо заголовок групи до результуючого рядка
    
    // Перебір всіх елементів усередині групи
    for (int j = 0; j < gr.Controls.Count; j++)
    {
        // Якщо елемент у групі є RadioButton (радіокнопкою)
        if (gr.Controls[j] is RadioButton)
        {
            r = gr.Controls[j] as RadioButton;
            
            // Якщо радіокнопка вибрана
            if (r.Checked)
            {
                // Додаємо текст вибраної радіокнопки до рядка
                ss = ss + r.Text + " ";
                
                // Встановлюємо прапорець для перевірки заповнення
                if (gr.Name == "groupBox1") 
                    f2 = true; // Позначаємо, що вибрано радіокнопку з groupBox1
                else 
                    f3 = true; // Позначаємо, що вибрано радіокнопку з groupBox2
            }
        }
    } // Кінець перебору елементів групи
} // Кінець умови для GroupBox

Після перегляду всіх елементів форми, перевіряються всі три прапорці, які визначають правильність заповнення форми.


/* Після перегляду всіх елементів форми */

// Якщо всі обов'язкові елементи заповнені - додаємо рядок у список
if (f1 && f2 && f3) 
{
    listBox1.Items.Add(ss);
}
else 
{
    // Якщо форма заповнена неправильно - показуємо повідомлення про помилку
    MessageBox.Show("Помилка при заповненні форми");
} // Кінець методу

Якщо всі три прапорці дорівнюють true, то накопичений кінцевий рядок ss додається в кінець списку listBox1.

Опис обробника button2_Click

Обробник підключається до кнопки "Очистити форму". Він очищає форму, тобто очищає текстове поле і вимикає всі радіокнопки. Для цього він знову повністю переглядає елементи форми, включаючи елементи всередині групбоксів.

Повний код обробника:


private void ClearFormButton_Click(object sender, EventArgs e)
{
    // Оголошення змінних для роботи з елементами форми
    TextBox textBox = null;         // для роботи з текстовим полем
    RadioButton radioBtn = null;    // для роботи з радіокнопкою
    GroupBox groupBox = null;       // для роботи з групою елементів

    // Перебір всіх елементів управління на формі
    foreach (Control control in Controls)
    {
        // Якщо елемент є текстовим полем
        if (control is TextBox)
        {
            textBox = (TextBox)control;
            textBox.Text = string.Empty;  // Очищення текстового поля
        }
        
        // Якщо елемент є групою (GroupBox)
        if (control is GroupBox)
        {
            groupBox = (GroupBox)control;
            
            // Перебір всіх елементів усередині групи
            foreach (Control groupControl in groupBox.Controls)
            {
                // Якщо елемент є радіокнопкою
                if (groupControl is RadioButton)
                {
                    radioBtn = (RadioButton)groupControl;
                    radioBtn.Checked = false;  // Вимкнення радіокнопки
                }
            }
        }
    }
}

Опис обробника button3_Click

Обробник підключається до кнопки "Очистити кошик" і виконує очищення списку listBox1. Код такий самий, як у першому способі.

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