Provide feedback
Saved searches
Use saved searches to filter your results more quickly
Sign up
Appearance settings
Приложения Windows Forms
Если вы захотите писать программы, похожие на привычные приложения 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
Мы добились успеха: наша программа умеет выполнять основные действия. Теперь добавим на форму несколько новых элементов управления, аккуратно разместим их и немного поработаем с ними. Возьмем элементы управления 4-х типов: Button, ListBox, MessageBox и PictureBox.
Обратите внимание: кроме System.Windows.Forms в этом примере упоминается пространство имен System.Drawing. Дело в том, что мы используем элемент управления PictureBox, а для работы с изображениями требуются классы Drawing.
using System.Windows.Forms; using System.Drawing; class MyForm : Form { // Объявим элемент ListBox как поле класса: // нам придется обращаться к нему из разных методов ListBox listBox1; // Метод-конструктор нашего класса public MyForm() { //Размеры формы this.Size = new Size(400, 400); // Создадим элемент PictureBox, поместим в него изображение, // добавим его на форму PictureBox pictureBox1 = new PictureBox(); pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; Bitmap image1 = new Bitmap ("..//..//images//Zakat.jpg"); pictureBox1.ClientSize = new Size(this.Width, 150); pictureBox1.Image = (Image)image1; this.Controls.Add(pictureBox1); // Создаем объект Button, определяем некоторые из его свойств Button button1 = new System.Windows.Forms.Button(); button1.Location = new Point(150, 160); button1.Size = new Size(100, 30); button1.Text = "Нажми меня"; button1.Click += new System.EventHandler(button1_Click); this.Controls.Add(button1); // Создаем ListBox, определяем свойства и добавляем на форму listBox1 = new System.Windows.Forms.ListBox(); listBox1.Location = new System.Drawing.Point(20, 200); listBox1.Size = new Size(100, 100); listBox1.Items.Add("Лес"); listBox1.Items.Add("Степь "); listBox1.Items.Add("Озеро"); listBox1.Items.Add("Море"); listBox1.Items.Add("Океан"); listBox1.SelectedIndex = 2; this.Controls.Add(listBox1); } // Обработчик события, срабатывающий при нажатии кнопки void button1_Click(object sender, System.EventArgs e) { // Выводим сообщение с указанием выбранного в списке пункта MessageBox.Show(this, "Вы выбрали " + listBox1.SelectedItem, "Уведомление", MessageBoxButtons.OK); } static void Main() { // Создаем и запускаем форму Application.Run(new MyForm()); } private void InitializeComponent() { this.SuspendLayout(); // // MyForm // this.BackColor = System.Drawing.SystemColors.Control; this.ClientSize = new System.Drawing.Size(292, 273); this.Name = "MyForm"; this.ResumeLayout(false); } }
Листинг
3.6.
Рассмотрим создание потоков на языке Visual C++. На примере программы в Visual Studio разберем основы и применение необходимых классов. В конце урока вы найдете видео, в котором тема раскрывается более подробно.
В видеоуроке рассказывается, как заменить стандартную тему оформления Windows Forms на стиль Material Design от Google. Проект создается на языке программирования C#.
Несомненно в языке C# и фреймворке .NET есть средства для печати документов и текста с помощью принтера. В данной статье описано, как вывести на печать текст программно. А для тех, кто больше любит смотреть, чем читать — в конце материла находится видеоурок…
Компонент ListView (из Windows Forms) предназначен для вывода текстовых данных. Создавая столбцы в нем, нельзя выбирать тип данных (например, изображения). Тем не менее способ вывода изображений в элемент управления ListView существует. Рассмотрим его на примере.
Рассмотрим выполнение запросов SELECT, INSERT, UPDATE и DELETE к базе данных Microsoft Access из программы на языке C#, на примере проекта Windows Forms в Visual Studio. В конце статьи вы найдете исходники, а также видеоурок по данной теме.
В Windows Forms табличные данные удобно выводить с помощью элемента управления DataGridView. В статье покажем, как это сделать на примере таблицы из базы данных и языка программирования C#.
В статье рассмотрим алгоритм перевода цветного изображения в черно-белое и напишем его реализацию на языке C#. Приводится исходный код программы, написанной в Visual Studio — приложение Windows Forms.
В статье рассмотрим способ создания «резинового» интерфейса в формах Windows Forms и разберёмся, как растянуть элементы на форме при изменении размера окна программы.
Покажем, как выполнить перенос строки в TextBox с атрибутом Multiline (когда текстовое поле занимает несколько строк). Сделаем это на примере программы в Windows Forms и языка C#.
Научимся работе с API на языке программирования C#. В этом уроке мы напишем программу в Visual Studio на Windows Forms, которая будет переводить текст с русского языка на английский и обратно при помощи веб-запросов к API Яндекс Переводчика. Также можно…
Время на прочтение8 мин
Количество просмотров37K
В статье описаны общие принципы построения приложений, с использованием подхода MVC, на примере внедрения в приложение, использующее много лет Code Behind подход.
Не будет:
• Классического Unit Test;
• Принижения влияния Code Behind;
• Неожиданных открытий в MVC.
Будет:
• Unit Test и Stub;
• MVC;
• Внедрение подхода на базе существующего продукта.
Введение
Перед тем, как начать использовать данных подход, я прошел большой путь обычного разработчика корпоративных систем. По пути мне встречались абсолютно шаблонные события и вещи, как простые, так и более сложные. Например, разработка закончена, функциональность отправлена на тестирование, кликается, далее валится масса ошибок, от простых недочетов, до грубых нарушений. Более сложный случай: функциональность принята, пользователи активно участвуют в обратной связи и приводят к необходимости менять функционал. Функционал поменяли, пошли по тому же пути и перестал работать старый функционал, да и новый оставляет желать лучшего. Кое как прищёлкивая быстрорастущую функциональность начинается постоянная правка багов. Сначала это были часы, потом недели, сейчас я знаю, что и месяцы не предел. Когда это занимало часы или дни, ошибки закрывались, все более – менее текло. Но стоило начать переоткрывать ошибки – начинался ад. Отдел тестирования постоянно ругается, разработчики постоянно правят ошибки и делают новые в разрабатываемом функционале. Все чаще приходит обратная связь, от реальных пользователей, полная негатива. А функционал рос и рос, я искал методы и подходы, как можно себе упростить жизнь. При этом меня давно посещала идея, задействовать при разработке пользовательского интерфейса тестирование на уровне разработчика. Желание заложить пользовательские сценарии привело меня к осознанию факта наличия проблемы: отсутствия хоть сколько-то объективных критериев готовности продукта от разработчика. И я начал мыслить несколько шире, а что, если постараться заложить все положительные сценарии использования в некоторые правила, постоянно проверять наборы правил, ведь это хоть какая-то гарантия того, что пользователь на следующем выпуске не будет ошарашен отвалившимся функционалом, а тестировщики будут задействованы по назначению. Именно этим правилам и предрекалось стать критерием окончания работы над функционалом для себя, для разработчика.
Формализация
Начались поиски инструментов, для формализации правил. Весь код логики взаимодействия с пользователем и данными находился в формах. Конечно же, были отделены слои работы с базой данных, сервисы, ремоутинги и многое, многое другое. Но пользовательский интерфейс оставался перенасыщен логикой. Логикой, никак не связанной с отображением. Первым, и вполне логичным шагом, мне показалось использовать средства для визуального тестирования форм. Набираем правило их кликов – вводов и преобразуем это в тест. Для примера это прекрасно умеет делать Visual Studio 2013 Ultimate, вернее один из её шаблонов. Я бодро создал несколько тестов и понял, что создавать таким образом тесты, а потом запускать, огромная беда. Требовалось кучу времени чтобы полностью загрузить всю систему, дойти до нужных диалогов и вызвать соответствующие события. Это требовало работу всех звеньев цепи, что местами было невозможно. Все действия я предпринимал абсолютно отделив для себя 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<ReplaceSymbol> Replaces
{
set;
}
ReplaceSymbol FocusedReplace
{
get;
set;
}
List<ReplaceSymbol> 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<ReplaceSymbol>();
var storage = new StubIReplaceStorage()
{
ReplaceSymbolsGet =
() =>
{
return emptyReplaces;
},
};
ReplaceSymbol focusedReplace = null;
var loadedReplaces = new List<ReplaceSymbol>();
var selectedReplaces = new List<ReplaceSymbol>();
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, который позволяет вызывать приватные методы, реализованные в объекте. Например, тест на удаление я получил такой:
[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, это абсолютно верно.
Спасибо за внимание! Надеюсь, вы не зря потратили время на меня.
Windows Forms is a framework available in Visual Studio that allows you to build desktop applications with the assistance of a graphical user interface. This allows you to click and drag widgets such as buttons or labels directly onto a canvas, and manipulate the properties of each widget such as its font-size, color or border.
In this article, a simple Celsius to Fahrenheit Converter will be used as an example to go through the basics of how to set up a Windows Form Application. Visual Studio 2019 Community Edition is the edition used for this tutorial.
How to Create the Windows Forms Project in Visual Studio
First, create the project in Visual Studio.
- Open Visual Studio and select Create a New Project.
- Visual Studio will provide you with a list of project templates you can choose from.
-
To create a Windows Forms Application, search for Windows Form App and select it from the list of templates. Once this is selected, click on Next.
If the Windows Form App option is not available on the list, modify your installed version of Visual Studio. In Visual Studio Installer, add the .NET desktop development workload for Desktop and Mobile, and re-launch Visual Studio.
-
Add a name and location for the project, and click on Next. The location is the directory where the code files will be stored.
- On the next screen, keep the default selection of .NET Core 3.1.
-
Click Create.
-
Once Visual Studio has finished creating the project, the project will open.
How to Add Elements to the Project Canvas
The canvas is the white area located at the top-left of the screen. Click and drag the points on the bottom, right, or bottom-right of the canvas to resize it if needed.
To create the UI of the application, add widgets such as buttons or text boxes onto the canvas.
-
Open the View Tab at the top of the window, and select Toolbox.
- This will add a toolbox to the left side of the application. Select the pin icon in the top-right of the toolbox to pin it there permanently.
-
This is where you can drag any widget from the toolbox onto the canvas. Highlight a button from the toolbox, and drag it onto the canvas.
-
Drag two more text boxes onto the canvas, along with three labels (two labels for each text box, and one label for the title at the top of the application).
- Every widget on the canvas has properties associated with them. Highlight a widget to display the Properties window in the bottom-right of Visual Studio, which lists all the properties that widget has. These properties can include the text, name, font size, border, or alignment of the highlighted widget.
-
At the moment, the text on these widgets still say label1, label2, or button1. Select the label1 widget and edit the Text property in the properties window to say «Celsius to Fahrenheit». Change the font size to be 22pt.
-
Similarly, edit the properties of the other widgets on the canvas to be the following:
Widget
Property
New Value
label2
Text
Celsius
label3
Text
Fahrenheit
button
Text
Calculate
Fahrenheit text box
ReadOnly
True
How to Handle Events and Write Code in the Code-Behind
Widgets on the canvas can be tied to events. Events can include things like clicking on a button, changing the text inside a text box, or selecting a particular radio button. When these events happen, it can cause a section of code in the Code-Behind to trigger.
C# is the language used when creating Windows Forms. If you haven’t already used C#, there are many practical reasons to learn C# programming.
For this particular application, add an event to the Calculate button, to trigger a section of code to run when this button is pressed.
-
Double-click the Calculate button to automatically open Form1.cs with a new Event method:
private void calculateButton_Click(object sender, EventArgs e)
- This is where you will add the code that will perform the Celsius to Fahrenheit calculation, and display the result in the Fahrenheit text box. To do this, you need to be able to read the value from the Celsius text box, and modify the Fahrenheit text box to display the result.
-
Go back to the canvas, and re-edit the properties as shown before. This time, edit the Name property for both the Celsius and Fahrenheit text boxes. These names can be used to reference the text boxes in the code.
Widget
Property
New Value
Celsius Text Box
Name
celsiusTextBox
Fahrenheit Text Box
Name
fahrenheitTextBox
- Go back to the calculateButton_Click function in Form1.cs.
-
Now, the Celsius text box can be referred to in the code using the name «celsiusTextBox». The Celsius value the user entered is stored in its Text property. However, since it’s a string, parse this into a double in order to include it in the future Fahrenheit calculations.
private void calculateButton_Click(object sender, EventArgs e)
{
// Get the value that the user entered in the Celsius Text Box
double celsiusValue = Double.Parse(celsiusTextBox.Text);
} -
The celsiusValue variable now stores the value that the user entered in the Celsius Text Box. The formula for converting Celsius to Fahrenheit is (celsiusValue * 9 / 5) + 32. Therefore, the result can now be calculated and stored in the Fahrenheit Text Box.
private void calculateButton_Click(object sender, EventArgs e)
{
// Get the value that the user entered in the Celsius Text Box
double celsiusValue = Double.Parse(celsiusTextBox.Text);// Apply the calculation
double result = (celsiusValue * 9 / 5) + 32;// Store the result in the Fahrenheit Textbox
fahrenheitTextBox.Text = result.ToString();
}
How to Run and Debug the Windows Forms Program
Running the Windows Forms Program in Visual Studio
Now that the UI and code logic is set up, run the program to see it working.
-
To run the program, select the green arrow at the top of the toolbar in Visual Studio.
-
Once the project has loaded, add a value into the Celsius text box and press the Calculate button. This will add the result into the Fahrenheit text box.
- If the program is blurry at runtime, it is likely your application is not DPI aware. This can cause scaling and resolution issues, so this will need to be enabled. You can also read more about configuring display scaling on Windows 10 for High-DPI monitors.
- Right-click on the TemperatureConverter Project in the Solutions Explorer. Select Add, then select New Item.
-
Search for the Application Manifest File, and click Add.
-
Copy the following code into the new app.manifest file, as a child of the assembly tag (if the code is already generated, just un-comment it).
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application> - For this change to take effect, re-run the program. Select the red stop button at the top of the toolbar, then select the green play button again.
Debugging the Windows Forms Program
You may want to debug the program if the logic of your Windows Forms application is not working as expected.
- Navigate back to the calculateButton_Click function in Form1.cs and click anywhere on the gray bar in the far-left of the screen. This will add a breakpoint, which is indicated by a red circle.
- Press the «Calculate» button again to trigger this method to execute. The program will pause when it hits the breakpoint to show all the values stored in the variables at that point.
-
To continue the program, click the green Continue arrow at the top of the toolbar.
Running the Program Using an Executable File
If you don’t want to run your program through Visual Studio, use the standalone executable file for the program. This is automatically generated.
-
Navigate to the executable file, which can be found here:
<your-project-folder>/bin/Debug/netcoreapp3.1/TemperatureConverter.exe
- Click on the executable file to directly run the program.
Adding More to Your Windows Form
Hopefully you now have a basic understanding of the basic structure of a Windows Form Application. You can continue exploring additional Windows Forms features by experimenting with new widgets, and taking a deeper dive into the other various events that can be handled.
Once you are more familiar with Windows Forms, you can start creating more complex applications. You can also explore many of the other ways you can create applications on Windows desktop.