C windows form практические работы

Калькулятор
Windows Forms на

языке

C#

Оригинал: http://vscode.ru/proglessons/kalkulyatorwindowsformscshapr.html

Мы создадим более усовершенствованный калькулятор Windows Forms.Итак, выглядеть у нас
он будет вот так:

 

Здесь у нас 19 кнопок Button, 1 Textbox и ещё 1
пустой Label (на рисунке он выделен). Применение его будет описано ниже. Итак, создаём
такую или похожую форму. Мы увеличили ширину TextBox’a, используяMultiLine:

 

 Также в Свойствах мы увеличили размер шрифта в
TextBox’e и Label’e до 12 пт.

 

Теперь делаем так, чтобы при нажатии на цифровые
кнопки, в TextBox’e появлялась соответствующая цифра.

Для этого дважды кликаем на кнопке “0” и в
открывшемся коде пишем:

private void button17_Click(object
sender, EventArgs e)

        {

            textBox1.Text =
textBox1.Text + 0;         }

Проверяем, несколько раз нажав на кнопку “0” у нас в
форме.

 

Работает. Делаем то же самое с остальными цифровыми
кнопками:

private void button13_Click(object
sender, EventArgs e)

        {

            textBox1.Text =
textBox1.Text + 1;

        }

private void button14_Click(object
sender, EventArgs e)

        {

            textBox1.Text =
textBox1.Text + 2;

        }

private void button15_Click(object
sender, EventArgs e)

        {

            textBox1.Text =
textBox1.Text + 3;

        }

private void button9_Click(object
sender, EventArgs e)

        {

            textBox1.Text =
textBox1.Text + 4;

        }

private void button10_Click(object
sender, EventArgs e)

        {

            textBox1.Text =
textBox1.Text + 5;

        }

private void button11_Click(object
sender, EventArgs e)

        {

            textBox1.Text =
textBox1.Text + 6;

        }

private void button5_Click(object
sender, EventArgs e)

        {

            textBox1.Text =
textBox1.Text + 7;

        }

private void button6_Click(object
sender, EventArgs e)

        {

            textBox1.Text =
textBox1.Text + 8;

        }

private void button7_Click(object
sender, EventArgs e)

        {

            textBox1.Text =
textBox1.Text + 9;         }

Таким же образом кликаем дважды на кнопку “.” в
форме. Она будет использоваться для создания десятичной дроби. Пишем следующий
код:

private void button18_Click(object
sender, EventArgs e)

        {

            textBox1.Text =
textBox1.Text + «,»;

        }

Кнопки нажимаются, в TextBox’e
отображаются нажатые цифры. Теперь надо научить программу производить с ними
какие-либо операции. Как видно из формы, наш калькулятор сможет производить
стандартные математические операции: сложение, вычитание, умножение и деление.
Для начала мы создадим  в самом начале программы несколько переменных, которые
нам для этого понадобятся:

float a, b; int count; bool znak =
true;

Первым двум переменным будут
присваиваться значения, набранные пользователем в калькуляторе. В последствии с ними будут
производиться нужные математические операции. Тип floatэто тип с плавающей точкой,
позволяющий работать с десятичными дробями, что нам, безусловно, нужно
при наличии кнопки “.” . Благодаря второй переменной мы будем давать программе
указания, какую именно операцию производить с переменными, описанными выше.
Здесь нам не нужна дробь, поэтому обойдёмся целочисленным типом int.

Последняя переменная znak нам понадобится для того,
чтобы менять знаки у введённых чисел. Тип bool может иметь два значения – ture
и false. Мы представим, что если znakимеет значение true в программе, то это
означает, что у числа знак +, если false – число отрицательное и перед собой
имеет знак -. Изначально в калькуляторе вбиваются положительные числа, поэтому
мы сразу присвоили переменной значение true. Далее мы дважды нажимаем на кнопку
“+”, обозначающую сложение, на форме и пишем следующий код:

private void button4_Click(object
sender, EventArgs e)

        {

            a = float.Parse(textBox1.Text);

           
textBox1.Clear();             count = 1;

            label1.Text =
a.ToString() + «+»;             znak = true;         }

В строке 3 мы присваиваем первой переменной a то, что
будет написано в TextBox’e (а именно число, которое введёт пользователь перед
тем, как нажать кнопку “+”).

Затем TextBox очищается, число, введённое
пользователем, в нём пропадает (но остаётся в переменной a) Переменной count
присваивается число 1, которая потом укажет программе, что именно операцию
сложения надо будет произвести с числами. Затем в Label записывается число из
переменной a (то самое, которое изначально ввёл пользователь) и знак плюса.
Выглядеть в форме это будет так, как описано ниже. Пользователь вводит
какое-либо число:

 

Затем нажимает на кнопку “+” и после этого видит:

 

Кроме того, как бы не было странным с первого
взгляда, мы присваиваем переменнойznak значение true, хотя выше, в начале кода,
мы и так присваивали это же значение. Подробнее данную переменную мы опишем
ниже, но смысл в том, что мы присваиваем значение true, когда хотим сделать
введённое число отрицательным, если оно положительно, а значение false, когда
хотим сделать число положительным, если оно отрицательное. Изначально у нас
вводятся положительные числа, сначала первое, потом второе. И если первое число
мы сделаем отрицательным, то значение у znakперейдёт в false и тогда получится,
что второе слагаемое как бы отрицательное (на практике, просто чтобы поставить
перед ним минус, придётся нажать дважды на соответствующую кнопку, чтобы с
false значение перешло в true, а затем обратно с trueв false, и появился знак
минуса).

Подобным образом заполняем код для кнопок “-“, “*” и
“/”:

private void button8_Click(object
sender, EventArgs e)

        {

            a =
float.Parse(textBox1.Text);             textBox1.Clear();             count =
2;

            label1.Text =
a.ToString() + «-«;

            znak = true;

        }

private void button12_Click(object
sender, EventArgs e)

        {

            a =
float.Parse(textBox1.Text);

           
textBox1.Clear();             count = 3;

            label1.Text =
a.ToString() + «*»;

            znak = true;

        }

private void button16_Click(object
sender, EventArgs e)

        {

            a =
float.Parse(textBox1.Text);             textBox1.Clear();             count =
4;

            label1.Text =
a.ToString() + «/»;             znak = true;

        }

Разница лишь в значении переменной count и в том,
какой знак добавляется в Label’e.

Далее нам понадобится создать функцию, которая будет
применять нужные нам математические операции к числам. Назовём её calculate. Но
перед этим мы кликнем дважды на кнопку “=” на форме и в коде к ней мы запишем:

private void button19_Click(object
sender, EventArgs e)

        {

           
calculate();             label1.Text = «»;         }

То есть, при нажатии пользователем на кнопку “=”, как
раз выполнится наша функция подсчёта calculate, и, заодно, очистится Label, так
как результат мы в будущем коде выведем в TextBox. Теперь-таки создаём нашу
функцию calculate и пишем следующий код:

private void calculate()

        {

           
switch(count)             {                 case 1:

                    b = a +
float.Parse(textBox1.Text);                     textBox1.Text = b.ToString();

                   
break;                 case 2:                     b = a —
float.Parse(textBox1.Text);                     textBox1.Text =
b.ToString();                     break;                 case
3:                     b = a * float.Parse(textBox1.Text);                    
textBox1.Text = b.ToString();                     break;                 case
4:

                    b = a /
float.Parse(textBox1.Text);                     textBox1.Text = b.ToString();

                   
break;                   default:                     break;

            }

        }

Здесь мы используем конструкцию switch-case.

Switch –
это оператор управления. Он может включать в себя несколько case’ов. Case – метки,
      от значения         которых          зависит,          какие   операции        будут
происходить. Строка switch(count) означает, что именно от значения count будет
зависеть, какое действие будет происходить в коде switch’a. Итак, если count=1
(в коде case 1:), то произойдёт следующее:

После того, как пользователь нажал “+”, он,
естественно, должен ввести второе слагаемое, что он и делает по стандартному
сценарию, а затем нажать кнопку “=” (и в ней, как мы помним, как раз выполнится
наша функция).

Как
только кнопка “=” будет нажата, программа сложит число из переменной a с тем
вторым слагаемым, которое записал пользователь в TextBox, и запишет результат в
переменную b (строка 6          кода    функции).       В         строке             7
         программа      выведет в TextBoxрезультат сложения – переменную b.

Оператор break (строка 8) завершает исполнение кода
switch при выполнении кода метки case 1, так как больше нам в нём делать
нечего.

Точно так же строится алгоритм при case 2, case 3 и
case 4 с той разницей, что в них происходит не сложение, а вычитание, умножение
и деление соответственно.

Оператор default срабатывает, если вдруг что-то
пойдёт не по плану и count  примет какое-либо иное значение, не описанное в
switch. Тогда срабатывает лишь операторbreak. Львиная доля программы готова.
Нам надо лишь написать код для трёх оставшихся нетронутыми до этого время
кнопок. Дважды жмём в форме на кнопку “С”. Она будет очищать все записи из
TextBox’a иLabel’a. Код у неё элементарный:

private void button3_Click(object
sender, EventArgs e)

        {

            textBox1.Text =
«»;             label1.Text = «»;         }

На очереди у нас кнопка “<–“. Она будет удалять
последнюю цифру записанного вTextBox’e числа. Код:

private void button2_Click(object
sender, EventArgs e)

        {

            int lenght =
textBox1.Text.Length — 1;             string text = textBox1.Text;

            textBox1.Clear();

            for (int i = 0; i <
lenght; i++)

            {

                textBox1.Text =
textBox1.Text + text[i];

            }

        }

Мы вводим новую переменную lenght целочисленного типа
и записываем в неё количество символов в TextBox’e минус один символ. Также мы
вводим новую переменную text, в которую полностью заносим текст из TextBox’а.
Затем мы очищаем TextBox и вводим цикл for, через который записываем в TextBox
строку text, но уже на символ короче. Например, в TextBox’e записано число
504523 При нажатии на кнопку “<–“ в переменную lenght записывается число 5
(6 цифр – 1), в переменную text записывается строка “504523”, TextBox
очищается, а затем в него по одному записываются символы из text, но в этот раз
их будет не 6, а 5, то есть вTextBox’e появится число 50452. У нас остаётся
последняя кнопка, которая отвечает за знак первого слагаемого. Переходим к её
коду. Тут мы будет работать с переменной znak, которую описывали выше. Код
выглядит вот так:

private void button1_Click(object
sender, EventArgs e)

        {

            if(znak==true)

            {

                textBox1.Text =
«-» + textBox1.Text;

                znak = false;

            }

            else if
(znak==false)

            {

                textBox1.Text=textBox1.Text.Replace(«-«,
«»);                 zna
k = true;

            }

Изначально, как мы помним, у переменной znak стоит значение true. Если
мы нажмём на кнопку первый раз, то в TextBox’e перед числом появится знак
“-“, а переменной znakбудет присвоено  значение false.

Если второй раз нажать на данную кнопку, то, так как znak у нас false,
произойдёт второе условие. Здесь используется метод Replace, который заменяет
какой-либо кусок строки на другой. В скобках после метода вначале пишется, что
будет заменено в строке, а после запятой, то, на что заменять. В данном случае мы заменяем
в TextBox’e минус на пустое значение.

Вот и всё, наш калькулятор Windows Forms готов! Можно его
тестировать!

 

Для создания приложения Windows Forms в Visual Studio 2019:

Лабораторная работа 1.
Элемент управления TextBox (текстовое поле)

Выполнить: Разработайте приложение, которое вычисляет сумму трех любых чисел при нажатии на кнопку.

Целью работы является знакомство с элементами управления visual c# textbox и button — текстовое поле и кнопка.

Пример выполнения:

[Название проекта: Lab1, название файла формы frmSumma.cs]

✍ Алгоритм:

    Инструментарий:

    объект свойство name свойство text
    форма Вычисление суммы
    кнопка (button) btnExit Выход
    текстовое поле (textbox) txtA 0
    текстовое поле (textbox) txtB 0
    текстовое поле (textbox) txtC 0
    текстовое поле (textbox) txtSumma 0
    кнопка (button) btnCount Вычислить
  1. Внимание! Называйте все объекты согласно правилам именования объектов, принятых в C#. В скобках будет указан возможный вариант для имени создаваемого объекта.
  2. Создайте новый проект (C# → Windows → Все типы проектов → Приложение Windows Forms (.Net Framework)), назовите проект Урок 4 Лаб 4, а его форму — frmSumma (окно Свойства → свойство (Name)).
  3. Создайте и запрограммируйте на форме кнопку Выход (btnExit). Для этого в окне Toolbox разверните свиток All Windows Forms и дважды щелкните по элементу button. На форме появилась кнопка. Для того, чтобы запрограммировать кнопку, дважды щелкните по ней на форме — открылась новая вкладка с кодом для кнопки. Введите код:
  4.  private void btnExit_Click(object sender, EventArgs e)
            {
                this.Close(); // эта строка - ваш введенный код
            }
  5. Запустите приложение и убедитесь, что кнопка работает.
  6. Верните во вкладку с дизайном формы. Создайте три элемента управления Textbox (txtA, txtB, txtC) для слагаемых. Задайте свойство Text для этих элементов управления, равное 0 (в окне PropertiesText).
  7. Создайте еще один элемент управления TextBox (txtSumma) (размеры и расположение кнопок см. выше рис «форма Вычисление_суммы»).
  8. Создайте кнопку Вычислить (btnCount).
  9. Запрограммируйте событие Click для кнопки Вычислить следующим образом (дважды щелкните по кнопке на форме, чтобы запрограммировать событие):
  10. private void btnCount_Click(object sender, EventArgs e)
            {
           // здесь начинается ваш код
                int summa = Int32.Parse(txtA.Text) + 
                   Int32.Parse(txtB.Text) + Int32.Parse(txtC.Text);
                txtSumma.Text = summa.ToString();
           // здесь ваш код закончился
            }

    где Parse – функция преобразования строкового значение в целое число;

  11. Задайте надписи для кнопок («Вычислить» и «Выход»), изменив их свойство Text.
  12. Запустите приложение, введите значения для слагаемых и посмотрите, что произойдет, если Вы нажмете на кнопку Вычислить.
  13. Сохраните проект. Найдите на компьютере папку с проектом. Загрузите в moodle два файла: 1) файл frmSumma.cs 2) В папке bin → Debug файл с расширением .exe. Либо загрузите архив всей папки с проектом.

Контрольное задание. Разработайте приложение, которое вычисляет:

  • площадь треугольника по трем сторонам;
  • площадь прямоугольника по двум сторонам;
  • площадь треугольника по двум сторонам и углу между ними;
  • процент от числа.

[Название проекта: Lesson_4ExTask0, название формы L4ExTask0.cs]

Лабораторная работа 2.
Элемент управления ListBox (список), свойства и методы списка, программирование с ветвлением

Измените свойство Backcolor (Задний фон) текстового поля при помощи элемента управления ListBox – список

Целью работы является ознакомление с элементом управления в visual c# Listbox. Изучаются свойства добавления и удаления пунктов списка listbox. Вводится понятие программирования с ветвлением.

Пример выполнения:

[Название проекта: Lab2, название файла формы Lab2.cs]

✍ Алгоритм:

Инструментарий:

объект свойство name свойство text
форма
кнопка (button) btnExit Выход
текстовое поле (textbox) txt
список (ListBox) lst
  1. Поместите на новую форму текстовое поле TextBox c именем txt и элемент управления Список ListBox . Назовите его lst (свойство Name).
  2. На панели свойств элемента управления ListBox выберите свойство (атрибут) Items и задайте для него четыре пункта списка (нажимая на Enter после каждого пункта): черный, красный, синий, зеленый.
  3. Теперь запрограммируйте событие SelectedIndexChanged (изменение пункта списка) для списка, таким образом, чтобы при нажатии на определенный пункт c цветом, цвет текстового поля менялся бы на соответствующий. Используйте при этом оператор Visual c# If:
  4. private void lst_SelectedIndexChanged(object sender, EventArgs e)
            {
               // ваш код:
                if (lst.SelectedItem == "black")
                {
                    txt.BackColor = System.Drawing.Color.Black;
                }
                else if (lst.SelectedItem == "red")
                {
                    txt.BackColor = System.Drawing.Color.Red;
                }
                else if (lst.SelectedItem == "blue")
                {
                    txt.BackColor = System.Drawing.Color.Blue;
                }
                else if (lst.SelectedItem == "green")
                {
                    txt.BackColor = System.Drawing.Color.Green;
                }
            // здесь ваш код закончился
            }
      

    System – пространство имен;
    Drawing — пространство имен, обеспечивающее доступ к функциональным возможностям графического интерфейса
    Событие SelectedIndexChanged происходит при выделении различных пунктов в элементе управления списка данных между отправками к серверу.

  5. Все работает, но теперь мы рассмотрим второй способ задания пунктов списка: с помощью программного кода.
  6. Удалите все цвета из атрибута Items элемента управления lst. Теперь необходимо добавить в обработку события Load формы (загрузка формы) следующий код (дважды щелкните на пустом месте дизайна формы, чтобы открыть код):
  7. private void Form1_Load(object sender, EventArgs e)
            {
                // ваш код:
                lst.Items.Add("black");
                // ... добавьте другие цвета
            }
  8. Запустите и отладьте программу.

Контрольное задание.
Добавьте ListBox для изменения ширины (атрибут Width) текстового поля: минимальная — 20, средняя – 50, максимальная — 100.

Примечание: использовать свойство текстового поля Size, и System.Drawing.Size(значение ширины, значение высоты)

[Название проекта: ExTaskLab2, название формы ExTaskLab2.cs]

Лабораторная работа 3.
Разработайте приложение, которое изменяет задний фон текстового поля из предыдущего занятия, реализовав эту функцию с помощью меню формы
Целью данного урока является ознакомление с элементом управления MenuStrip при работе в visual c++ с формами.

Пример выполнения:

c++ меню menuStrip

[Название проекта: Lab3, название файла формы Lab3.cs]

✍ Алгоритм:

Инструментарий:

объект свойство name
форма
меню формы (MenuStrip) MenuStrip1
  1. Для создания меню на панели инструментов выберите MenuStrip . Дважды кликните на появившемся в нижней области окна объекте, а затем перейдите на форму и в области (Вводить здесь) введите меню верхнего уровня с текстом Цвет.
  2. Переместитесь на нижнюю область и введите текст Черный. Заполните элемент MenuStrip следующим образом:
  1. Запустите программу и поэкспериментируйте: выбирайте разные элементы созданного объекта.
  2. Запрограммируйте событие Click для каждого пункта; например, для элемента Черный необходимо написать следующий код (дважды щелкнув на пункте, чтобы открыть код):
private void ЧерныйToolStripMenuItem_Click(object sender, EventArgs e)
{
  this.txt.BackColor=System.Drawing.Color.Black;
}
  1. Запрограммируйте аналогично остальные пункты Цвет.
  2. Запустите и отладьте приложение. Сохраните проект.

Дополнительное задание:

  1. При выборе какого-либо пункта сделайте его недоступным для повторного выбора (свойство Enabled=false).
  2. Выполните дополнительное задание из занятия № 1, реализовав функцию с помощью MenuStrip.

Вопросы для самоконтроля:

  1. Каково основное назначение объекта MenuStrip?
  2. Как запрограммировать необходимый пункт меню формы в Visual c++?
  3. Какое свойство служит для изменения фона объекта?
  4. С помощью какого свойства menu можно сделать недоступным какой-либо пункт?

Provide feedback

Saved searches

Use saved searches to filter your results more quickly

Sign up

Решаем типовые задачи на C# с помощью Windows Forms

В последнее время здесь был ряд заметок по работе с приложениями Windows Forms на C#, все вместе их можно рассматривать как набросок небольшого курса вроде «Технологии программирования, часть 1», изучаемого, когда «Языки программирования» в лице основ C++ и C# уже «пройдены»:

1. Введение и основы Windows Forms

2. Взаимодействие форм. MDI-приложения

3. Работа со строками и списочными компонентами

4. Табличные компоненты и работа с ними

5. Графика (отрисовка, работа с изображениями)

6. Графика (работа с Chart-компонентами и анимация в .NET)

7. Интеграция с офисными приложениями

В этой заметке мы обобщаем, «чему должны были научиться» и приводим ряд типовых задач, которые имеет смысл ставить перед неофитами при контроле знаний.

В настоящее время нами освоены следующие возможности библиотеки .NET:

  • управление приложением и компонентами с помощью событий и свойств;
  • создание прикладных приложений и вычислительная обработка данных на основе базовых компонент (Panel, Button, Label, TextBox);
  • списочные и табличные компоненты, обработка информации с их помощью (ListView, ListBox, ComboBox, DataGridView, DataGrid);
  • работа с графической канвой и таймером, управление отображением и перемещением графических объектов (PictureBox, Graphics, Timer);
  • работа с текстовыми и структурированными файлами средствами .NET;
  • динамическое создание/удаление компонентов, управление дочерними объектами.

Как правило, в зачётной или экзаменационной работе по подобному курсу задач на «конкретные компоненты» нет (если тип компоненты отдельно не оговорен в условии), а задача состоит в том, чтобы написать работающее приложение согласно поставленному условию и с применением компонент, которые кажутся вам наиболее подходящими для этой цели.

Проект Ex8_1. Реализовать отсортированный по алфавиту список имён с поддержкой операций добавления и удаления элементов, сохранением списка строк в файл и загрузкой его из файла. Допустимые символы в именах – буквы и цифры.

Задачу можно решать как на основе списочных, так и табличных компонент. Поскольку требуется сортировка данных, удобнее решать на основе какого-либо списка, имеющего встроенное свойство Sorted. Форма будет иметь следующий вид:


Повторите, какие свойства формы вы поменяли, чтобы получить такой вид окна?

Справа расположена panel1 со свойством Dock = Right, на ней 4 кнопки button1, …, button4 для выполнения предусмотренных задачей действий. Слева – список comboBox1 со свойством Dock = Fill.

По загрузке формы настроим список для нашей задачи:

  private void Form1_Load (object sender, EventArgs e) {
   comboBox1.Sorted = true; //список будет сортироваться
   comboBox1.DropDownStyle = ComboBoxStyle.Simple; //развёрнутый вид списка
  }

Кнопка 1 будет добавлять запись, если такой же записи ещё нет в списке:

  private void button1_Click (object sender, EventArgs e) {
   String r = comboBox1.Text;
   if (comboBox1.FindString (r) == -1) comboBox1.Items.Add (r);
  }

Кнопка 2 будет удалять выбранный в списке элемент, если таковой есть:

  private void button2_Click (object sender, EventArgs e) {
   if (comboBox1.SelectedIndex != -1) 
    comboBox1.Items.Remove (comboBox1.SelectedItem);
  }

Кнопка 3 выполнит работу по сохранению файла с использованием поточного класса StreamWriter. Для простоты используем файл с фиксированным именем data.txt, располагающийся в текущей папке.

  private void button3_Click (object sender, EventArgs e) {
   try {
    System.IO.StreamWriter file = new System.IO.StreamWriter ("data.txt");
    for (int i = 0; i < comboBox1.Items.Count; i++)
     file.WriteLine (comboBox1.Items [i].ToString ());
    file.Close ();
   }
   catch (Exception) {
    MessageBox.Show ("Не могу записать data.txt");
   }
  }

Кнопка 4 отвечает за загрузку элементов списка из файла data.txt. Чтобы можно было закрыть дескриптор файла после чтения данных, применим поточный класс StreamReader:

  private void button4_Click (object sender, EventArgs e) {
   try {
    System.IO.StreamReader file = new System.IO.StreamReader ("data.txt");
    String line;
    comboBox1.Items.Clear ();
    while (( line = file.ReadLine () ) != null) 
     comboBox1.Items.Add (line);
    file.Close ();
   }
   catch (Exception) {
    MessageBox.Show ("Не могу открыть data.txt");
   }
  }

Осталось обеспечить ввод только разрешённых символов, для этого достаточно добавить обработчик события KeyPress (там доступно свойство KeyChar, в отличие от KeyCode в обработчике события KeyDown) для списка comboBox1:

  private void comboBox1_KeyPress (object sender, KeyPressEventArgs e) {
   char c = e.KeyChar;
   if (Char.IsLetterOrDigit (c) || c == (char) Keys.Back || c == (char) Keys.Enter)
    return;
   else e.Handled = true;
  }

Задача решена полностью.

 Скачать пример Ex8_1 в архиве .zip с проектом C# Visual Studio 2019 (11 Кб)

Проект Ex8_2. На графической канве отобразить работу светофора с задержкой между состояниями «красный-жёлтый-зелёный» 1 сек.

Форма – пустое окно Windows Forms.

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

Опишем таймер, счётчик состояний и размер элемента светофора в классе формы:

private Timer timer1;
private int cnt;
private const int size = 120; //ширина и высота окружностей

По событию загрузки формы (Load) настроим размеры окна и инициализируем таймер:

  private void Form1_Load (object sender, EventArgs e) {
   this.ClientSize = new System.Drawing.Size (size, size*3);
   this.DoubleBuffered = true;
   timer1 = new Timer ();
   timer1.Interval = 1000;
   timer1.Tick += (sendr, args) => {
    Invalidate ();
    cnt = ( cnt + 1 ) % 3;
   };
   timer1.Enabled = true;
   cnt = 0;
  }

Обработчик события Tick таймера мы встроили в оператор назначения как стрелочную функцию. Обратите внимание, что этот обработчик таймера только вызывает перерисовку формы (вызов Invalidate(), отправляющий сообщение стандартному методу пререрисовки Paint()) и меняет счётчик состояний cnt, а саму отрисовку будет делать метод Paint:

  private void Form1_Paint (object sender, PaintEventArgs e) {
   Pen [] pens = new Pen [] { Pens.Red, Pens.Yellow, Pens.Green };
   for (int i = 0; i < 3; i++)
    e.Graphics.DrawEllipse (pens [i], 0, i * size, size, size); //контуры 3 кружков
   Brush [] brushes = new Brush [] { Brushes.Red, Brushes.Yellow, Brushes.Green };
   e.Graphics.FillEllipse (brushes [cnt], 0, cnt * size, size, size); //текущий закрасить
  }

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

Альтернативный подход (без привязки к методу Paint) – в обработчике события таймера программно создавать Bitmap нужной размерности, выполнять отрисовку на нём, а затем назначать его компоненте PictureBox.

Задача решена полностью.

 Скачать пример Ex8_2 в архиве .zip с проектом C# Visual Studio 2019 (11 Кб)

Проект Ex8_3. Поддержка динамического списка компонент TextBox произвольной размерности. Реализовать добавление и удаление компонент.

Форма – пустая Windows Forms. В качестве примера будем создавать поля ввода TextBox в месте щелчка мышью по форме и удалять их при щелчке мышью на самих полях.

Нам не понадобится отдельно сохранять поля ввода в каком-либо списке, хотя мы могли бы сделать это, например, так:

using System.Collections.Generic;
//...
List <TextBox> F; 
 //динамический список System.Collections.Generic.List объектов типа TextBox
//...
F = new List <TextBox>(); //конструктор списка
//...
F.Add (T); //где T - созданный TextBox

Дело в том, что у формы уже есть контейнер Controls с методами Add и Remove.

В классе формы дополнительно опишем только счётчик контролов:

  int cnt; //счётчик объектов

Инициализируем счётчик в конструкторе формы:

  public Form1 () {
   InitializeComponent ();
   cnt = 0;
  }

Щелчку по форме мышью соответствует событие MouseClick. Достаточно в обработчике этого события формы создать программно новый TextBox и добавить его в список компонент формы:

  private void Form1_MouseClick (object sender, MouseEventArgs e) {
   TextBox T = new TextBox ();
   T.Text = "Text" + ( cnt++ );
   T.Location = new Point (e.X, e.Y);
   T.Parent = this;
   this.Controls.Add (T);
  }

Длина списка не ограничена. Однако если мы хотим удалять компоненты TextBox по какому-то событию, например, по щелчку на них, придётся всем создаваемым TextBox программно назначать обработчик этого события, так что вставим соответствующий код в метод Form1_MouseClick (перед добавлением поля ввода в список контролов):

   T.Click += (sendr, args) => {
    this.Controls.Remove ((TextBox)sendr);
   };

Задача решена полностью.

Альтернативным, но избыточным решением, как сказано выше, были бы статические или динамические массивы компонент.

 Скачать пример Ex8_3 в архиве .zip с проектом C# Visual Studio 2019 (10 Кб)

Проект Ex8_4. Реализовать простейшее движение объекта («героя») по форме (двумерному «лабиринту»). Лабиринт состоит из отдельных полей, среди которых есть проходимые и не проходимые.

Сделаем всё максимально просто согласно условию задачи.

Нам понадобится растянутый на всю клиентскую часть формы PictureBox (свойство Dock = Fill) и таймер, у которого установлены свойства Enabled = true и Interval = 200.

В классе формы опишем нужные данные:

  public const int width = 10, height = 10, k = 16;
   //размеры игровой доски и одного поля
  public int [,] field = new int [width, height];
   //сама игровая доска
  public int [] hero = new int [] { 1, 1};
   //координаты героя
  public Bitmap bitfield = new Bitmap (k * width, k * height );
   //битмап для отрисовки
  public Graphics gr;
   //графический контекст

Массив в C# автоматически инициализируется нулями, поэтому достаточно выставить в значение «1» те элементы массива поля, которые соответствуют «стенам». Сделаем это в конструкторе формы, там же установим размер окна и получим графический контекст:

  public Form1 () {
   InitializeComponent ();
   //установим размер окна и получим графический контекст:
   this.ClientSize = new Size (k * width, k * height);
   gr = Graphics.FromImage (bitfield);
   //выставим все крайние поля в единицы:
   for (int i = 0; i < width; i++) {
    field [i, 0] = 1;
    field [i, height - 1] = 1;
   }
   for (int i = 0; i < height; i++) {
    field [0, i] = 1;
    field [width - 1, i] = 1;
   }
   //выставьте и некоторые другие поля в единицы...
  }

Обработчик нажатия клавиши формы будет получать текущее положение героя и менять его, если этому не мешают препятствия (в нашем случае — «стены»):

  private void Form1_KeyDown (object sender, KeyEventArgs e) {
   //обрабатываем нажатия клавиш со стрелками
   int x = hero [0], y = hero [1];
   switch (e.KeyCode) {
    case Keys.Left:
     if (x > 0 && field [x - 1, y] == 0) x--;
    break;
    case Keys.Right:
     if (x < width - 1 && field [x + 1, y] == 0) x++;
    break;
    case Keys.Up:
     if (y > 0 && field [x, y-1] == 0) y--;
    break;
    case Keys.Down:
     if (x < height - 1 && field [x , y+1] == 0) y++;
    break;
   }
   hero[0] = x; hero [1] = y;
  }

Обработчик события таймера будет просто запрашивать отрисовку, которую мы, на случай развития приложения, вынесем в отдельный метод DrawMe:

  private void TickTimer_Tick (object sender, EventArgs e) {
   //по таймеру просто запрашиваем отрисовку
   DrawMe ();
  }

  public void DrawMe () {
   //метод для отрисовки поля и героя
   gr.Clear (Color.Black);
   for (int i = 0; i < width; i++)
    for (int j = 0; j < height; j++)
     if (field [i, j] == 1) {
      gr.FillRectangle (Brushes.Green, i * k, j * k, k, k);
      gr.DrawRectangle (Pens.Black, i * k, j * k, k, k);
     }
   gr.FillEllipse (Brushes.Red, hero[0] * k, hero [1] * k, k, k);
   pictureBox1.Image = bitfield;
  }

Задача решена полностью, вот что вышло:


вид приложения, стены — только по краям поля

 Скачать пример Ex8_4 в архиве .zip с проектом C# Visual Studio 2019 (11 Кб)

13.05.2023, 10:04 [2936 просмотров]


К этой статье пока нет комментариев, Ваш будет первым

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Windows 7 установщик обнаружил ошибку 0xc8000222
  • Мониторинг windows server 2012 средства мониторинга
  • Ошибка 0xc000014c при загрузке windows 10
  • Nextcloud windows server 2008
  • Windows api function openscmanager error code 5