Введение в Windows Forms — пишем первую программу
В данной статье будет рассказано о том как написать простой обработчик событий на C++ для приложения Windows Forms, работающего под управления .NET Framework. Мы создадим простейшую Windows программу, которая вычисляет факториал целого числа. Для написания данной программы Вам понадобится Visual Studio 2008 Express Edition или Professional.
Для начала создадим проект.
Откроем Visual Studio, далее жмем Файл→Создать→Проект, далее выбираем пункт CLR и отмечаем Приложение Windows Forms, даем имя проекта, к примеру factr и жмем Ok.
После того как мы создали проект, должна появиться пустая форма, которая должна выглядеть примерно так:
Справа должна появиться панель элементов, если ее нет, то можно включить ее в меню Вид→Панель Элементов или нажатием горячих клавиш — Ctrl + Alt + X.
На ней расположены различные элементы для вставки в форму, нам понадобятся только элементы Button (Кнопка), Label (Надпись) и TextBox (Текстовое поле). Перетащите на форму три элемента Label, Два элемента TextBox, и одну кнопку (Button), расставьте элементы примерно так:
Теперь нам нужно будет изменить текст надписей для элементов Label и Button и Задать подходящие имена классов для элементов TextBox. Для этого Выделите элемент label1, перейдите в Панель свойств, (обычно она находится под Панелью элементов, если панель выключена, включите ее в меню Вид -> Диспетчер свойств.) и задайте для данного элемента значение атрибута Text как показано на рисунке.
Задайте атрибут Text для всех элементов Label и Кнопки Button аналогичным образом. Наша форма должна принять примерно следующий вид:
Я сделал кнопку развернуть неактивной, так как изменение размеров данной формы испортит ее внешний вид, Вы также можете это сделать, щелкнув левой кнопкой мыши на пустом месте формы и в Панели свойств задать для атрибута MaximizeBox параметр False.
Теперь задайте для текстовых полей (TextBox) Атрибуты Name в Панели Свойств – для первого поля это будет num1, а для второго, соответственно num2. Тем самым мы изменили имена классов для полей TextBox, чуть позднее Вы поймете зачем.
Итак, каркас формы готов, если откомпилировать и запустить программу, то мы увидим, какой будет наша форма на финише, правда сейчас она совершенно бесполезна. Перейдем к написанию обработчика событий для кнопки Button, т.е. что будет происходить при нажатии на эту кнопку, также мы напишем саму функцию вычисления факториала, которую мы будем использовать в обработчике.
Первым делом нужно добавить заголовочный файл fact.h в проект, для этого щелкаем правой кнопкой мыши в Обозревателе решений на папке Заголовочные файлы, далее меню Добавить -> Создать Элемент, вписываем название файла – fact.h и нажимаем Добавить. В данном файле будет содержаться прототип функции для вычисления факториала. Добавляем туда следующий исходный код.
Далее подключаем этот файл к проекту с помощью директивы #include – Открываем файл factr.cpp и добавляем после строчки #include «stdafx.h» следующий код.
Теперь наш заголовочный файл подключен к проекту, далее аналогичным образом создаем файл исходного кода fact.cpp в проект.
В него добавляем саму функцию вычисления факториала целого числа.
Теперь наш проект содержит функцию вычисления факториала, откомпилируйте его, если ошибок нет, то можно приступить к написанию обработчика событий для кнопки Button.
Открываем файл Form.h, в нем мы видим визуальное представление нашей формы. Щелкаем двойным щелчком на кнопке Button и переходим к исходному коду.
После фигурной скобки ставим абзац и приступаем к кодированию. Любой набор символов, которые мы вводим с клавиатуры в текстовое поле программы является строкой, поэтому нам нужно вытащить значение из текстового поля и привести его к целочисленному типу. Это довольно сложная процедура, но, к счастью в языке C++ уже есть множество функций, выполняющих конвертирование типов данных. Сначала нам необходимо описать и инициализировать переменную, в которой будет храниться значение числа, для которого должен быть вычислен факториал. Добавим в том место, где Вы поставили абзац следующий код:
Эта строка инициализирует переменную, которая хранит в себе число для вычисления его факториала. Далее нам нужно будет произвести вызов нашей функции fact с переменной number в качестве единственного аргумента и занести результат работы функции в новую переменную factor.
И затем преобразовать полученное значение обратно в строку и присвоить его второму текстовому полю.
Таким образом, наш простой обработчик событий будет выглядеть вот так:
Теперь можно скомпилировать и запустить готовую программу и проверить ее. Помните, что тип double в С++ может хранить число не превышающее !170.
Результат работы программы можно проверить в инженерном калькуляторе Windows.
Ответы на 7 самых частых вопросов по WinForms
Ответы на 7 самых частых вопроса по WinForms
1. Как создать вторую форму
Любая форма представляет из себя класс, унаследованный от Form.
Экземпляр главной формы создается в файле Program.cs по умолчанию.
При этом ShowDialog() блокирует главную форму, т.е. управление вернется в нее, только по закрытию второй формы, а Show() просто отображает вторую форму, т.е. будут доступны обе формы.
2. Как передать данные из одной формы в другую
Часто возникает необходимость передать данные из одной формы в другую, я придумал 7 способов, у каждого свои недостатки и достоинства.
2.1 Изменение модификатора доступа (добавлено 24 июля 2017: лучше воздержаться от применения данного способа)
В Form2 Установить модификатор доступа для контрола/поля public
В любом месте Form1
+ Самый быстрый в реализации и удобный способ
— Противоречит всем основам ООП
— Возможна передача только из более поздней формы в более раннюю
— Форма f показывается только с использованием ShowDialog(), т.е. в первую форму управление вернется только по закрытию второй. Избежать этого можно, сохранив ссылку на вторую форму в поле первой формы
2.2 Использование открытого свойства/метода. Способ очень похож на первый
В классе Form2 определяем свойство (или метод)
+ Противоречит не всем основам ООП
— Минусы те же
2.3 Передача данных в конструктор Form2
Изменяем конструктор Form2
+ Простой в реализации способ
+ Не нарушает ООП
— Возможна передача только из более ранней формы в более позднюю
2.4 Передача ссылки в конструктор
Изменяем конструктор Form2
+ Доступ ко всем открытым полям/функциям первой формы
+ Передача данных возможна в обе стороны
— Нарушает ООП
2.5 Используем свойство ‘родитель’
При создании второй формы устанавливаем владельца
+ Доступ ко всем открытым полям/функциям первой формы
+ Передача данных возможна в обе стороны
+ Не нарушает ООП
2.6 Используем отдельный класс
Создаем отдельный класс, лучше статический, в основном namespace, т.е. например в файле Program.cs
+ Самый удобный способ, когда данные активно используются несколькими формами.
2.7 Использование функций обратного вызова
2.7.1 Передача метода в конструктор
Создаем в основном namespace делегат
Непонятен пункт 2.5 из «Ответы на 7 самых частых вопросов по WinForms»
Вопрос по пункту 2.5 из «Ответы на 7 самых частых вопроса по WinForms». Вот код: // в форме 1.
Ответы на 7 самых частых вопросов по Windows Forms, C++/CLI Edition
Ответы на 7 самых частых вопросов по Windows Forms C++/CLI Edition Эта статья является.
Ответы на 7 самых частых вопросов по Windows Forms, C++/CLI Edition — свой способ передачи данных между формами
Способ с использованием макросов. Средней сложности в реализации и понимании, не знаю, нарушает ли.
Список Ваших вопросов Платону Щукину и его ответы
Данная тема будет предназначана для публикования Ваших вопросов и ответов с службой поддержки.
+ Наиболее гибкий способ передачи данных
— Сложен в реализации и понимании
3. Как получить доступ к контролу из другого потока
С элементами управления можно работать только из того потока в котором они были созданы. При обращении из другого потока будет сгенерировано исключение InvalidOperationException с текстом «Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on.» (Недопустимая операция в нескольких потоках: попытка доступа к элементу управления не из того потока, в котором он был создан.). Возможные решения:
3.1 Простой и неправильный способ
Отменяем проверку, из какого потока используется контрол
Для одного раза может и сработать, но делать так крайне не рекомендуется.
3.2 Использование методов Invoke/BeginInvoke
Эти методы выполняют указанные делегаты в том потоке, в котором контрол был создан.
Invoke вызывает делегат синхронно, BeginInvoke — асинхронно.
Чтобы определить, требуется ли Invoke используйте свойство InvokeRequired.
Например, объявляем делегат
Позволю себе дополнить вопрос по связи и передаче данных двух форм, формы и класса. Подобные темы возникают очень часто, но в данном FAQ нет главного примера — использование событий, которые, как я считаю, являются самым верным способом для передачи к-либо данных.
Итак, вот участки кода. Для лучшего понимания прикрепляю архив с проектом. Имеем:
1.Главная форма, с двумя датагридами и двумя кнопками.
2.Дополнительная форма с тремя текстовыми полями и одной кнопкой.
3.Отдельный класс.
Логика работы: по нажатию на кнопку получения данных из доп.формы, открывается окно второй формы. Заполняем текстовые поля, и по нажатию кнопки форма закрывается, а данные из полей оказываются в гриде 1. По нажатию кнопки получения данных из класса создается объект класса, в конструкторе класса формируется таблица, которая при вызове метода класса передает данные в осн. форму, где они отображаются в гриде 2.
Также уточню, что передачу таблиц я выбрал для наглядности, и передавать таким способом можно все что угодно, используя приведенный шаблон
PS.В моем коде специально не использовались анонимные делегаты и лямбда, для облегчения восприятия новичками.
Код основной формы:
Вложения
FormsCommunicatoinTest.rar (51.7 Кб, 1461 просмотров) |
Комментарий модератора | ||
|
Меню пользователя @ tezaurismosis |
Читать блог |
Найти вероятность того, что студент, выбирая ответы наугад, ответит на 10 вопросов
Машина-экзаменатор содержит 12 вопросов, на каждый из которых предлагается 4 варианта ответа.
Ответы на Комплект вопросов сертиф экз «1С:Бухгалтерия 8» ред. 1.6
У кого есть ответы на «Комплект вопросов сертифицированного экзамена по программе «1С:Бухгалтерия.
на ответы@mail.ru на один из моих вопросов, где я уточнил, что использую ubuntu 10.10 мне сказали, что.
на ответы@mail.ru на один из моих вопросов, где я уточнил, что использую ubuntu 10.10 мне сказали.
Найти два самых больших и самых маленьких элементов массива
Одномерные массивы для обычных массивов и для класса Array. Составить программу нахождения двух.
Использование собственного класса в Windows Forms
Использование собственного класса в Windows Forms
Здравствуйте! Прошу помочь мне с использованием собственного класса (последовательный алгоритм.
Использование собственного класса в Виндовс Формс
Надо сделать программу на Windows Forms. По сути ето типа база данных транспортных средств должа.
Использование Boost в Windows Forms
Здравствуйте, возникла необходимость использовать библиотеки boost в windows forms. Скачал.
Использование WinINet в Windows Forms
Возможно использовать WinInet в Windows Form или нет. Если возможно то пожалуйста подскажите как.
Matrix_of_Light
1>Matrix_Lite.obj : error LNK2020: неразрешенная лексема (06000005) Matrix_of_Light::elem_trans_inverse
1>Matrix_Lite.obj : error LNK2020: неразрешенная лексема (06000006) Matrix_of_Light::Res
1>Matrix_Lite.obj : error LNK2020: неразрешенная лексема (06000007) Matrix_of_Light::elem_trans_determ
1>d:\мои документы\visual studio 2010\Projects\Matrix_Lite\Debug\Matrix_Lite.exe : fatal error LNK1120: 7 неразрешенных внешних элементов
Подключаю #include «Class_Matrix.h» в cpp проекта.
Вот код класса:
.h
Странно, что он не ругается на конструктор. Я подумал, что это из-за того, что там массива нет, попробовал убрать массивы в других функциях, не помогло.
. понятно, на конструктор он тоже ругается, в тексте ошибки он его почему-то .ctor обозвал.
Добавлено через 17 минут
нашел на одном форуме похожую тему, там написали, что шаблоны нельзя выносить в .cpp файл. Переместил, те функции, которые у меня уже были описаны в хедэр и они перестали отображаться как запрещенные лексемы, значит вроде как решил проблему?