Пример программы с winforms

Содержание

В статье описаны общие принципы построения приложений, с использованием подхода MVC, на примере внедрения в приложение, использующее много лет Code Behind подход.

Не будет:
• Классического Unit Test;
• Принижения влияния Code Behind;
• Неожиданных открытий в MVC.

Будет:
• Unit Test и Stub;
• MVC;
• Внедрение подхода на базе существующего продукта.

Введение

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

Более сложный случай: функциональность принята, пользователи активно участвуют в обратной связи и приводят к необходимости менять функционал. Функционал поменяли, пошли по тому же пути и перестал работать старый функционал, да и новый оставляет желать лучшего. Кое как прищёлкивая быстрорастущую функциональность начинается постоянная правка багов.

Уроки C# .NET Windows Forms / #1 — Создание приложения на C# с SQL (базами данных)

Сначала это были часы, потом недели, сейчас я знаю, что и месяцы не предел. Когда это занимало часы или дни, ошибки закрывались, все более – менее текло. Но стоило начать переоткрывать ошибки – начинался ад. Отдел тестирования постоянно ругается, разработчики постоянно правят ошибки и делают новые в разрабатываемом функционале.

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

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

Формализация

Начались поиски инструментов, для формализации правил. Весь код логики взаимодействия с пользователем и данными находился в формах. Конечно же, были отделены слои работы с базой данных, сервисы, ремоутинги и многое, многое другое. Но пользовательский интерфейс оставался перенасыщен логикой. Логикой, никак не связанной с отображением.

Первым, и вполне логичным шагом, мне показалось использовать средства для визуального тестирования форм. Набираем правило их кликов – вводов и преобразуем это в тест. Для примера это прекрасно умеет делать Visual Studio 2013 Ultimate, вернее один из её шаблонов. Я бодро создал несколько тестов и понял, что создавать таким образом тесты, а потом запускать, огромная беда.

C++ перенос программы с консольного приложения на WinForms. (2. Создание проекта под Windows Forms)

Требовалось кучу времени чтобы полностью загрузить всю систему, дойти до нужных диалогов и вызвать соответствующие события. Это требовало работу всех звеньев цепи, что местами было невозможно.

Все действия я предпринимал абсолютно отделив для себя Unit Testing, при этом его постоянно использовал для сервисов и логики, которая вращалась на сервере, ведь у неё не было форм, соответственно Code Behind. Параллельно работая с ASP.NET MVC мне все больше нравился подход с отделением логики от представлений.

Упрощенно, вызывая контроллер ASP.NET MVC мы просто дергаем его публичный метод, который возвращает представление с некоторыми изменениями. Я начал думать, как эту модель переложить на WinForms и пришел к выводу, что используя события на представлениях я буду вызывать методы контроллеров.

Я принял правило, что у меня всегда есть класс-контроллер, который привязывается к событиям класса, реализующего интерфейс представления. Тем самым я убрал весь код логики из Code Behind в код контроллера, а контроллер подлежал тестированию с помощью обычных Unit Tests, реализуя Stubs для классов менеджеров данных и самих представлений. Позже я научился тестировать и сами представления, исключительно с помощью Unit Tests. Далее я хочу показать пример того, как я пришел к этому.

Читайте также:
Как переключать программы быстро

Пример

Описание задачи

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

При удалении исключения фокус должен переходить на первый элемент списка. При этом форма вызывается из контекста никак не реализующего MVC.

Формализация представления

Воспитанный на огромном количестве форм, в корпоративных приложениях, я пришел к выводу, что тоже буду использовать стандартный подход к интерфейсу: панель управления с кнопками — действиями над исключениями, список исключений, в виде таблицы, и базовой кнопкой закрыть. Соответственно для отображения в интерфейсе мне понадобится:
• Весь список исключений, для построения таблицы;
• Исключение в фокусе;
• Событие смены исключения в фокусе;
• Событие добавления;
• Событие удаления;
• Событие нажатия кнопки закрыть;
• Метод открытия;
• Метод закрытия;
• Метод обновления представления.
В дальнейшем я понял, что для реализации более дружественного интерфейса мне понадобится еще несколько вещей:
• Доступность создания;
• Доступность удаления;
• Список всех выделенных исключений, для массового удаления.

Преобразовав все это в код, я получил интерфейс представления:

public interface IReplaceView < bool EnableCreate < get; set; >bool EnableDelete < get; set; >List Replaces < set; >ReplaceSymbol FocusedReplace < get; set; >List SelectedReplaces < get; set; >event EventHandler Closing; event EventHandler Creating; event EventHandler Deleting; event EventHandler FocusedChanged; void Open(); void Close(); void RefreshView(); >

Формализация контроллера

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

public class ReplaceController : IReplaceController < private IReplaceView _view = null; private IReplaceStorage _replaceStorage = null; public ReplaceController(IReplaceView view, IReplaceStorage replaceStorage) < Contract.Requires(view != null, «View can’t be null»); Contract.Requires(replaceStorage != null, «ReplaceStorage can’t be null”); _view = view; _replaceStorage = replaceStorage; >>

В данном контроллере для проверки параметров я использую контракты, но для статьи это не имеет никакого значения.

Тестирование

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

Загрузить пустой список исключений

При этом должна быть доступна кнопка создания исключений, недоступна кнопка удаления исключений, элемент в фокусе должен быть null, а список выбранных элементов пустой, но не null. Преобразовав в код получил:

[TestMethod] public void LoadEmptyReplaces() < var emptyReplaces = new List(); var storage = new StubIReplaceStorage() < ReplaceSymbolsGet = () =>< return emptyReplaces; >, >; ReplaceSymbol focusedReplace = null; var loadedReplaces = new List(); var selectedReplaces = new List(); var enableCreate = false; var enableDelete = false; var view = new StubIReplaceView() < FocusedReplaceGet = () =>< return focusedReplace; >, FocusedReplaceSetReplaceSymbol = x => < focusedReplace = x; if (x != null) < selectedReplaces.Add(x); >>, ReplacesSetListOfReplaceSymbol = x => < loadedReplaces = x; >, EnableCreateSetBoolean = x => < enableCreate = x; >, EnableDeleteSetBoolean = x => < enableDelete = x; >, SelectedReplacesGet = () => < return selectedReplaces; >, >; var controller = new ReplaceController(view, storage); controller.Open(); view.FocusedChangedEvent(null, null); Assert.IsNotNull(loadedReplaces, «После создания контроллераи и его открытия список замен не должен быть null»); Assert.IsTrue(loadedReplaces.Count == 0, «После создания контроллера и его открытия список замен не должен быть пустым, так как в него загружен пустой список»); Assert.IsNull(focusedReplace, «После создания контроллера и его открытия активной замены быть не должно»); Assert.IsNotNull(selectedReplaces, «После создания контроллера список замен не может быть null»); Assert.IsTrue(selectedReplaces.Count == 0, «После создания контроллера и его открытия в список выбраных замен должен быть пустой»); Assert.IsTrue(enableCreate, «После создания контроллера должна быть доступна возможность создавать замены»); Assert.IsFalse(enableDelete, «После создания контроллера не должно быть доступно удаление, так как список замен пустой»); >

Другие правила

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

Реализация представления

После этого я создал само представление, реализующее вышеуказанный интерфейс. Для него я так же создал небольшие тесты, используя забавный класс PrivateObject, который позволяет вызывать приватные методы, реализованные в объекте. Например, тест на удаление я получил такой:

Читайте также:
Программы похожие на reaper

[TestMethod] public void DeleteOneReplaceView() < var replaces = GetTestReplaces(); var storage = new StubIReplaceStorage() < ReplaceSymbolsGet = () =>< return replaces; >, >; var controller = new ReplaceController(_view, storage); Task.Run(() => < controller.Open(); >).Wait(WaitTaskComplited); var privateObject = new PrivateObject(_view); privateObject.Invoke(«RiseDeleting»); Assert.IsTrue(replaces.Count == 2, «После удаления одной замены должны остаться еще две»); Assert.IsNotNull(_view.FocusedReplace, «После удаления замены фокус должен перейти на первую замену»); Assert.AreEqual(replaces.First().Source, _view.FocusedReplace.Source, «После удаления замены фокус должен перейти на первую замену из оставшегося списка»); Assert.IsTrue(_view.SelectedReplaces.Count == 1, «После удаления замены должна быть выбрана первая из оставшегося списка»); Assert.AreEqual(_view.FocusedReplace.Source, _view.SelectedReplaces.First().Source, «После удаления замены фокус должен перейти на первую замену из оставшегося списка»); Assert.IsTrue(_view.EnableCreate, «После удаления замены должна быть доступна возможность добавлять замены»); Assert.IsTrue(_view.EnableDelete, «После удаления замены должна быть возможность удалить первую из оставшегося списка»); >

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

После, сделал вызов в коде контроллера с уже реальным менеджером и представлением.

_replaceView = new ReplaceView(); _replaceController = new ReplaceController(_replaceView, _importer);

Запустил все приложение и увидел конечный результат работы. Все работало точно так, как я закладывал. Отдел тестирования доволен, клиенты довольны, положительная обратная связь получена. Что еще необходимо?

Очень буду рад любым замечаниям или своим рассказам о том, как вы справляетесь с Windows Forms. Первые отзывы правильно замечают, что своим пыхтением я пришел к MVP, это абсолютно верно.
Спасибо за внимание! Надеюсь, вы не зря потратили время на меня.

  • оценка точки завершения работ
  • unit testing
  • code behind

Источник: habr.com

Программирование в .NET Framework

Если вы захотите писать программы, похожие на привычные приложения Windows, то наверняка воспользуетесь классами из пространства имен System.Windows.Forms . Они позволяют задействовать кнопки, списки, текстовые поля, меню, окна сообщений и множество других «элементов управления». Элементы управления — это то, что вы помещаете в форму. Они нужны для вывода информации, например, текстовой (элемент управления Label ) или графической (элемент управления PictureBox ), либо для выполнения определенных действий, например, выбора значения или перехода к другой форме после нажатия кнопки. Все элементы управления помещаются на форму.

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

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

Компания Майкрософт предоставила в составе библиотеки классов .NET Framework огромное количество «элементов управления», которые можно помещать на формы. Освоив этот инструмент, вы сможете быстро создавать эффектные приложения.

Некоторые полезные классы из пространства имен System.Windows.Forms

Вот некоторые элементы управления, которые можно размещать на формах:

  • Label (Надпись).
  • Button (Кнопка).
  • ListBox (Список).
  • CheckBox (Флажок).
  • RadioButton (Переключатель).
  • MessageBox (Окно сообщений).
  • Menu (Меню).
  • TabControl (Управление вкладками).
  • Toolbar (Панель инструментов).
  • TreeView (Дерево).
  • DataGrid (Сетка данных).
  • PictureBox (Изображение).
  • RichTextBox (Текстовое поле с поддержкой формата RTF ).

Работа с примерами программ Windows Forms в Visual C# Express

Возможно, вы предпочтете не использовать уже заготовленные примеры проектов, а разрабатывать их «с нуля». В таком случае нужно учесть, что для каждого проекта C# Express сразу же создает два файла (с именами Form1.cs и Program.cs ) и наполняет их исходным кодом на языке C#, то есть вы изначально получаете простейшую, но полноценную программу. Предлагаемый нами способ работы с уже полученным проектом состоит в выполнении следующих действий:

  • Удалите файл Form1.cs.
  • Замените код в файле Program.cs на код примера, с которым вы работаете.

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

Пример программы 3.3

Рассмотрим пример простейшего приложения Windows Forms. Оно всего лишь создает новую форму и выводит определенный текст в заголовок окна формы.

using System.Windows.Forms; class SimpleWindowsForm : Form < // Метод-конструктор нашего класса public SimpleWindowsForm() < // Указываем заголовок окна this.Text = «Это простая форма с заголовком»; >static void Main() < // Создаем новый экземпляр класса //и запускаем его на выполнение // В результате на экране дисплея откроется форма Application.Run(new SimpleWindowsForm()); >>
Листинг 3.3.

Читайте также:
Как написать простую программу на Андроид

Пример программы 3.4

Следующий пример тоже достаточно прост, но мы делаем шаг вперед — размещаем на форме кнопку.

using System.Windows.Forms; class SimpleWindowsFormWithButton : Form < Button button1; // Метод-конструктор нашего класса public SimpleWindowsFormWithButton() < // Указываем заголовок окна this.Text = «Форма с командной кнопкой»; // Добавляем кнопку в коллекцию элементов управления формы // Хотя на кнопке написано: «Нажми меня!», // пока при нажатии ничего не происходит! button1 = new Button(); button1.Text = «Нажми меня!»; button1.Top = 100; button1.Left = 100; button1.Height = 50; button1.Width = 70; this.Controls.Add(button1); >static void Main() < // Создаем и запускаем форму Application.Run(new SimpleWindowsFormWithButton()); >>
Листинг 3.4.

Пример программы 3.5

Кнопку на форму мы поместили, но при нажатии на нее ничего не происходит. Это скучно.

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

using System; using System.Windows.Forms; using System.Drawing; class FormWithWorkingButton : Form < Button mrButton; // Метод-конструктор нашего класса public FormWithWorkingButton() < // Указываем заголовок окна this.Text = «Форма с работающей кнопкой!»; // Добавляем кнопку и привязываем ее к обработчику события mrButton = new Button(); mrButton.Text = «Нажми меня»; mrButton.Top = 100; mrButton.Left = 100; mrButton.Height = 50; mrButton.Width = 70; mrButton.Click += new System.EventHandler(mrButton_Click); this.Controls.Add(mrButton); >static void Main() < // Создаем и запускаем форму Application.Run(new FormWithWorkingButton()); >// Обработчик события, срабатывающий при нажатии кнопки void mrButton_Click(object sender, EventArgs e) < // Изменяем текст mrButton.Text = «Кнопка была нажата!»; >>
Листинг 3.5.

Пример программы 3.6

Программирование на C, C# и Java

Уроки программирования, алгоритмы, статьи, исходники, примеры программ и полезные советы

Windows Forms

Потоки в Visual C++ — Пример реализации и использования

Потоки в Visual C++ — Пример реализации и использования

Рассмотрим создание потоков на языке Visual C++. На примере программы в Visual Studio разберем основы и применение необходимых классов. В конце урока вы найдете видео, в котором тема раскрывается более подробно.

Стиль Material Design в Windows Forms

Стиль Material Design в Windows Forms

В видеоуроке рассказывается, как заменить стандартную тему оформления Windows Forms на стиль Material Design от Google. Проект создается на языке программирования C#.

Печать документов на C# — Программный вывод текста на принтер

Печать документов на C# — Программный вывод текста на принтер

Несомненно в языке C# и фреймворке .NET есть средства для печати документов и текста с помощью принтера. В данной статье описано, как вывести на печать текст программно. А для тех, кто больше любит смотреть, чем читать — в конце материла находится видеоурок…

Вывод изображений в ListView

Вывод изображений в ListView

Компонент ListView (из Windows Forms) предназначен для вывода текстовых данных. Создавая столбцы в нем, нельзя выбирать тип данных (например, изображения). Тем не менее способ вывода изображений в элемент управления ListView существует. Рассмотрим его на примере.

MS Access и C# — работаем с базой данных из программы Windows Forms

MS Access и C# — работаем с базой данных из программы Windows Forms

Рассмотрим выполнение запросов SELECT, INSERT, UPDATE и DELETE к базе данных Microsoft Access из программы на языке C#, на примере проекта Windows Forms в Visual Studio. В конце статьи вы найдете исходники, а также видеоурок по данной теме.

Вывод данных в DataGridView из БД на C#

Вывод данных в DataGridView из БД на C#

В Windows Forms табличные данные удобно выводить с помощью элемента управления DataGridView. В статье покажем, как это сделать на примере таблицы из базы данных и языка программирования C#.

Преобразование цветного изображения в черно-белое C#

Преобразование цветного изображения в черно-белое C#

В статье рассмотрим алгоритм перевода цветного изображения в черно-белое и напишем его реализацию на языке C#. Приводится исходный код программы, написанной в Visual Studio — приложение Windows Forms.

Растянуть элементы на форме Windows Forms

Растянуть элементы на форме Windows Forms

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

Перенос строки в TextBox с Multiline

Перенос строки в TextBox с Multiline

Покажем, как выполнить перенос строки в TextBox с атрибутом Multiline (когда текстовое поле занимает несколько строк). Сделаем это на примере программы в Windows Forms и языка C#.

Работа с API Яндекс Переводчика

Работа с API Яндекс Переводчика

Научимся работе с API на языке программирования C#. В этом уроке мы напишем программу в Visual Studio на Windows Forms, которая будет переводить текст с русского языка на английский и обратно при помощи веб-запросов к API Яндекс Переводчика. Также можно…

Видеоуроки по программированию на YouTube

Контакты

Электронная почта
Группа ВКонтакте
Twitter
RSS лента
RSS подписка
Помочь проекту

Источник: vscode.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru