Файлы к лабораторной работе Вы можете скачать здесь.
В данной лабораторной работе мы рассмотрим некоторые возможности
интегрированной среды ) Visual Studio.NET 2005. Мы будем
использовать разработанный Microsoft самый красивый
и современный язык программирования C# (.NET Framework ( -
Framework BCL -
Выполните
команду File/New/Project оболочки для создания нового проекта
В
диалоговом окне New Project выберите кнопкой Browse папку
для размещения проекта, задайте тип, шаблон и имя проекта WinFormsApp
После щелчка на кнопке OK мастер создаст
заготовку приложения и выведет в режиме дизайна пустую форму,
которая при запуске приложения будет представлять окно. Стандартный
размер сгенерированной формы равен 300x300.
Сделаем эту форму стартовой и разместим на ней элементы управления
для вызова дочерних форм, реализующих отдельные упражнения
данной работы.
Откройте
панель Solution Explorer оболочки и переименуйте файл Form1.cs в файл Start.cs
Щелкните
на форме правой кнопкой мыши и выполните команду контекстного
меню View Em, чтобы вызвать представление файла Start.cs в режиме 
В
режиме кода вызовите комбинацией клавиш Ctrl-F
окно Find and Replace для замены всех
вхождений Form1 на Start.
После заполнения полей поиска и замены щелкните на кнопке Replace All
В
раскрывающемся списке Members выделите функцию InitializeComponent(),
чтобы быстро позиционироваться в соответствующее место
кода
Отредактируйте
в функции InitializeComponent() код
установки заголовка окна в режиме выполненияprivate void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Text = "Lab38 - Снетков";
}
Теперь давайте добавим к главной форме Start код
поддержки пароля при запуске приложения. Для этого нам потребуется
диалоговое окно с текстовым полем. Сконструируем его. Создание
диалогового окна будет состоять из трех шагов:
InputPassword )
В
панели Solution Explorer выделите корневой
узел проекта и командой Add/Windows Form добавьте
в проект файл формы с именем InputPassword.cs
Удалите
из узла References лишние добавленные
мастером ссылки на библиотечные сборки System.Data и System.Xml
Откройте
файл InputPassword.cs в режиме View
Code и удалите инструкции using подключения
пространств имен System.Data и System.Xml
Настройте
форму InputPassword в соответствии с таблицей| Свойство | Значение | Пояснения |
|---|---|---|
StartPosition |
CenterScreen |
Открывать в центре экрана |
FormBorderStyle |
FixedDialog |
Запретить пользователю менять размер |
MaximizeBox |
false |
Отключить системную кнопку |
MinimizeBox |
falseStandardDialogs |
Отключить системную кнопку свертывания |
ShowInTaskbar |
false |
Запретить появление в панели задач |
|
true |
Подстраиваться под содержимое |
AutoSizeMode |
GrowAndShrink |
Подстраиваться под содержимое (расширяться и сжиматься) |
Text |
Пусто |
Заголовок окна |
Из
свитка Containers панели инструментов Toolbox поместите
на форму компоновочную панель FlowLayoutPanel и
настройти ее в соответствии с таблицей| Свойство | Значение | Пояснения |
|---|---|---|
Name |
|
Имя компоновочной панели |
|
true |
Подстраиваться под содержимое |
FlowDirection |
TopDown |
Размещать сверху вниз |
WrapContents |
false |
Не переносить дочерние элементы в следующий столбец |
|
8 |
|
|
|
Распахнуть на всю клиентскую область родителя (формы) |
Эта панель будет автоматически следить за размещением своих дочерних элементов в соответствии с настройками.
Выделите
на форме компоновочную панель flow , чтобы
именно она принимала дочерние элементы, поместите в нее
из свитка Common Controls текстовую метку Label и
настройте ее свойства в соответствии с таблицей| Свойство | Значение | Пояснения |
|---|---|---|
Name |
lblMessage |
Имя текстовой метки |
|
true |
Подстраиваться под содержимое |
|
None |
Расположить посредине |
|
8 |
Отступ по наружному периметру текстовой метки |
Аналогичным
образом поместите в панель flow последовательно
экземпляры компонентов TextBox и Button,
которые настройте так| Свойство | Значение | Пояснения |
|---|---|---|
Name |
txtInput |
Имя текстовой метки |
|
None |
Расположить посредине |
|
8 |
Отступ по наружному периметру текстовой метки |
PasswordChar |
* |
Эхо ввода в текстовом поле |
| Свойство | Значение | Пояснения |
|---|---|---|
Name |
btnOk |
Имя кнопки |
|
true |
Подстраиваться под содержимое |
|
None |
Расположить посредине |
|
8 |
Отступ по наружному периметру кнопки |
Text |
OK |
Надпись |
DialogResult |
OK |
Назначить статус "кнопки OK" в родительской форме |
Свойству дочерних кнопок формы DialogResult можно
присвоить любое значение из перечисления System.Windows.Forms.DialogResult ( , , , No, None, OK, , 25_73 ).
Оно и будет возвращено функцией ShowDialog() формы,
если пользователь выберет именно эту кнопку. Если свойству DialogResult кнопки
будет присвоен статус, отличный от None,
то при щелчке пользователя на такой кнопке форма будет автоматически
закрываться.
Подтяните
низ формы до приемлемого размера, чтобы она стала выглядеть
примерно так
Откройте
файл InputPassword.cs в режиме View
Designer, щелкните на заголовке формы и выполните
команду Format/Lock Controls, чтобы защитить
интерфейс формы от случайных изменений. Это групповая команда,
которая устанавливает свойство Locked всех
дочерних визуальных элементов и самой формы в значение True.
То же самое можно сделать индивидуально для каждого элемента
через меню PropertiesМы создали сам пользовательский интерфейс класса InputPassword диалогового
окна. Теперь нужно настроить класс InputPassword,
добавив туда метод создания диалогового окна и вызова его
на экран.
Модифицируйте
класс InputPassword следующим образомusing System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace WinFormsApp
{
public partial class InputPassword : Form
{
public InputPassword()
{
InitializeComponent();
}
public InputPassword(string windowTitle, string message)
{
InitializeComponent();
this.Text = windowTitle;
lblMessage.Text = message;
}
public static string Show(string windowTitle, string message)
{
using(InputPassword inputDlg =
new InputPassword(windowTitle, message))
{
inputDlg.ShowDialog();
return inputDlg.txtInput.Text;
}
}
}
}
Мы создали параметризованный конструктор для ввода заголовков
диалогового окна в момент его создания. Мы добавили статический
метод создания диалогового окна, который возвращает значение
текстового поля после щелчка пользователем на кнопке, и такой
метод нужно вызывать по имени класса. Упаковка создания экземпляра
формы в блок using позволяет вызвать сборщик
мусора сразу после выхода из этого блока.
Теперь нужно поместить вызов окна запроса пароля в обработчик
события Load запуска формы.
Откройте
файл Start.cs в режиме View Designer,
выделите форму через ее заголовок, перейдите в панель Properties,
установите ее в режим Events , найдите
событие Load и создайте для него обработчик Start_Load().
Заполните обработчик события такprivate void Start_Load(object sender, System.EventArgs e)
{
string password = InputPassword.Show(
"Окно аутентификации пользователя",
"Просим ввести Ваш пароль:");
if (password != "root")// Плохой способ хранения пароля
{
MessageBox.Show(
"Извините, но Вам не разрешено\n" // Сообщение
+ "пользоваться этой суперпрограммой!!!",
"Неверный пароль", // Заголовок окна
MessageBoxButtons.OK, // Кнопка OK
MessageBoxIcon.Stop);// Критическая иконка
this.Close();
}
}
Запустите
приложение, диалоговое окно ввода пароля должно
выглядеть так
При неправильном пароле появляется простое диалоговое окно сообщений

и приложение завершит свою работу.
На стартовой форме мы создадим список с наименованиями упражнений, который будем пополнять по мере их выполнения. В окончательном варианте работы щелчок по пункту списка должен запускать дочернюю форму, соответствующую выполненному упражнению. Это удобно при демонстрации выполненной лабораторной работы.
Перейдите
в режим Design, откройте в панели Toolbox вкладку Common
Controls и
двойным щелчком на компоненте ListBox создайте
на форме его экземпляр
Выделите
объект listBox1 и в панели Properties установите
для него следующие значения свойств| Свойство | Значение |
|---|---|
Name |
generalList |
|
|
Items |
1) Простое диалоговое окно со смайликами |
Щелкните
на заголовке формы и увеличьте ее ширину за маркеры так,
чтобы поместилось все предложение в списке ListBox.
Через
раскрывающийся список вверху панели Properties выделите
объект generalList и установите для нее
режим Events
Найдите
событие SelectedIndexChanged и двойным
щелчком на его поле
значений создайте обработчик generalList_SelectedIndexChanged()Теперь мы будем добавлять к приложению новые формы для выполнения каждого нового упражнения, регистрировать их в списке и помещать вызовы упражнений в этот обработчик главной формы.
Выполните
команду Project/Add Windows Form, чтобы
добавить к проекту новую форму
Задайте
имя новой форме Smiles.cs (Улыбки)
Поместите
на форму три компонента PictureBox из
вкладки Common Controls панели Toolbox ,
текстовую метку Label и
одну кнопку Button.
Все расположите так, как показано на снимке экрана (установите
свойство label1.AutoSize
=false )
Для
выравнивания компонентов пользуйтесь командами меню
оболочки, входящими в категорию Format,
или одноименными кнопками панели инструментов
Выполните
команду меню Format/Lock Controls, чтобы
закрепить расположение интерфейсных элементов на форме
и, тем самым, защитить их от случайного сдвига или изменения
размеров. Обратите внимание, что теперь на выделенных
элементах маркеры сменились гладкой рамкой с пиктограммой
замкаТеперь давайте установим для помещенных на форму объектов
нужные свойства через панель Properties.
При этом важно понимать, что все визуальные манипуляции с
формой и помещенными на нее компонентами, в том числе и установка
свойств через панель Properties, - это ничто иное, как удобный
и наглядный способ генерации кода с помощью графических средств
оболочки. Наша работа в режиме дизайна сопровождается параллельной
работой оболочки в режиме кода. И все, что можно сделать
через
Графические возможности являются бесспорным
помощником только при разработке пользовательского интерфейса
окон. Но дальнейшая работа
требует от программиста широких профессиональных знаний не
только принципов программирования и тонкого знания языка
- как основного инструмента, но и знания
Интерфейс пользователя является только посредником. Но и его значения умалять нельзя. Вычурный, непонятный, крикливый интерфейс может сослужить плохую службу действительно толковой программе. Нужно стремиться к простому и понятному интерфейсу, по-возможности вписывающемуся в уже сложившиеся представления о принципах программного взаимодействия с пользователем.
Задайте
свойства размещенных на форме объектов через панель Properties в порядке их следования слева-направо,
сверху-вниз, как указано в таблице| Класс | Свойство | Значение | Пояснения |
|---|---|---|---|
Form |
Text |
Smiles - Упражнение №1 | Заголовок окна |
FormBorderStyle |
FixedDialog | Запретили изменение размера окна формы | |
MaximizeBox |
False | Отключили системную кнопку |
|
MinimizeBox |
False | Запретили системную кнопку свертывания окна | |
PictureBox |
Name |
picSmile | |
Image |
FACE02.ICO (возьмите из данной работы в каталоге Source.
Используйте кнопку Import для радиокнопки Local
) |
Файл рисунка | |
SizeMode |
StretchImage | Опция - растянуть рисунок по размерам объекта | |
PictureBox |
Name |
picFrown | |
|
Image |
FACE04.ICO (возьмите
из данной работы в каталоге Source. Используйте кнопку Import для
радиокнопки Local ) |
Файл рисунка |
SizeMode |
StretchImage | Опция - растянуть рисунок по размерам объекта | |
PictureBox |
Name |
picHappy | |
Image |
FACE03.ICO (возьмите
из данной работы в каталоге Source. Используйте кнопку Import для
радиокнопки Local ) |
Файл рисунка | |
SizeMode |
StretchImage | Опция - растянуть рисунок по размерам объекта | |
Label |
Name |
lblMessage | |
Text |
Щелкайте на смайликах | Начальное содержимое текстовой метки | |
Font/Name |
Arial | Наименование шрифта | |
Font/Size |
14 | ||
Font/ |
True | Полужирный | |
ForeColor |
Red | Цвет переднего плана (красный) | |
TextAlign |
MiddleCenter | Выравнивание текста - середина по вертикали, центр по горизонтали | |
|
Fixed3D | Объемный вид элемента | |
Button |
Name |
btnExit | |
Text |
Выход | Надпись на кнопке |
|
|
true | Подстраиваться под размер надписи |
После всех настроек внешний вид формы должен быть примерно таким

Разработку интерфейса первой дочерней формы на этом можно считать завершенной. Теперь пришла пора обеспечить ее функциональность.
Выделите
первый смайлик picSmile и
через панель Properties (в режиме Events )
создайте обработчик события Click
Заполните
обработчик следующим кодомprivate void picSmile_Click(object sender, System.EventArgs e)
{
picSmile.BorderStyle = BorderStyle.FixedSingle; // Рамка
picFrown.BorderStyle = BorderStyle.None; // Нет рамки
picHappy.BorderStyle = BorderStyle.None; // Нет рамки
lblMessage.Text = "Щелкнули на первом рисунке";
}
Двойным
щелчком на втором рисунке ( picFrown ) создайте
для него обработчик, который заполните такprivate void picFrown_Click(object sender, System.EventArgs e)
{
picSmile.BorderStyle = BorderStyle.None; // Нет рамки
picFrown.BorderStyle = BorderStyle.FixedSingle; // Рамка
picHappy.BorderStyle = BorderStyle.None; // Нет рамки
lblMessage.Text = "Щелкнули на втором рисунке";
}
Двойным
щелчком на третьем рисунке ( picHappy )
создайте для него обработчик, который заполните такprivate void picHappy_Click(object sender, System.EventArgs e)
{
picSmile.BorderStyle = BorderStyle.None; // Нет рамки
picFrown.BorderStyle = BorderStyle.None; // Нет рамки
picHappy.BorderStyle = BorderStyle.FixedSingle; // Рамка
lblMessage.Text = "Щелкнули на третьем рисунке";
}
Двойным
щелчком на кнопке btnExit создайте
для нее обработчик, который заполните такprivate void btnExit_Click(object sender, System.EventArgs e)
{
this.Close(); // Закрыть форму
}
Теперь подключим вызов этой дочерней формы к движку приложения, обеспечив возможность ее вызова по щелчку на соответствующей строке списка с упражнениями.
Сохраните
проект командой меню File/Save All и закройте
все окна редактирования командой Window/Close All
Documents.
В
панели Solution Explorer щелкните правой
кнопкой мыши на файле Start.cs и
выполните команду контекстного меню View
Designer (или откройте файл в режиме дизайна двойным
щелчком левой кнопки мыши).
Выделите
элемент списка generalList и через панель Properties щелкните два раза на имени
уже созданного обработчика в поле события SelectedIndexChanged,
чтобы быстро позиционироваться к заголовку кода обработчика.
Заполните обработчик следующим кодомprivate void generalList_SelectedIndexChanged(object sender, System.EventArgs e)
{
switch(generalList.SelectedIndex + 1)
{
case 1:
Smiles frm1 = new Smiles();
frm1.ShowDialog();
break;
}
}
Здесь мы применили метод ShowDialog() класса Form (вместо
метода Show() ). Это позволит нам открывать
дочерние формы в модальном режиме
(пока не закроется очередная форма, другие окна приложения
не получат фокус ввода).
Выделите
в режиме дизайна форму Start (щелкните
на заголовке окна формы) и установите через панель Properties ee
свойство StartPosition в
значение CenterScreen,
чтобы при первом запуске она появлялась в центре экрана
Откройте
в режиме дизайна (в панели Solution Explorer ) форму Smiles,
выделите ее через заголовок окна формы и установите свойство StartPosition в значение Manual . Проследите, чтобы свойство Location (размещение) имело значение ( 0,
0 ). Тем самым
мы задали позицию появления дочерней формы в верхнем левом
углу экрана.Два последних действия позволят нам держать форму движка в центре экрана, а дочерние формы задвинуть в начало экрана (удобно для демонстрации упражнений, полезно для тренировки).
Запустите
приложение и проверьте его работоспособностьНа этапе построения формы бывает полезным сразу запускать
ее для проверки. В нашем случае форма Smiles может
быть вызвана только из главной формы. Исправим это.
Добавьте
в конец класса Smiles следующую функцию-член Main(),
которая позволит отображать форму первой при запуске приложенияpublic class Smiles : System.Windows.Forms.Form
{
..............................................................
private void btnExit_Click(object sender, System.EventArgs e)
{
this.Close(); // Закрыть форму
}
static void Main()
{
Application.Run(new Smiles());
}
}
Установите
в качестве стартовой форму Smiles. Для этого выполните
команду меню оболочки Project/WinFormsApp Properties и
в появившемся диалоговом окне установите свойство Startup
Object в значение WinFormsApp.Smiles
Запустите
приложение и убедитесь, что теперь дочерняя форма Smiles стартует
первой и единственной.Вкладка All Windows Forms панели Toolbox содержит
все компоненты, которые необходимы для быстрой
разработки интерфейса пользователя. Она становится доступной,
когда форма открыта в режиме Design и текущее
приложение не запущено. Режим Design и компоненты
панели - это
лишь инструменты для частичной C# приложения в файле *.cs.
Все компоненты поддерживаются соответствующими классами и
доступны для управления ими программным путем.
В таблице приведено краткое описание части компонентов, а в упражнениях этой работы мы продемонстрируем возможности некоторых из них.
| Компонент | Назначение |
|---|---|
![]() |
Установка курсора в режим выделения объектов. |
![]() Button |
Инструмент для генерирования события щелчка, по которому вызывается функция - обработчик. В эту функцию можно разместить любой код, который требуется выполнить при щелчке на этом инструменте. |
![]() |
Дает возможность пользователю установить нужный режим
из двух возможных. При обединении этих элементов в тематическую
|
![]() CheckedListBox |
Множество элементов |
![]() ColorDialog |
Стандартное диалоговое окно для предоставления пользователю возможности выбирать цвета |
![]() ComboBox |
Раскрывающийся список. Состоит из верхней части с редактируемым текстовым полем, и нижней части со списком для выбора готовых элементов. |
![]() ContextMenuStrip |
Контекстные меню обычно вызываются щелчком правой кнопкой мыши на нужном элементе управления формы. Туда обычно включают часто используемые команды из основного меню приложения. Это обеспечивает быстрый доступ пользователя к таким командам. |
![]() DataGridView |
Этот элемент отображает данные в виде таблицы, состоящей
из строк и столбцов. В простейшем случае этот элемент
просто отображает все данные связанной с ним одной таблицы
базы данных без всяких условий и позволяет оперировать
с ними как в обычной электронной таблице. В более сложном
случае элемент отображает |
![]() DateTimePicker |
Этот элемент дает возможность пользователю быстро выбирать нужные дату из предоставляемого удобного интерфейса в виде календаря. |
![]() DomainUpDown |
Представляет собой текстовое поле со стрелками для изменения значений списка вверх или вниз. |
![]() ErrorProvider |
Этот элемент управления (невизуальный компонент) применяется для проверки правильности пользовательского ввода в допустимых пределах данных. Он предоставляет разработчику удобный интерфейс для оповещения пользователя о допущенных нарушениях и является лучшей заменой простому окну сообщений. |
![]() FolderBrowserDialog |
Представляет собой диалоговое окно для навигации по папкам файловой системы компьютера. |
![]() FontDialog |
Является стандартным диалоговоым окном, с помощью которого можно выбирать шрифты, установленные в настоящее время на текущем компьютере. |
![]() |
Применяется для |
![]() HelpProvider |
Используется для |
![]() HScrollBar |
Самостоятельный элемент управления, который присоединяется к другим элементам интерфейса для продвижения по большим массивам информации в горизонтальном направлении. |
![]() ImageList |
Используется для хранения последовательности рисунков, подлежащих отображению приложением. Рисунки можно выбирать с помощью индексов списка и отображать на экране другими элементами управления. |
![]() Label |
Простая текстовая метка для отображения нередактируемого текста на экране компьютера. |
![]() LinkLabel |
Позволяет использовать текстовую метку в стиле гиперссылки. С помощью этого элемента часть текста можно связать с файлом, каталогом или Web-страницей. |
![]() ListBox |
Отображает список элементов, из которых пользователь
может выбрать один или несколько элементов. Если количество
элементов в вписке превышает то, что может быть отображено,
то автоматически добавляется вертикальная MultiColumn в значение true добавляется
горизонтальная true свойство ScrollAlwaysVisible, то SelectionMode устанавливает,
сколько элементов списка может быть выделено одновременно.
Свойство SelectedIndex возвращает индекс
первого выделенного элемента в списке, начиная с нуля.
Если нет выделенных элементов, свойство возвращает значение
-1. |
![]() ListView |
Отображает список элементов с иконками, наподобие правой
области Windows Explorer. Элемент имеет четыре
режима отображения: LargeIcon, SmallIcon, List, и . |
![]() MenuStrip |
Создает главное меню формы, за пунктами которого можно закреплять различные команды управления приложением. |
![]() MonthCalendar |
Обеспечивает привычный интерфейс работы с датой в виде календаря. |
![]() NotifyIcon |
Используется для отображения в виде значков процессов,
которые выполняются в фоновом режиме и долгое время не
видны пользователю. Примером может служить программа
|
![]() NumericUpDown |
Представляет собой комбинацию текстового поля и пары стрелок, которые пользователь может применять для наглядного управления целым числовым значением. |
![]() OpenFileDialog |
Представляет стандартное диалоговое окно |
![]() PageSetupDialog |
Предоставляет стандартное диалоговое окно настройки страницы документа при печати. |
![]() Panel |
Элемент Panel подобен элементу .
Применяется для |
![]() PictureBox |
Элемент служит для отображения рисунков в формате
Image.
Свойство SizeMode устанавливает режим согласования
размеров элемента и рисунка. Рисунок отображается как в режиме
разработки, так и во время выполнения приложения. |
![]() PrintDialog |
Это стандартное диалоговое окно используется для настроек принтера перед печатью. |
![]() PrintDocument |
Устанавливает, что печатать и как печатать.
Может использоваться совместно с элементом PrintDialog для
полного описания всех аспектов печати. |
![]() PrintPreviewControl |
Позволяет предварительно просмотреть документ перед печатью, как он будет выглядеть после печати. |
![]() PrintPreviewDialog |
Позволяет предварительно просмотреть документ перед печатью, как он будет выглядеть после печати. Отображает стандартное диалоговое окно с необходимыми элементами управления. |
![]() ProgressBar |
Индикаторная линейка - отображает продвижение процесса в горизонтальном направлении. |
![]() RadioButton |
Радиокнопка (переключатель) |
![]() RichTextBox |
Представляет собой полноценный текстовый редактор. |
![]() SaveFileDialog |
Обеспечивает стандартный настраиваемый диалог сохранения файлов. |
![]() |
Используется для изменения |
![]() StatusBar |
Элемент создает строку состояния. |
![]() TabControl |
Элемент для создания вкладок. Создает одну или несколько вкладок, на каждой из которых могут быть размещены другие объекты. |
![]() TextBox |
Редактируемое текстовое поле. |
![]() |
|
![]() ToolStrip |
Панель инструментов - контейнер для кнопок быстрого доступа. |
![]() |
Для создания всплывающих коротких подсказок, которые появляются при наведении курсора на элемент управления. |
![]() TrackBar |
Регулятор для визуального изменения числовой информации
(иногда называют |
![]() |
Отображает информацию в древовидном формате. |
![]() VScrollBar |
Самостоятельный элемент управления, который присоединяется к другим элементам интерфейса для продвижения по большим массивам информации в вертикальном направлении. |
Toolbox и
выполнив команду контекстного меню Add
Tab.
Удалить вкладку можно, щелкнув правой кнопкой мыши на
заголовке соответствующей вкладки и выполнив команду Delete Tab.
Копировать нужные компоненты из одной вкладки в другую
можно выполнением команд контекстного меню Copy и Paste.Разработаем калькулятор, выполняющий простые действия над
целыми и
Добавьте
к проекту новую форму командой Project/Add Windows
Form и задайте ей имя Calculate 
Поместите
на форму элементы из вкладки Common Controls панели Toolbox в
соответствии с таблицей, чтобы пользовательский интерфейс
формы был таким
| Элемент | Свойство | Значение |
|---|---|---|
Form |
Name |
|
StartPosition |
|
|
Location |
0; 0 |
|
Text |
Простой калькулятор |
|
|
Выбрать по усмотрению...(можно из Source) |
|
FormBorderStyle |
FixedDialog |
|
Label |
Name |
lblFirst |
Text |
Первое число: |
|
TextAlign |
MiddleRight |
|
Label |
Name |
lblSecond |
Text |
Второе число: |
|
TextAlign |
MiddleRight |
|
Label |
Name |
lblResult |
Text |
Результат: |
|
TextAlign |
MiddleRight |
|
TextBox |
Name |
txtFirst |
Text |
пусто |
|
TextBox |
Name |
txtSecond |
Text |
пусто |
|
TextBox |
Name |
txtResult |
Text |
пусто |
|
|
True |
|
TabStop |
False |
|
Button |
Name |
btnIncrement |
Text |
+ |
|
Font/ |
True |
|
Font/Size |
20 |
|
Size |
40; 40 |
|
Button |
Name |
btnDecrement |
Text |
- |
|
Font/Name |
Courier New |
|
| Font/ |
True |
|
Font/Size |
20 |
|
Size |
40; 40 |
|
Button |
Name |
btnIncrease |
Text |
* |
|
Font/Name |
Courier New |
|
Font/ |
True |
|
Font/Size |
20 |
|
Size |
40; 40 |
|
Button |
Name |
btnDivide |
Text |
: | |
Font/Name |
Courier New |
|
Font/ |
True |
|
Font/Size |
20 |
|
Size |
40; 40 |
|
Button |
Name |
btnExit |
Text |
Выход |
Здесь мы использовали
некоторые префиксы при
назначении имен элементам управления. Для лучшей узнаваемости
в
| Объект | Префикс |
|---|---|
Button |
btn |
|
chk |
ComboBox |
|
|
|
Form |
frm |
Label |
|
ListBox |
lst |
MenuStrip |
mnu |
PictureBox |
|
RadioButton |
|
TextBox |
txt |
Добавьте
к классу Calculate функцию Main() для автономной отладки
формыstatic void Main()
{
Application.Run(new Calculate());
}
Выполните
команду меню WinFormsApp Properties и
для вкладки Application установите в свойстве Startup
Object форму Calculate стартовой
Защитите
интерфейс формы Calculate от случайных
изменений, выполнив команду Format/Lock
Controls меню оболочкиТеперь нужно реализовать функциональность интерфейса. Прежде всего нужно защитить поля ввода от всех символов, кроме цифр, одного знака минус и одной точки. Стрелки и клавиша Del в текстовых полях функционируют, но работу клавиши Backspace нужно учесть явно.
Объявите
в конце класса Calculate логическое
поле isNumeric для
отфильтровывания нецифровых символов, которые пользователь
может попытаться ввести в текстовые поляprivate bool isNumber = false;
Выделите
текстовое поле txtFirst и через панель Properties в
режиме Events создайте обработчик для события KeyDown.
Заполните обработчик такprivate bool isNumber = false;
private void txtFirst_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
isNumber =
e.KeyCode >= Keys.D0 e.KeyCode <= Keys.D9 // keyboard - основная клавиатура
|| e.KeyCode >= Keys.NumPad0 e.KeyCode <= Keys.NumPad9 // keypad - дополнительная клавиатура
|| e.KeyCode == Keys.Back;
}
Выделите
текстовое поле txtFirst и через панель Properties в
режиме Events создайте обработчик для
события KeyPress . Заполните обработчик
такprivate void txtFirst_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
TextBox box = (TextBox) sender;// Явное преобразование типов
switch(e.KeyChar) // Переключатель
{
case '-': // Разрешаем минус, если он первый
if(box.Text.Length == 0)
isNumber = true;
break;
case '.':
// Точка не должна быть первой
if(box.Text.Length == 0)
break;
// Точка не должна следовать сразу за минусом
if(box.Text[0] == '-' box.Text.Length == 1)
break;
// Точка должна быть одна
if(box.Text.IndexOf('.') == -1)
isNumber = true; // Еще не было точек
break;
}
// Запрещаем в текстовом поле лишние символы
if(!isNumber)
e.Handled = true;
}
Выделите
текстовое поле txtSecond и через панель Properties в
режиме Events подключите к событиям KeyDown и KeyPress соответствующие
обработчики, только что созданные для поля txtFirst.
Обработчики подключите через раскрывающиеся списки
полей значений
Здесь мы одни и те же обработчики используем для разных
полей, поскольку необходимо выполнять одинаковые действия.
Задача одна - не допускать для ввода в поля никакие другие
символы, кроме цифр, одного минуса и одной точки.
Возможность ввода цифр реализована для основной ( )
и дополнительной ( ) частей клавиатуры. Параметр sender передает
в обработчик ссылку на активное текстовое поле, вызвавшее
событие редактирования.
Конечно, программа будет более понятна, если для каждого элемента создавать свой обработчик. Но очень часто, как в нашем случае, преобладающая часть кода может быть совершенно одинакова в каждом обработчике. Тогда имеет смысл объединять несколько индивидуальных обработчиков в один. Какой подход выбрать - зависит от конкретной задачи и предпочтений программиста.
Добавьте
в конец класса Calculate объявления числовых
переменных, с которыми мы будем производить простые арифметические
операции// Объявляем числовые переменные как поля-члены класса
// Их можно объявить как локальные и внутри обработчика btn_Click()
// Но оставляем область видимости класс, вдруг где-нибудь еще пригодятся!
private double numFirst, numSecond, numResult;
Перейдите
в режим Design формы Calculate и выделите все четыре кнопки
с операциями
Установите
в панели Properties режим Events ,
найдите событие Click и введите вручную в
поле значений этого события имя обработчика btn_Click
В
созданный оболочкой общий обработчик для всех выделенных
кнопок введите следующий код// Один обработчик для всех кнопок-операций
private void btn_Click(object sender, System.EventArgs e)
{
// Копируем текстовые поля в локальные переменные
string strFirst = string.Copy(txtFirst.Text);
string strSecond = string.Copy(txtSecond.Text);
// Замена в строке точки символом запятой
// для корректного преобразования в число
int pos = strFirst.IndexOf('.');
if(pos != -1)
{
strFirst = strFirst.Substring(0, pos)
+ ','
+ strFirst.Substring(pos + 1);
}
pos = strSecond.IndexOf('.');
if(pos != -1)
{
strSecond = strSecond.Substring(0, pos)
+ ','
+ strSecond.Substring(pos + 1);
}
// Преобразуем текст в число для выполнения операций
if(txtFirst.Text.Length > 0)
numFirst = Convert.ToDouble(strFirst);
else
numFirst = 0.0D;
if(txtSecond.Text.Length > 0)
numSecond = Convert.ToDouble(strSecond);
else
numSecond = 0.0D;
// Выполняем нужную операцию
string btnText = "";// Создали строковую переменную
bool divideFlag = false;// Флаг деления на ноль
Button btn = (Button) sender;// Явное приведение типов для распознавания кнопок
switch(btn.Name)// Переключатель
{
case "btnIncrement":// Операция сложения
btnText = "\"+\"";// Экраны кавычек
numResult = numFirst + numSecond;
break;
case "btnDecrement":// Операция вычитания
btnText = "\"-\"";// Экраны кавычек
numResult = numFirst - numSecond;
break;
case "btnIncrease":// Операция умножения
btnText = "\"*\"";// Экраны кавычек
numResult = numFirst * numSecond;
break;
case "btnDivide":// Операция деления
btnText = "\":\"";// Экраны кавычек
// Проверяем корректность деления
if (Math.Abs(numSecond) < 1.0E-30)
{
MessageBox.Show(
"Делить на ноль нельзя!", // Сообщение
"Ошибка", // Заголовок окна
MessageBoxButtons.OK, // Кнопка OK
MessageBoxIcon.Stop);// Критическая иконка
divideFlag = true;
}
else
numResult = numFirst / numSecond;
break;
}
// Для отображения в панели Output режима Debug
System.Diagnostics.Debug.WriteLine("Нажата кнопка " + btnText);// Конкатенация
// Отображение результата
if(!divideFlag)
{
txtResult.Text = Convert.ToString(numResult);
this.Validate(); // Обновить экран (можно убрать-излишне)
}
}
Здесь мы прежде всего скопировали значения полей ввода в
промежуточные текстовые переменные, используя статический
метод System.String. Copy() класса String (string ).
Затем мы проверяем наличие символа "точки" в этих
переменных и при обнаружении производим замену на символ "запятая" с
полным формированием новой строки. Мы не можем заменить символ
"на месте" в существующей строке, обратившись к
нему как элементу массива, поскольку индексная форма
Но мы можем, сформировав новую строку справа от знака присваивания, присвоить результат вновь той же самой ссылке, которая фактически будет адресоваться к новой области памяти, а старая строка, как брошенный фрагмент памяти, будет оставлена для сборщика мусора. Операция замены точки на запятую выполняется для того, чтобы корректно преобразовать текстовое значение поля ввода в числовое, иначе генерируется исключение.
Далее мы явно приводим переданную в обработчик ссылку типа object на нажатую кнопку к типу Button.
В заголовке переключателя выделяем имя нажатой кнопки и выполняем
соответствующую
После переключателя мы располагаем оператор вывода строки System. с
выполненной операцией в панель оболочки Output.
Этот класс предназначен для работы с программой в отладочном
режиме
и автоматически изымается из кода
при компиляции окончательного варианта приложения в режиме .
На последнем этапе, в коде обработчика,
мы выводим результат в соответствующее текстовое поле с
предварительным
Теперь создадим обработчик нажатия на кнопку закрытия формы.
В
режиме Design двойным щелчком на кнопке btnExit создайте
обработчик, который заполните такprivate void btnExit_Click(object sender, System.EventArgs e)
{
this.Close();
}
Запустите
проект и проверьте функциональность простого калькулятораТеперь мы должны подключить разработанную форму калькулятора к основному окну приложения.
Установите
в качестве стартовой форму Start. Для
этого выполните команду меню оболочки Project/WinFormsApp
Properties и в появившемся диалоговом окне установите
для вкладки Application свойство Startup
Object в
значение WinFormsApp.Program
Откройте
файл Start.cs в режиме View Code.
Через раскрывающийся список Members в
верхней части окна generalList_SelectedIndexChanged(),
который мы создали ранее, и дополните его вызовом окна
калькулятораprivate void generalList_SelectedIndexChanged(object sender, System.EventArgs e)
{
switch(generalList.SelectedIndex + 1)
{
case 1:
Smiles frm1 = new Smiles();
frm1.ShowDialog();
break;
case 2:
Calculate frm2 = new Calculate();
frm2.ShowDialog();
break;
}
}
В
панели Solution Explorer оболочки щелкните
дважды на пиктограмме файла Start.cs,
чтобы открыть его в режиме View
Designer,
выделите элемент списка в клиентской области формы и через
панель Properties добавьте в свойство Items строку
" 2)
Простой калькулятор "
Запустите
приложение и проверьте его работоспособностьВ C# под коллекцией понимается группа объектов,
возможно, не одинаковых типов. Самым простым примером коллекции
является обычный массив. Но в отличие от массива коллекции
способны хранить объекты разных System.Collections библиотеки mscorlib.dll
C# - классы коллекций по сути аналогичны классам стандартной
библиотеки шаблонов ( - Standard C++. То, что в C++ называется контейнером,
в C# именуется коллекцией. Коллекции
упрощают программирование, предлагая уже готовые решения
для построения структур данных, разработка которых "с нуля"
потребовала бы больших затрат.
Основное достоинство коллекций состоит в том, что они упрощают
работу с группами объектов в , IComparer, IDictionary и т.д.).
Для контроля за запуском форм упражнений и предотвращения
их повторного запуска можно использовать обычный массив,
куда при каждом запуске очередной формы сохранять метку
на форму и при повторной попытке проверять существование
этой метки. Но недостатком использования массива является
его фиксированный размер, определяемый однажды при создании
массива. Коллекцию использовать удобнее, поскольку механизм
автоматического изменения размера в нее уже встроен, и предусмотрен
ряд полезных методов для управления коллекцией. Все коллекции
предполагают использование цикла foreach (в
каждом) для
Мы будем использовать класс ,
представляющий собой массив переменной длины ( динамический
массив ), элементами которого являются объектные ссылки. Только,
для удобства и тренировки мы упакуем этот класс в свой класс,
в котором предусмотрим необходимые нам методы и свойства.
При этом мы не будем создавать для нового класса отдельный
файл, а добавим его в файл Start.cs. Все методы класса и
ссылку на коллекцию сделаем статическими, чтобы не создавать
экземпляр класса в основном
Добавьте
в Start следующий код// Класс для предотвращения повторных запусков форм
public class Restart
{
// Создали коллекцию
private static System.Collections.ArrayList frmList =
new System.Collections.ArrayList();
// Метод для добавления метки в коллекцию
public static void Add(Object frm)
{
frmList.Add(frm);
}
// Метод для удаления метки из коллекции
public static void Remove(String str)
{
frmList.Remove(str);
}
// Метод, который отвечает на вопрос - запущена ли форма
public static bool IsPresent(Object frm)
{
bool flag = false;
foreach(Object x in frmList)
{
if(Object.Equals(x.ToString(), frm.ToString()))
flag = true;
}
return flag;
}
}
Найдите
в файле Start.cs обработчик generalList_SelectedIndexChanged() и
замените его тело на следующий кодprivate void generalList_SelectedIndexChanged(object sender, System.EventArgs e)
{
switch(generalList.SelectedIndex + 1)
{
case 1:
Smiles frm1 = new Smiles();
if(!Restart.IsPresent(frm1))
{
Restart.Add(frm1);
frm1.Show();
}
break;
case 2:
Calculate frm2 = new Calculate();
if(!Restart.IsPresent(frm2))
{
Restart.Add(frm2);
frm2.Show();
}
break;
}
}
В
режиме дизайна форм Smiles и Calculate создайте
обработчики для события FormClosed, которые
заполните кодом удаления метки из коллекции при закрытии
формыprivate void Smiles_FormClosed(object sender, FormClosedEventArgs e)
{
Restart.Remove(this.ToString());
}
private void Calculate_FormClosed(object sender, FormClosedEventArgs e)
{
Restart.Remove(this.ToString());
}
Запустите
приложение и проверьте, что повторный запуск уже запущенной
дочерней формы блокируетсяВ реализациях следующих упражнений этой лабораторной работы
нам необходимо соблюдать введенную нами технологию предотвращения
повторных запусков дочерних форм. Для этого в переключателе switch обработчика generalList_SelectedIndexChanged() нужно
добавлять метку запущенной формы в коллекцию нашего класса , а при закрытии дочерней формы необходимо удалять
эту метку из коллекции в обработчике события FormClosed.
В этом упражнении мы встроим COM -объект
( COM - - оболочки.
Чтобы не смешивать набор элементов стандартных вкладок панели ,
поместим этот элемент в отдельную вкладку.
Через
панель Solution Explorer откройте любой
файл проекта в режиме дизайна, чтобы стала доступна панель
инструментов Toolbox . Щелкните правой
кнопкой мыши на любом месте панели Toolbox и
через контекстное меню выполните команду Add
Tab
Присвойте
добавленной вкладке имя " Моя
вкладка " и раскройте ееMain() в файле Start.cs стоял
атрибут [STAThread],
который сообщает среде исполнения, что основной программный
поток приложения должен использовать однопоточную модель.
Это необходимо для правильного взаимодействия с подсистемой COM.
Щелкните
на новой вкладке правой кнопкой мыши и выполните команду
контекстного меню Choose Items
В
появившемся окне выберите вкладку COM Components,
найдите в списке Windows
Media Player, отметьте его и щелкните на
кнопке OK
После этого в новой вкладке панели появится
пиктограмма выбранного компонента

и его можно размещать на форме обычным образом.
Замечание.
Возможно, что оболочка на Вашем компьютере по умолчанию настроена
на другой тип COM -компонента, который будет
иметь другие свойства и события, чем используемый в этой
работе. В этом случае щелкните на кнопке вкладки COM
Components окна выбора элементов Choose
Toolboxs Items и в системном каталоге Windows/System32 выберите компонент msdxm..
Это и будет интересующий нас компонент

Через
меню оболочки выполните команду Project/Add Windows
Form ,
чтобы добавить к проекту новую форму, и в появившемся диалоговом
окне задайте имя файла формы MediaPlayer.cs
Поместите
на форму с вкладки " Моя вкладка " компонент
плеера. Форма после этого будет иметь такой вид
Выделите
компонент видеоплейера на форме и через панель Properties задайте
ему следующие свойства| Свойство | Значение | Пояснения |
|---|---|---|
Name |
|
Имя компонента |
AutoRewind |
True |
Автоперемотка, чтобы после просмотра видеоплеер устанавливался в начало |
AutoStart |
False |
Чтобы плеер не начинал проигрывать файл сразу после его открытия, а ждал отдельной команды на проигрывание |
ClickToPlay |
False |
Отключили возможность проигрывания/остановки по щелчку на самом плеере |
Size/Width |
286 |
Можно настроить в визуальном режиме |
Size/Height |
280 |
Можно настроить в визуальном режиме |
Перейдите
в режим редактирования кода файла MediaPlayer.cs и
добавьте в конец класса MediaPlayer точку
входа для автономного запуска вместе с атрибутом однопоточности [STAThread]// Точка входа
[STAThread]
static void Main()
{
Application.Run(new MediaPlayer());
}
Выполните
команду меню Project/WinFormsApp Properties и
установите в свойстве Startup Object значение WinFormsApp.MediaPlayer,
чтобы сделать форму плеера стартовой на период отладкиЕсли выделить компонент плеера и посмотреть его свойства
в панели Properties, то можно увидеть много
возможностей для его начальной настройки в режиме дизайна.
Вот некоторые из свойств
| Свойство | Пояснение |
|---|---|
|
Темп воспроизведения. Если установить его значение, например, равным 2, то файл будет проигрываться в удвоенном темпе |
PlayCount |
Сколько раз повторять проигрывание файла. При значении 0 воспроизведение файла будет повторяться бесконечно |
|
Файл для проигрывания |
|
(немой) Начальное состояние кнопки включения звука |
ShowControls |
Показывать или нет встроенную панель управления плеером |
ShowTracker |
(буксир) Показывать или нет ползунок поиска проигрывателя |
ShowAudioControls |
Показывать или нет элементы управления динамиком |
ShowDisplay |
Показывать или нет информационную панель со сведениями о проигрываемом файле |
ShowPosicionControls |
Отключает панель управления позицией головки проигрывателя |
CurrentPosition |
Содержит значение, на какой секунде находится в данный момент воспроизведение файла |
|
Громкость звука. Число 0 - самый громкий звук. Отрицательное число -10000 означает полную тишину |
|
Свойство только для чтения, доступно программно. Содержит общую продолжительность проигрываемого файла в секундах |
Часть из этих свойств можно настроить через окно свойств самого компонента, если щелкнуть на нем правой кнопкой мыши. Это окно устанавливает те же самые свойства через более понятный интерфейс

Продублируем встроенные элементы управления плеером своими. Эти действия будем выполнять последовательно шаг за шагом, сразу программируя и проверяя их работу.
Увеличьте
вниз размер формы так, чтобы освободить место для элементов
управления. Разместите на форме из вкладки Containers панели Toolbox элемент
управления GroupBox , который будет служить контейнером для
наших элементов. Задайте ему свойства: Name = groupBox , Dock =Text =" Мои
элементы управления "
Поместите
в верхней части контейнера groupBox четыре кнопки Button.
Кнопки помещайте так: щелкайте на компоненте Button вкладки Common
Controls панели Toolbox один
раз, затем щелкайте внутри контейнера groupBox .
Контейнер для кнопок будет родителем и
может передавать им значения своих свойств, например, местоположение,
цвет
Выровняйте
кнопки, используя панель инструментов Layout оболочки
Замкните
элементы управления групповой командой Format/Lock
Controls, чтобы случайно не нарушить дизайн
Задайте
кнопкам следующие свойства| Элемент | Свойство | Значение | Пояснения |
|---|---|---|---|
Button |
Name |
btnOpen | Кнопка для открытия диалога выбора проигрываемого файла |
Text |
Open | ||
Button |
Name |
btnPlay | Кнопка для начала воспроизведения |
Text |
|||
Button |
Name |
btnStop | Кнопка для остановки воспроизведения |
Text |
Stop | ||
Button |
Name |
btnRewind | Кнопка установки в начало воспроизведения |
Text |
Теперь нужно запрограммировать наши кнопки в соответствии с решаемой задачей.
Кнопка btnOpen должна
загружать файл, предназначенный для проигрывания. Воспользуемся стандартным
диалогом .
Поместите
из вкладки Dialogs панели Toolbox компонент OpenFileDialog.
Это невизуальный компонент (неотображаемый
на форме на
Настройте
объект диалога Properties, предварительно
выделив его в подвале | Элемент | Свойство | Значение | |
|---|---|---|---|
OpenFileDialog |
Name |
openFilePlayer | |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Wave (Microsoft) (*.wav) |*.wav| Dialogic VOX ADPCM (*.vox) |*.vox| InterVoice (*.ivc) |*.ivc| Macintosh AIFF (*.aif,*.aiff,*.snd) |*.aif,*.aiff,*.snd| MP3 Audio (*.mp3) |*.mp3| NeXT/Sun (Java) File (*.ai,*.snd) |*.ai,*.snd| OggVorbis (*.ogg) |*.ogg| Perfect Clarity Audio (*.pca) |*.pca| QuickTime (*.mov) |*.mov| Raw File (*.raw) |*.raw| RealMedia (*.rm) |*.rm| Sound Designer 1 (*.dig,*.sd) |*.dig,*.sd| Video for Windows (*.avi) |*.avi| Windows Media (*asf) |*asf| Windows Media Audio (*.wma) |*.wma| Windows Media Video (*.wmv) |*.wmv| All Files (*.*) |*.* |
|
FilterIndex |
13 |
Свойство предназначено для управления
пользователем типом отображаемых файлов, а свойство FilterIndex устанавливает,
какой фильтр появится первым при запуске окна. Фильтры в
свойстве следуют парами друг за другом " Название
фильтра|шаблон_фильтра " и разделяются
символом "Вертикальная черта".
Внимание!!! Если
вы будете копировать значение свойства прямо
из этой таблицы, то предварительно нужно убрать все невидимые
символы перевода на новую строку (например, в блокноте),
которые здесь введены в целях форматирования. Строка фильтра
должна быть непрерывной. В шаблонах_фильтране
должно быть пробелов ни внутри, ни в окружении,
иначе фильтр не сработает.
Создадим, как и в случае с калькулятором, один обработчик для всех размещенных ранее кнопок. Для этого выполните следующее...
Перейдите
в режим дизайна для файла MediaPlayer.cs,
выделите первую кнопку btnOpen и через
панель Properties для события Click в
поле его значений установите вручную имя
обработчика btnClick
Разместите
в созданном оболочкой обработчике следующий кодprivate void btnClick(object sender, System.EventArgs e)
{
Button btn = (Button) sender;// Явное приведение типов
switch(btn.Name)
{
case "btnOpen":
openFilePlayer.InitialDirectory = // Начальный каталог для фильтра
System.IO.Directory.GetCurrentDirectory();// Каталог исполнимого файла
openFilePlayer.ShowDialog();// Открываем диалог
Player.FileName = openFilePlayer.FileName;// Передаем имя файла в плеер
break;
}
}
Подсоедините
обработчик btnClick к остальным кнопкам.
Для этого откройте панель Properties в
режиме Events , выделите оставшиеся три
кнопки вместе и
через раскрывающийся список в поле значения свойства Click выберите
обработчик btnClick
Дополните
код обработчика btnClick такprivate void btnClick(object sender, System.EventArgs e)
{
Button btn = (Button) sender;// Явное приведение типов
switch(btn.Name)
{
case "btnOpen":
openFilePlayer.InitialDirectory = // Начальный каталог для фильтра
System.IO.Directory.GetCurrentDirectory();// Каталог исполнимого файла
openFilePlayer.ShowDialog();// Открываем диалог
Player.FileName = openFilePlayer.FileName;// Передаем имя файла в плеер
break;
case "btnPlay":
Player.Play();
break;
case "btnStop":
Player.Stop();
break;
case "btnRewind":
Player.CurrentPosition = 0;
break;
}
}
После завершения работы стандартного диалогового окна OpenFileDialog его
свойство либо содержит полное (вместе
с путем) имя выбранного файла, либо пустую строку, если пользователь
отказался от выбора.
Теперь мы готовы к Source файл " WellWait
- 02. "). Поэкспериментируйте с кнопками
- они все работают.
Но здесь есть одна проблема. Если пользователь после
запуска формы вначале щелкнет на кнопке btnPlay,
то будет сгенерировано исключение, поскольку нечего проигрывать.
Эту проблему можно решить двумя способами:
try...catchbtnPlay до тех
пор, пока не будет загружен файл для проигрыванияМы воспользуемся вторым способом. Для начального блокирования кнопки есть три пути:
Enabled кнопки
на FalseEnabled кнопки
в состояние false в MediaPlayerLoad и
разместить в нем код установки кнопки в недоступное состояниеМы воспользуемся последним способом. При этом будем блокировать
все кнопки, кроме btnOpen, чтобы лишний
раз не вводить в заблуждение нашего дорогого пользователя.
Перейдите
в режим View Designer формы, выделите
форму щелчком на ее заголовке или через раскрывающийся
список панели Properties, установите панель Properties в
режим Events и создайте обработчик события Load формы
двойным щелчком на поле значений этого события. Заполните
обработчик следующим кодомprivate void MediaPlayer_Load(object sender, System.EventArgs e)
{
btnPlay.Enabled = btnStop.Enabled = btnRewind.Enabled = false;
}
Здесь мы употребили сцепленную
Теперь нужно разблокировать кнопки после того, как будет загружен файл в проигрыватель. Для этого
Дополните
обработчик btnClick следующим кодомprivate void btnClick(object sender, System.EventArgs e)
{
Button btn = (Button) sender;// Явное приведение типов
switch(btn.Name)
{
case "btnOpen":
openFilePlayer.InitialDirectory = // Начальный каталог для фильтра
System.IO.Directory.GetCurrentDirectory();// Каталог исполнимого файла
openFilePlayer.ShowDialog();// Открываем диалог
Player.FileName = openFilePlayer.FileName;// Передаем имя файла в плеер
if(Player.FileName.Length > 0)
{
// Перебираем все дочерние элементы контейнера GroupBox
foreach(Control obj in groupBox.Controls)
{
// Выделяем полное имя типа вместе с пространствами имен
String str = obj.GetType().ToString();
// Ищем позицию последней точки
int pos = str.LastIndexOf('.');
// Выделяем имя типа без пути
str = str.Substring(pos + 1);
if(str == "Button")
obj.Enabled = true;
}
}
break;
case "btnPlay":
Player.Play();
break;
case "btnStop":
Player.Stop();
break;
case "btnRewind":
Player.CurrentPosition = 0;
break;
}
}
В добавленном коде мы проверяем, что выбранное пользователем имя файла непустое (надо было все-таки поставить обработчик исключения, поскольку пользователь может выбрать файл, не подлежащий проигрыванию. Но пока хватит и этого!).
Родительские элементы, такие как Panel, , TabControl,
сама форма Form, имеют свойство Controls,
которое является коллекцией и содержит ссылки на все помещенные
на родительский элемент дочерние компоненты - наследники
класса Control.
Мы перебираем в цикле foreach ( -для
каждого ) все элементы коллекции ,
находим среди них кнопки и устанавливаем их доступными.
Здесь мы наворотили лишние проверки на тот случай, если
кроме кнопок в контейнере окажутся
и элементы других типов, хотя на данном этапе кроме кнопок
мы туда ничего не помещали.
Запустите
проект и убедитесь, что все добавленные нами возможности
управления работают правильно.Усовершенствуем схему управления медиаплеером. Задействуем
возможности управления звуком и контроля позиции проигрывающей
головки. Для этого нам понадобятся такие элементы управления
вкладки All , как TrackBar ( ползунок ), ( флажок ), ProgressBar ( индикатор
процесса, индикатор прогресса ), TextBox ( текстовое
поле ).
Сместите
кнопку btnRewind влево на один уровень
с кнопкой btnOpen и поместите на освободившееся
справа место элемент CheckBox (один
щелчок на CheckBox , затем щелчок внутри
контейнера groupBox ). Этот элемент даст
возможность пользователю отключать или включать звук при
воспроизведении файла
Правее
элемента CheckBox разместите в контейнере groupBox текстовое
поле TextBox,
которое мы будем использовать для отображения численного
значения величины звука
Ниже
разместите в контейнере groupBox элемент TrackBar для
плавного регулирования звукаТеперь нужно настроить эти элементы управления. Начнем с
элемента . Этот элемент мы будем
использовать для отключения звука плеера. Настройте его свойства
так
| Свойство | Значение |
|---|---|
Name |
checkVolume |
CheckAlign |
MiddleLeft |
Image |
VOLUME01.ICO (возьмите из данной работы в каталоге
Source. Используйте кнопку Import для
радиокнопки Local ) |
ImageAlign |
BottomRight |
Checked |
True |
Text |
ПУСТО |
Давайте сразу запрограммируем этот элемент. При каждом щелчке
на элементе изменяется его булево
свойство Checked (и CheckState ).
Создайте
в панели Properties обработчик события CheckedChanged элемента checkVolume и
добавьте в него следующий кодprivate void checkVolume_CheckedChanged(object sender, System.EventArgs e)
{
// Это наше извращение, можно сразу обращаться к checkVolume
CheckBox check = (CheckBox) sender;
// В каком состоянии оказался CheckBox
if(check.CheckState == CheckState.Checked)
{
Player.Mute = false;
}
else
{
Player.Mute = true;
}
}
Для плавного изменения звука мы воспользуемся элементом TrackBar.
Свойства и методы элемента TrackBar аналогичны
ScrollBar. Некоторые из
них перечислены в таблице. Причем не все свойства элемента TrackBar доступны
в режиме проектирования, зато все доступны в программном
режиме на этапе выполнения.
| Свойство | Пояснения |
|---|---|
Value |
Главная регулируемая величина, определяющая текущее
состояние головки бегунка. По умолчанию начальное значение
равно значению свойства |
SmallChange |
Минимальная дискретность изменения величины Value при
управлении стрелками или перемещением головки бегунка
с |
LargeChange |
Максимальная дискретность изменения величины Value
при нажатии клавиш PageUp или PageDown, или щелчках мышью
на |
|
Нижний предел значения Value. По умолчанию 0 |
|
Верхний предел значения Value. По умолчанию 10 |
TickFrequency |
Свойство |
TickStyle |
Определяет форму ползунка при отображении пользователю |
Настройте
свойства элемента TrackBar так| Свойство | Значение |
|---|---|
Name |
trackVolume |
Location |
8; 104 |
Size |
272; 53 |
|
0 |
|
50 |
|
|
LargeChange |
5 |
SmallChange |
1 |
TickFrequency |
5 |
TickStyle |
BottomRight |
Присвойте
элементу TextBox имя txtVolume Элемент txtVolume будет только
отображать числовое значение плеера,
поэтому запретим его редактирование пользователем.
Выделите
элемент txtVolume и создайте через панель Properties для
его события KeyPress обработчик,
который заполните такprivate void txtVolume_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
// Запрещаем редактировать поле, кроме клавиши Del
// и горизонтальных стрелок - они встроены в элемент
e.Handled = true;
}
Свойство сообщает элементу, что
все уже обработано и нужно успокоиться и ничего не делать.
Элемент TrackBar имеет
событие , которое происходит каждый
раз, когда изменяется положение головки бегунка. Воспользуемся
этим, чтобы менять численное значение величины плеера.
Создайте
для события Scroll элемента TrackBar обработчик,
который заполните такprivate const int maxVolume = 0;
private const int minVolume = -5000;
private void trackVolume_Scroll(object sender, System.EventArgs e)
{
TrackBar track = (TrackBar) sender;
float minValue = track.Minimum;
float maxValue = track.Maximum;
float value = track.Value;
// Формула линейного изменения свойства Player.Volume
// (самая простая, хотя можно вставить и нелинейный закон)
Player.Volume = minVolume -
(int) ( (value - minValue) /(maxValue - minValue)
* minVolume );
txtVolume.Text = Convert.ToString(Player.Volume);
}
Теперь нужно установить начальные значения текстового поля и положения бегунка при первой загрузке формы
Добавьте
в обработчик события Load формы, который
мы уже создали раньше, следующий кодprivate void MediaPlayer_Load(object sender, System.EventArgs e)
{
btnPlay.Enabled = btnStop.Enabled = btnRewind.Enabled = false;
txtVolume.Text = Convert.ToString(Player.Volume);// Отображаем величину звука
trackVolume.Value = // Устанавливаем бегунок
// Поскольку работаем с целыми, которые округляются,
// то вначале умножаем, потом делим
trackVolume.Minimum + (minVolume - Player.Volume)
* (trackVolume.Maximum - trackVolume.Minimum)
/ minVolume;
}
Чтобы не давать пользователю возможности оперировать элементом TrackBar при
выключенном звуке, будем блокировать этот элемент, когда
звук отключен.
Добавьте
в обработчик checkVolume_CheckedChanged() следующий
код блокирования ползункаprivate void checkVolume_CheckedChanged(object sender, System.EventArgs e)
{
// Это наше извращение, можно сразу обращаться к checkVolume
CheckBox check = (CheckBox) sender;
// В каком состоянии оказался CheckBox
if(check.CheckState == CheckState.Checked)
{
Player.Mute = false;
trackVolume.Enabled = true;
}
else
{
Player.Mute = true;
trackVolume.Enabled = false;
}
}
Теперь мы хотим сделать так, чтобы пользователь мог видеть
по нашему интерфейсу, какая часть файла уже воспроизведена.
Для этого используем ProgressBar.
Есть еще альтернативный вариант - COM-Microsoft
ProgressBar Control 6.0 (SP4).
Этот
Откройте вкладку панели "Моя
вкладка", которую мы создали ранее, щелкните
на ней правой кнопкой мыши и выполните команду Coose Items. Установите в появившемся окне
вкладку COM , найдите
нужный элемент Microsoft ProgressBar Control 6.0 (SP4),
отметьте его и нажмите кнопку OK.
Теперь этот компонент можно помещать на форму обычным
образом.
Некоторые свойства:
Scrolling - гладкий или
прерывистый вид полосыMin , Max - пределы изменения
полосыValue - текущее значениеOrientation - горизонтальное
или вертикальное расположение полосыAppearance , BorderStyle
- внешний вид полосы
Поместите
компонент ProgressBar в
контейнер groupBox (щелчком там и там)
и настройте через панель Properties его
свойства так| Свойство | Значение |
|---|---|
Name |
progressBar |
Location |
16; 160 |
Size |
256; 8 |
Здесь мы установили только интерфейсные свойства элемента, а существенные свойства по управлению элементом будем задавать программно.
Выровняйте
интерфейсные элементы с применением панели инструментов Layout оболочки,
чтобы панель имела на данном этапе примерно такой вид
Выделите
элемент Player и на панели Properties в
режиме Events найдите событие ReadyStateChange.
Создайте двойным щелчком на поле значений этого события
обработчик Player_ReadyStateChange(),
который заполните такprivate void Player_ReadyStateChange(object sender, AxMediaPlayer._MediaPlayerEvents_ReadyStateChangeEvent e)
{
progressBar.Minimum = 0;
int maximum = progressBar.Maximum = (int)Player.Duration;
}
Этот обработчик будет срабатывать каждый раз при загрузке
нового файла и устанавливать новые значения свойств диапазона
Вновь
выделите элемент Player и на панели Properties в
режиме Events найдите событие PositionChange.
Создайте двойным щелчком на поле значений этого события
обработчик Player_PositionChange(), который
заполните такprivate void Player_PositionChange(object sender, AxMediaPlayer._MediaPlayerEvents_PositionChangeEvent e)
{
progressBar.Value = (int)Player.CurrentPosition;
}
Если теперь запустить форму на выполнение, то можно заметить,
что
Добавьте
двойным щелчком во вкладке All Windows Forms на
компоненте Timer timer
Создайте
для его единственного события Tick обработчик,
в котором продублируйте код обработчика Player_PositionChange(),
обновляющий позицию элемента progressBarprivate void timer_Tick(object sender, System.EventArgs e)
{
progressBar.Value = (int)Player.CurrentPosition;
// progressBar.PerformStep();// Для альтернативного способа
}
Дополните
обработчик Player_ReadyStateChange() события
загруки медиафайла кодом настройки и запуска таймераprivate int countSteps;
private void Player_ReadyStateChange(object sender, AxMediaPlayer._MediaPlayerEvents_ReadyStateChangeEvent e)
{
countSteps = 50; // Количество шагов индикатора прогресса
progressBar.Minimum = 0;
progressBar.Maximum = (int)Player.Duration;
timer.Interval = (progressBar.Maximum - progressBar.Minimum)
* 1000 // Переводим секунды в миллисекунды
/ countSteps; // Операция деления на последнем месте
timer.Start();
progressBar.Value = progressBar.Minimum;
/* // Для альтернативного способа
progressBar.Step = (progressBar.Maximum - progressBar.Minimum)
/ countSteps;
*/
}
Красным цветом выделен альтернативный код управления интикатором.
Но если вы его будете использовать, то нужно позаботиться
об остановке таймера при каждой остановке проигрывания и
о его запуске при продолжении проигравания. Если этого не
сделать, то при остановке проигрывания
Выделите
форму через ее заголовок и установите два свойства в следующие
значенияFormBorderStyle=FixedSingleMaximizeBox=FalseТеперь осталось подключить эту форму к основному окну приложения и сделать необходимые настройки.
Создайте
обработчик события FormClosed формы MediaPlayer,
как мы это делали в предыдущих случаях данной работы для
предотвращения повторного запуска, и заполните его такprivate void MediaPlayer_FormClosed(object sender, System.EventArgs e)
{
Restart.Remove(this.ToString());
}
Измените
заголовок формы, задав ее свойству Text значение " Упражнение
№3 - MediaPlayer "
Через
панель Solution Explorer откройте файл Start.cs в
режиме кода и добавьте к обработчику generalList_SelectedIndexChanged() следующий
кодprivate void generalList_SelectedIndexChanged(object sender, System.EventArgs e)
{
switch(generalList.SelectedIndex + 1)
{
.................................................
case 3:
MediaPlayer frm3 = new MediaPlayer();
if(!Restart.IsPresent(frm3))
{
Restart.Add(frm3);
frm3.Show();
}
break;
}
}
Через
панель Solution Explorer откройте файл Start.cs в
режиме дизайна двойным щелчком на пиктограмме. Выделите
через панель Properties список generalList и
добавьте в его свойство Items следующую
строку3) Собственный Windows
Media
Командой
меню оболочки Project/WinFormsApp Properties выберите
вкладку Application
и верните свойство Startup Object в значение WinFormsApp.Program
Запустите
приложение, загрузите медиафайл, испытайте элементы управления
и полюбуйтесь на свою работу. Просмотрите мультик, прилагаемый
к работе
Файлы к лабораторной работе Вы можете скачать здесь.
В данной лабораторной работе мы рассмотрим некоторые возможности
интегрированной среды ) Visual Studio.NET 2005. Мы будем
использовать разработанный Microsoft самый красивый
и современный язык программирования C# (.NET Framework ( -
Framework BCL -
Выполните
команду File/New/Project оболочки для создания нового проекта
В
диалоговом окне New Project выберите кнопкой Browse папку
для размещения проекта, задайте тип, шаблон и имя проекта WinFormsApp
После щелчка на кнопке OK мастер создаст
заготовку приложения и выведет в режиме дизайна пустую форму,
которая при запуске приложения будет представлять окно. Стандартный
размер сгенерированной формы равен 300x300.
Сделаем эту форму стартовой и разместим на ней элементы управления
для вызова дочерних форм, реализующих отдельные упражнения
данной работы.
Откройте
панель Solution Explorer оболочки и переименуйте файл Form1.cs в файл Start.cs
Щелкните
на форме правой кнопкой мыши и выполните команду контекстного
меню View Em, чтобы вызвать представление файла Start.cs в режиме 
В
режиме кода вызовите комбинацией клавиш Ctrl-F
окно Find and Replace для замены всех
вхождений Form1 на Start.
После заполнения полей поиска и замены щелкните на кнопке Replace All
В
раскрывающемся списке Members выделите функцию InitializeComponent(),
чтобы быстро позиционироваться в соответствующее место
кода
Отредактируйте
в функции InitializeComponent() код
установки заголовка окна в режиме выполненияprivate void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Text = "Lab38 - Снетков";
}
Теперь давайте добавим к главной форме Start код
поддержки пароля при запуске приложения. Для этого нам потребуется
диалоговое окно с текстовым полем. Сконструируем его. Создание
диалогового окна будет состоять из трех шагов:
InputPassword )
В
панели Solution Explorer выделите корневой
узел проекта и командой Add/Windows Form добавьте
в проект файл формы с именем InputPassword.cs
Удалите
из узла References лишние добавленные
мастером ссылки на библиотечные сборки System.Data и System.Xml
Откройте
файл InputPassword.cs в режиме View
Code и удалите инструкции using подключения
пространств имен System.Data и System.Xml
Настройте
форму InputPassword в соответствии с таблицей| Свойство | Значение | Пояснения |
|---|---|---|
StartPosition |
CenterScreen |
Открывать в центре экрана |
FormBorderStyle |
FixedDialog |
Запретить пользователю менять размер |
MaximizeBox |
false |
Отключить системную кнопку |
MinimizeBox |
falseStandardDialogs |
Отключить системную кнопку свертывания |
ShowInTaskbar |
false |
Запретить появление в панели задач |
|
true |
Подстраиваться под содержимое |
AutoSizeMode |
GrowAndShrink |
Подстраиваться под содержимое (расширяться и сжиматься) |
Text |
Пусто |
Заголовок окна |
Из
свитка Containers панели инструментов Toolbox поместите
на форму компоновочную панель FlowLayoutPanel и
настройти ее в соответствии с таблицей| Свойство | Значение | Пояснения |
|---|---|---|
Name |
|
Имя компоновочной панели |
|
true |
Подстраиваться под содержимое |
FlowDirection |
TopDown |
Размещать сверху вниз |
WrapContents |
false |
Не переносить дочерние элементы в следующий столбец |
|
8 |
|
|
|
Распахнуть на всю клиентскую область родителя (формы) |
Эта панель будет автоматически следить за размещением своих дочерних элементов в соответствии с настройками.
Выделите
на форме компоновочную панель flow , чтобы
именно она принимала дочерние элементы, поместите в нее
из свитка Common Controls текстовую метку Label и
настройте ее свойства в соответствии с таблицей| Свойство | Значение | Пояснения |
|---|---|---|
Name |
lblMessage |
Имя текстовой метки |
|
true |
Подстраиваться под содержимое |
|
None |
Расположить посредине |
|
8 |
Отступ по наружному периметру текстовой метки |
Аналогичным
образом поместите в панель flow последовательно
экземпляры компонентов TextBox и Button,
которые настройте так| Свойство | Значение | Пояснения |
|---|---|---|
Name |
txtInput |
Имя текстовой метки |
|
None |
Расположить посредине |
|
8 |
Отступ по наружному периметру текстовой метки |
PasswordChar |
* |
Эхо ввода в текстовом поле |
| Свойство | Значение | Пояснения |
|---|---|---|
Name |
btnOk |
Имя кнопки |
|
true |
Подстраиваться под содержимое |
|
None |
Расположить посредине |
|
8 |
Отступ по наружному периметру кнопки |
Text |
OK |
Надпись |
DialogResult |
OK |
Назначить статус "кнопки OK" в родительской форме |
Свойству дочерних кнопок формы DialogResult можно
присвоить любое значение из перечисления System.Windows.Forms.DialogResult ( , , , No, None, OK, , 25_73 ).
Оно и будет возвращено функцией ShowDialog() формы,
если пользователь выберет именно эту кнопку. Если свойству DialogResult кнопки
будет присвоен статус, отличный от None,
то при щелчке пользователя на такой кнопке форма будет автоматически
закрываться.
Подтяните
низ формы до приемлемого размера, чтобы она стала выглядеть
примерно так
Откройте
файл InputPassword.cs в режиме View
Designer, щелкните на заголовке формы и выполните
команду Format/Lock Controls, чтобы защитить
интерфейс формы от случайных изменений. Это групповая команда,
которая устанавливает свойство Locked всех
дочерних визуальных элементов и самой формы в значение True.
То же самое можно сделать индивидуально для каждого элемента
через меню PropertiesМы создали сам пользовательский интерфейс класса InputPassword диалогового
окна. Теперь нужно настроить класс InputPassword,
добавив туда метод создания диалогового окна и вызова его
на экран.
Модифицируйте
класс InputPassword следующим образомusing System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace WinFormsApp
{
public partial class InputPassword : Form
{
public InputPassword()
{
InitializeComponent();
}
public InputPassword(string windowTitle, string message)
{
InitializeComponent();
this.Text = windowTitle;
lblMessage.Text = message;
}
public static string Show(string windowTitle, string message)
{
using(InputPassword inputDlg =
new InputPassword(windowTitle, message))
{
inputDlg.ShowDialog();
return inputDlg.txtInput.Text;
}
}
}
}
Мы создали параметризованный конструктор для ввода заголовков
диалогового окна в момент его создания. Мы добавили статический
метод создания диалогового окна, который возвращает значение
текстового поля после щелчка пользователем на кнопке, и такой
метод нужно вызывать по имени класса. Упаковка создания экземпляра
формы в блок using позволяет вызвать сборщик
мусора сразу после выхода из этого блока.
Теперь нужно поместить вызов окна запроса пароля в обработчик
события Load запуска формы.
Откройте
файл Start.cs в режиме View Designer,
выделите форму через ее заголовок, перейдите в панель Properties,
установите ее в режим Events , найдите
событие Load и создайте для него обработчик Start_Load().
Заполните обработчик события такprivate void Start_Load(object sender, System.EventArgs e)
{
string password = InputPassword.Show(
"Окно аутентификации пользователя",
"Просим ввести Ваш пароль:");
if (password != "root")// Плохой способ хранения пароля
{
MessageBox.Show(
"Извините, но Вам не разрешено\n" // Сообщение
+ "пользоваться этой суперпрограммой!!!",
"Неверный пароль", // Заголовок окна
MessageBoxButtons.OK, // Кнопка OK
MessageBoxIcon.Stop);// Критическая иконка
this.Close();
}
}
Запустите
приложение, диалоговое окно ввода пароля должно
выглядеть так
При неправильном пароле появляется простое диалоговое окно сообщений

и приложение завершит свою работу.
На стартовой форме мы создадим список с наименованиями упражнений, который будем пополнять по мере их выполнения. В окончательном варианте работы щелчок по пункту списка должен запускать дочернюю форму, соответствующую выполненному упражнению. Это удобно при демонстрации выполненной лабораторной работы.
Перейдите
в режим Design, откройте в панели Toolbox вкладку Common
Controls и
двойным щелчком на компоненте ListBox создайте
на форме его экземпляр
Выделите
объект listBox1 и в панели Properties установите
для него следующие значения свойств| Свойство | Значение |
|---|---|
Name |
generalList |
|
|
Items |
1) Простое диалоговое окно со смайликами |
Щелкните
на заголовке формы и увеличьте ее ширину за маркеры так,
чтобы поместилось все предложение в списке ListBox.
Через
раскрывающийся список вверху панели Properties выделите
объект generalList и установите для нее
режим Events
Найдите
событие SelectedIndexChanged и двойным
щелчком на его поле
значений создайте обработчик generalList_SelectedIndexChanged()Теперь мы будем добавлять к приложению новые формы для выполнения каждого нового упражнения, регистрировать их в списке и помещать вызовы упражнений в этот обработчик главной формы.
Выполните
команду Project/Add Windows Form, чтобы
добавить к проекту новую форму
Задайте
имя новой форме Smiles.cs (Улыбки)
Поместите
на форму три компонента PictureBox из
вкладки Common Controls панели Toolbox ,
текстовую метку Label и
одну кнопку Button.
Все расположите так, как показано на снимке экрана (установите
свойство label1.AutoSize
=false )
Для
выравнивания компонентов пользуйтесь командами меню
оболочки, входящими в категорию Format,
или одноименными кнопками панели инструментов
Выполните
команду меню Format/Lock Controls, чтобы
закрепить расположение интерфейсных элементов на форме
и, тем самым, защитить их от случайного сдвига или изменения
размеров. Обратите внимание, что теперь на выделенных
элементах маркеры сменились гладкой рамкой с пиктограммой
замкаТеперь давайте установим для помещенных на форму объектов
нужные свойства через панель Properties.
При этом важно понимать, что все визуальные манипуляции с
формой и помещенными на нее компонентами, в том числе и установка
свойств через панель Properties, - это ничто иное, как удобный
и наглядный способ генерации кода с помощью графических средств
оболочки. Наша работа в режиме дизайна сопровождается параллельной
работой оболочки в режиме кода. И все, что можно сделать
через
Графические возможности являются бесспорным
помощником только при разработке пользовательского интерфейса
окон. Но дальнейшая работа
требует от программиста широких профессиональных знаний не
только принципов программирования и тонкого знания языка
- как основного инструмента, но и знания
Интерфейс пользователя является только посредником. Но и его значения умалять нельзя. Вычурный, непонятный, крикливый интерфейс может сослужить плохую службу действительно толковой программе. Нужно стремиться к простому и понятному интерфейсу, по-возможности вписывающемуся в уже сложившиеся представления о принципах программного взаимодействия с пользователем.
Задайте
свойства размещенных на форме объектов через панель Properties в порядке их следования слева-направо,
сверху-вниз, как указано в таблице| Класс | Свойство | Значение | Пояснения |
|---|---|---|---|
Form |
Text |
Smiles - Упражнение №1 | Заголовок окна |
FormBorderStyle |
FixedDialog | Запретили изменение размера окна формы | |
MaximizeBox |
False | Отключили системную кнопку |
|
MinimizeBox |
False | Запретили системную кнопку свертывания окна | |
PictureBox |
Name |
picSmile | |
Image |
FACE02.ICO (возьмите из данной работы в каталоге Source.
Используйте кнопку Import для радиокнопки Local
) |
Файл рисунка | |
SizeMode |
StretchImage | Опция - растянуть рисунок по размерам объекта | |
PictureBox |
Name |
picFrown | |
|
Image |
FACE04.ICO (возьмите
из данной работы в каталоге Source. Используйте кнопку Import для
радиокнопки Local ) |
Файл рисунка |
SizeMode |
StretchImage | Опция - растянуть рисунок по размерам объекта | |
PictureBox |
Name |
picHappy | |
Image |
FACE03.ICO (возьмите
из данной работы в каталоге Source. Используйте кнопку Import для
радиокнопки Local ) |
Файл рисунка | |
SizeMode |
StretchImage | Опция - растянуть рисунок по размерам объекта | |
Label |
Name |
lblMessage | |
Text |
Щелкайте на смайликах | Начальное содержимое текстовой метки | |
Font/Name |
Arial | Наименование шрифта | |
Font/Size |
14 | ||
Font/ |
True | Полужирный | |
ForeColor |
Red | Цвет переднего плана (красный) | |
TextAlign |
MiddleCenter | Выравнивание текста - середина по вертикали, центр по горизонтали | |
|
Fixed3D | Объемный вид элемента | |
Button |
Name |
btnExit | |
Text |
Выход | Надпись на кнопке |
|
|
true | Подстраиваться под размер надписи |
После всех настроек внешний вид формы должен быть примерно таким

Разработку интерфейса первой дочерней формы на этом можно считать завершенной. Теперь пришла пора обеспечить ее функциональность.
Выделите
первый смайлик picSmile и
через панель Properties (в режиме Events )
создайте обработчик события Click
Заполните
обработчик следующим кодомprivate void picSmile_Click(object sender, System.EventArgs e)
{
picSmile.BorderStyle = BorderStyle.FixedSingle; // Рамка
picFrown.BorderStyle = BorderStyle.None; // Нет рамки
picHappy.BorderStyle = BorderStyle.None; // Нет рамки
lblMessage.Text = "Щелкнули на первом рисунке";
}
Двойным
щелчком на втором рисунке ( picFrown ) создайте
для него обработчик, который заполните такprivate void picFrown_Click(object sender, System.EventArgs e)
{
picSmile.BorderStyle = BorderStyle.None; // Нет рамки
picFrown.BorderStyle = BorderStyle.FixedSingle; // Рамка
picHappy.BorderStyle = BorderStyle.None; // Нет рамки
lblMessage.Text = "Щелкнули на втором рисунке";
}
Двойным
щелчком на третьем рисунке ( picHappy )
создайте для него обработчик, который заполните такprivate void picHappy_Click(object sender, System.EventArgs e)
{
picSmile.BorderStyle = BorderStyle.None; // Нет рамки
picFrown.BorderStyle = BorderStyle.None; // Нет рамки
picHappy.BorderStyle = BorderStyle.FixedSingle; // Рамка
lblMessage.Text = "Щелкнули на третьем рисунке";
}
Двойным
щелчком на кнопке btnExit создайте
для нее обработчик, который заполните такprivate void btnExit_Click(object sender, System.EventArgs e)
{
this.Close(); // Закрыть форму
}
Теперь подключим вызов этой дочерней формы к движку приложения, обеспечив возможность ее вызова по щелчку на соответствующей строке списка с упражнениями.
Сохраните
проект командой меню File/Save All и закройте
все окна редактирования командой Window/Close All
Documents.
В
панели Solution Explorer щелкните правой
кнопкой мыши на файле Start.cs и
выполните команду контекстного меню View
Designer (или откройте файл в режиме дизайна двойным
щелчком левой кнопки мыши).
Выделите
элемент списка generalList и через панель Properties щелкните два раза на имени
уже созданного обработчика в поле события SelectedIndexChanged,
чтобы быстро позиционироваться к заголовку кода обработчика.
Заполните обработчик следующим кодомprivate void generalList_SelectedIndexChanged(object sender, System.EventArgs e)
{
switch(generalList.SelectedIndex + 1)
{
case 1:
Smiles frm1 = new Smiles();
frm1.ShowDialog();
break;
}
}
Здесь мы применили метод ShowDialog() класса Form (вместо
метода Show() ). Это позволит нам открывать
дочерние формы в модальном режиме
(пока не закроется очередная форма, другие окна приложения
не получат фокус ввода).
Выделите
в режиме дизайна форму Start (щелкните
на заголовке окна формы) и установите через панель Properties ee
свойство StartPosition в
значение CenterScreen,
чтобы при первом запуске она появлялась в центре экрана
Откройте
в режиме дизайна (в панели Solution Explorer ) форму Smiles,
выделите ее через заголовок окна формы и установите свойство StartPosition в значение Manual . Проследите, чтобы свойство Location (размещение) имело значение ( 0,
0 ). Тем самым
мы задали позицию появления дочерней формы в верхнем левом
углу экрана.Два последних действия позволят нам держать форму движка в центре экрана, а дочерние формы задвинуть в начало экрана (удобно для демонстрации упражнений, полезно для тренировки).
Запустите
приложение и проверьте его работоспособностьНа этапе построения формы бывает полезным сразу запускать
ее для проверки. В нашем случае форма Smiles может
быть вызвана только из главной формы. Исправим это.
Добавьте
в конец класса Smiles следующую функцию-член Main(),
которая позволит отображать форму первой при запуске приложенияpublic class Smiles : System.Windows.Forms.Form
{
..............................................................
private void btnExit_Click(object sender, System.EventArgs e)
{
this.Close(); // Закрыть форму
}
static void Main()
{
Application.Run(new Smiles());
}
}
Установите
в качестве стартовой форму Smiles. Для этого выполните
команду меню оболочки Project/WinFormsApp Properties и
в появившемся диалоговом окне установите свойство Startup
Object в значение WinFormsApp.Smiles
Запустите
приложение и убедитесь, что теперь дочерняя форма Smiles стартует
первой и единственной.Вкладка All Windows Forms панели Toolbox содержит
все компоненты, которые необходимы для быстрой
разработки интерфейса пользователя. Она становится доступной,
когда форма открыта в режиме Design и текущее
приложение не запущено. Режим Design и компоненты
панели - это
лишь инструменты для частичной C# приложения в файле *.cs.
Все компоненты поддерживаются соответствующими классами и
доступны для управления ими программным путем.
В таблице приведено краткое описание части компонентов, а в упражнениях этой работы мы продемонстрируем возможности некоторых из них.
| Компонент | Назначение |
|---|---|
![]() |
Установка курсора в режим выделения объектов. |
![]() Button |
Инструмент для генерирования события щелчка, по которому вызывается функция - обработчик. В эту функцию можно разместить любой код, который требуется выполнить при щелчке на этом инструменте. |
![]() |
Дает возможность пользователю установить нужный режим
из двух возможных. При обединении этих элементов в тематическую
|
![]() CheckedListBox |
Множество элементов |
![]() ColorDialog |
Стандартное диалоговое окно для предоставления пользователю возможности выбирать цвета |
![]() ComboBox |
Раскрывающийся список. Состоит из верхней части с редактируемым текстовым полем, и нижней части со списком для выбора готовых элементов. |
![]() ContextMenuStrip |
Контекстные меню обычно вызываются щелчком правой кнопкой мыши на нужном элементе управления формы. Туда обычно включают часто используемые команды из основного меню приложения. Это обеспечивает быстрый доступ пользователя к таким командам. |
![]() DataGridView |
Этот элемент отображает данные в виде таблицы, состоящей
из строк и столбцов. В простейшем случае этот элемент
просто отображает все данные связанной с ним одной таблицы
базы данных без всяких условий и позволяет оперировать
с ними как в обычной электронной таблице. В более сложном
случае элемент отображает |
![]() DateTimePicker |
Этот элемент дает возможность пользователю быстро выбирать нужные дату из предоставляемого удобного интерфейса в виде календаря. |
![]() DomainUpDown |
Представляет собой текстовое поле со стрелками для изменения значений списка вверх или вниз. |
![]() ErrorProvider |
Этот элемент управления (невизуальный компонент) применяется для проверки правильности пользовательского ввода в допустимых пределах данных. Он предоставляет разработчику удобный интерфейс для оповещения пользователя о допущенных нарушениях и является лучшей заменой простому окну сообщений. |
![]() FolderBrowserDialog |
Представляет собой диалоговое окно для навигации по папкам файловой системы компьютера. |
![]() FontDialog |
Является стандартным диалоговоым окном, с помощью которого можно выбирать шрифты, установленные в настоящее время на текущем компьютере. |
![]() |
Применяется для |
![]() HelpProvider |
Используется для |
![]() HScrollBar |
Самостоятельный элемент управления, который присоединяется к другим элементам интерфейса для продвижения по большим массивам информации в горизонтальном направлении. |
![]() ImageList |
Используется для хранения последовательности рисунков, подлежащих отображению приложением. Рисунки можно выбирать с помощью индексов списка и отображать на экране другими элементами управления. |
![]() Label |
Простая текстовая метка для отображения нередактируемого текста на экране компьютера. |
![]() LinkLabel |
Позволяет использовать текстовую метку в стиле гиперссылки. С помощью этого элемента часть текста можно связать с файлом, каталогом или Web-страницей. |
![]() ListBox |
Отображает список элементов, из которых пользователь
может выбрать один или несколько элементов. Если количество
элементов в вписке превышает то, что может быть отображено,
то автоматически добавляется вертикальная MultiColumn в значение true добавляется
горизонтальная true свойство ScrollAlwaysVisible, то SelectionMode устанавливает,
сколько элементов списка может быть выделено одновременно.
Свойство SelectedIndex возвращает индекс
первого выделенного элемента в списке, начиная с нуля.
Если нет выделенных элементов, свойство возвращает значение
-1. |
![]() ListView |
Отображает список элементов с иконками, наподобие правой
области Windows Explorer. Элемент имеет четыре
режима отображения: LargeIcon, SmallIcon, List, и . |
![]() MenuStrip |
Создает главное меню формы, за пунктами которого можно закреплять различные команды управления приложением. |
![]() MonthCalendar |
Обеспечивает привычный интерфейс работы с датой в виде календаря. |
![]() NotifyIcon |
Используется для отображения в виде значков процессов,
которые выполняются в фоновом режиме и долгое время не
видны пользователю. Примером может служить программа
|
![]() NumericUpDown |
Представляет собой комбинацию текстового поля и пары стрелок, которые пользователь может применять для наглядного управления целым числовым значением. |
![]() OpenFileDialog |
Представляет стандартное диалоговое окно |
![]() PageSetupDialog |
Предоставляет стандартное диалоговое окно настройки страницы документа при печати. |
![]() Panel |
Элемент Panel подобен элементу .
Применяется для |
![]() PictureBox |
Элемент служит для отображения рисунков в формате
Image.
Свойство SizeMode устанавливает режим согласования
размеров элемента и рисунка. Рисунок отображается как в режиме
разработки, так и во время выполнения приложения. |
![]() PrintDialog |
Это стандартное диалоговое окно используется для настроек принтера перед печатью. |
![]() PrintDocument |
Устанавливает, что печатать и как печатать.
Может использоваться совместно с элементом PrintDialog для
полного описания всех аспектов печати. |
![]() PrintPreviewControl |
Позволяет предварительно просмотреть документ перед печатью, как он будет выглядеть после печати. |
![]() PrintPreviewDialog |
Позволяет предварительно просмотреть документ перед печатью, как он будет выглядеть после печати. Отображает стандартное диалоговое окно с необходимыми элементами управления. |
![]() ProgressBar |
Индикаторная линейка - отображает продвижение процесса в горизонтальном направлении. |
![]() RadioButton |
Радиокнопка (переключатель) |
![]() RichTextBox |
Представляет собой полноценный текстовый редактор. |
![]() SaveFileDialog |
Обеспечивает стандартный настраиваемый диалог сохранения файлов. |
![]() |
Используется для изменения |
![]() StatusBar |
Элемент создает строку состояния. |
![]() TabControl |
Элемент для создания вкладок. Создает одну или несколько вкладок, на каждой из которых могут быть размещены другие объекты. |
![]() TextBox |
Редактируемое текстовое поле. |
![]() |
|
![]() ToolStrip |
Панель инструментов - контейнер для кнопок быстрого доступа. |
![]() |
Для создания всплывающих коротких подсказок, которые появляются при наведении курсора на элемент управления. |
![]() TrackBar |
Регулятор для визуального изменения числовой информации
(иногда называют |
![]() |
Отображает информацию в древовидном формате. |
![]() VScrollBar |
Самостоятельный элемент управления, который присоединяется к другим элементам интерфейса для продвижения по большим массивам информации в вертикальном направлении. |
Toolbox и
выполнив команду контекстного меню Add
Tab.
Удалить вкладку можно, щелкнув правой кнопкой мыши на
заголовке соответствующей вкладки и выполнив команду Delete Tab.
Копировать нужные компоненты из одной вкладки в другую
можно выполнением команд контекстного меню Copy и Paste.Разработаем калькулятор, выполняющий простые действия над
целыми и
Добавьте
к проекту новую форму командой Project/Add Windows
Form и задайте ей имя Calculate 
Поместите
на форму элементы из вкладки Common Controls панели Toolbox в
соответствии с таблицей, чтобы пользовательский интерфейс
формы был таким
| Элемент | Свойство | Значение |
|---|---|---|
Form |
Name |
|
StartPosition |
|
|
Location |
0; 0 |
|
Text |
Простой калькулятор |
|
|
Выбрать по усмотрению...(можно из Source) |
|
FormBorderStyle |
FixedDialog |
|
Label |
Name |
lblFirst |
Text |
Первое число: |
|
TextAlign |
MiddleRight |
|
Label |
Name |
lblSecond |
Text |
Второе число: |
|
TextAlign |
MiddleRight |
|
Label |
Name |
lblResult |
Text |
Результат: |
|
TextAlign |
MiddleRight |
|
TextBox |
Name |
txtFirst |
Text |
пусто |
|
TextBox |
Name |
txtSecond |
Text |
пусто |
|
TextBox |
Name |
txtResult |
Text |
пусто |
|
|
True |
|
TabStop |
False |
|
Button |
Name |
btnIncrement |
Text |
+ |
|
Font/ |
True |
|
Font/Size |
20 |
|
Size |
40; 40 |
|
Button |
Name |
btnDecrement |
Text |
- |
|
Font/Name |
Courier New |
|
| Font/ |
True |
|
Font/Size |
20 |
|
Size |
40; 40 |
|
Button |
Name |
btnIncrease |
Text |
* |
|
Font/Name |
Courier New |
|
Font/ |
True |
|
Font/Size |
20 |
|
Size |
40; 40 |
|
Button |
Name |
btnDivide |
Text |
: | |
Font/Name |
Courier New |
|
Font/ |
True |
|
Font/Size |
20 |
|
Size |
40; 40 |
|
Button |
Name |
btnExit |
Text |
Выход |
Здесь мы использовали
некоторые префиксы при
назначении имен элементам управления. Для лучшей узнаваемости
в
| Объект | Префикс |
|---|---|
Button |
btn |
|
chk |
ComboBox |
|
|
|
Form |
frm |
Label |
|
ListBox |
lst |
MenuStrip |
mnu |
PictureBox |
|
RadioButton |
|
TextBox |
txt |
Добавьте
к классу Calculate функцию Main() для автономной отладки
формыstatic void Main()
{
Application.Run(new Calculate());
}
Выполните
команду меню WinFormsApp Properties и
для вкладки Application установите в свойстве Startup
Object форму Calculate стартовой
Защитите
интерфейс формы Calculate от случайных
изменений, выполнив команду Format/Lock
Controls меню оболочкиТеперь нужно реализовать функциональность интерфейса. Прежде всего нужно защитить поля ввода от всех символов, кроме цифр, одного знака минус и одной точки. Стрелки и клавиша Del в текстовых полях функционируют, но работу клавиши Backspace нужно учесть явно.
Объявите
в конце класса Calculate логическое
поле isNumeric для
отфильтровывания нецифровых символов, которые пользователь
может попытаться ввести в текстовые поляprivate bool isNumber = false;
Выделите
текстовое поле txtFirst и через панель Properties в
режиме Events создайте обработчик для события KeyDown.
Заполните обработчик такprivate bool isNumber = false;
private void txtFirst_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
isNumber =
e.KeyCode >= Keys.D0 e.KeyCode <= Keys.D9 // keyboard - основная клавиатура
|| e.KeyCode >= Keys.NumPad0 e.KeyCode <= Keys.NumPad9 // keypad - дополнительная клавиатура
|| e.KeyCode == Keys.Back;
}
Выделите
текстовое поле txtFirst и через панель Properties в
режиме Events создайте обработчик для
события KeyPress . Заполните обработчик
такprivate void txtFirst_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
TextBox box = (TextBox) sender;// Явное преобразование типов
switch(e.KeyChar) // Переключатель
{
case '-': // Разрешаем минус, если он первый
if(box.Text.Length == 0)
isNumber = true;
break;
case '.':
// Точка не должна быть первой
if(box.Text.Length == 0)
break;
// Точка не должна следовать сразу за минусом
if(box.Text[0] == '-' box.Text.Length == 1)
break;
// Точка должна быть одна
if(box.Text.IndexOf('.') == -1)
isNumber = true; // Еще не было точек
break;
}
// Запрещаем в текстовом поле лишние символы
if(!isNumber)
e.Handled = true;
}
Выделите
текстовое поле txtSecond и через панель Properties в
режиме Events подключите к событиям KeyDown и KeyPress соответствующие
обработчики, только что созданные для поля txtFirst.
Обработчики подключите через раскрывающиеся списки
полей значений
Здесь мы одни и те же обработчики используем для разных
полей, поскольку необходимо выполнять одинаковые действия.
Задача одна - не допускать для ввода в поля никакие другие
символы, кроме цифр, одного минуса и одной точки.
Возможность ввода цифр реализована для основной ( )
и дополнительной ( ) частей клавиатуры. Параметр sender передает
в обработчик ссылку на активное текстовое поле, вызвавшее
событие редактирования.
Конечно, программа будет более понятна, если для каждого элемента создавать свой обработчик. Но очень часто, как в нашем случае, преобладающая часть кода может быть совершенно одинакова в каждом обработчике. Тогда имеет смысл объединять несколько индивидуальных обработчиков в один. Какой подход выбрать - зависит от конкретной задачи и предпочтений программиста.
Добавьте
в конец класса Calculate объявления числовых
переменных, с которыми мы будем производить простые арифметические
операции// Объявляем числовые переменные как поля-члены класса
// Их можно объявить как локальные и внутри обработчика btn_Click()
// Но оставляем область видимости класс, вдруг где-нибудь еще пригодятся!
private double numFirst, numSecond, numResult;
Перейдите
в режим Design формы Calculate и выделите все четыре кнопки
с операциями
Установите
в панели Properties режим Events ,
найдите событие Click и введите вручную в
поле значений этого события имя обработчика btn_Click
В
созданный оболочкой общий обработчик для всех выделенных
кнопок введите следующий код// Один обработчик для всех кнопок-операций
private void btn_Click(object sender, System.EventArgs e)
{
// Копируем текстовые поля в локальные переменные
string strFirst = string.Copy(txtFirst.Text);
string strSecond = string.Copy(txtSecond.Text);
// Замена в строке точки символом запятой
// для корректного преобразования в число
int pos = strFirst.IndexOf('.');
if(pos != -1)
{
strFirst = strFirst.Substring(0, pos)
+ ','
+ strFirst.Substring(pos + 1);
}
pos = strSecond.IndexOf('.');
if(pos != -1)
{
strSecond = strSecond.Substring(0, pos)
+ ','
+ strSecond.Substring(pos + 1);
}
// Преобразуем текст в число для выполнения операций
if(txtFirst.Text.Length > 0)
numFirst = Convert.ToDouble(strFirst);
else
numFirst = 0.0D;
if(txtSecond.Text.Length > 0)
numSecond = Convert.ToDouble(strSecond);
else
numSecond = 0.0D;
// Выполняем нужную операцию
string btnText = "";// Создали строковую переменную
bool divideFlag = false;// Флаг деления на ноль
Button btn = (Button) sender;// Явное приведение типов для распознавания кнопок
switch(btn.Name)// Переключатель
{
case "btnIncrement":// Операция сложения
btnText = "\"+\"";// Экраны кавычек
numResult = numFirst + numSecond;
break;
case "btnDecrement":// Операция вычитания
btnText = "\"-\"";// Экраны кавычек
numResult = numFirst - numSecond;
break;
case "btnIncrease":// Операция умножения
btnText = "\"*\"";// Экраны кавычек
numResult = numFirst * numSecond;
break;
case "btnDivide":// Операция деления
btnText = "\":\"";// Экраны кавычек
// Проверяем корректность деления
if (Math.Abs(numSecond) < 1.0E-30)
{
MessageBox.Show(
"Делить на ноль нельзя!", // Сообщение
"Ошибка", // Заголовок окна
MessageBoxButtons.OK, // Кнопка OK
MessageBoxIcon.Stop);// Критическая иконка
divideFlag = true;
}
else
numResult = numFirst / numSecond;
break;
}
// Для отображения в панели Output режима Debug
System.Diagnostics.Debug.WriteLine("Нажата кнопка " + btnText);// Конкатенация
// Отображение результата
if(!divideFlag)
{
txtResult.Text = Convert.ToString(numResult);
this.Validate(); // Обновить экран (можно убрать-излишне)
}
}
Здесь мы прежде всего скопировали значения полей ввода в
промежуточные текстовые переменные, используя статический
метод System.String. Copy() класса String (string ).
Затем мы проверяем наличие символа "точки" в этих
переменных и при обнаружении производим замену на символ "запятая" с
полным формированием новой строки. Мы не можем заменить символ
"на месте" в существующей строке, обратившись к
нему как элементу массива, поскольку индексная форма
Но мы можем, сформировав новую строку справа от знака присваивания, присвоить результат вновь той же самой ссылке, которая фактически будет адресоваться к новой области памяти, а старая строка, как брошенный фрагмент памяти, будет оставлена для сборщика мусора. Операция замены точки на запятую выполняется для того, чтобы корректно преобразовать текстовое значение поля ввода в числовое, иначе генерируется исключение.
Далее мы явно приводим переданную в обработчик ссылку типа object на нажатую кнопку к типу Button.
В заголовке переключателя выделяем имя нажатой кнопки и выполняем
соответствующую
После переключателя мы располагаем оператор вывода строки System. с
выполненной операцией в панель оболочки Output.
Этот класс предназначен для работы с программой в отладочном
режиме
и автоматически изымается из кода
при компиляции окончательного варианта приложения в режиме .
На последнем этапе, в коде обработчика,
мы выводим результат в соответствующее текстовое поле с
предварительным
Теперь создадим обработчик нажатия на кнопку закрытия формы.
В
режиме Design двойным щелчком на кнопке btnExit создайте
обработчик, который заполните такprivate void btnExit_Click(object sender, System.EventArgs e)
{
this.Close();
}
Запустите
проект и проверьте функциональность простого калькулятораТеперь мы должны подключить разработанную форму калькулятора к основному окну приложения.
Установите
в качестве стартовой форму Start. Для
этого выполните команду меню оболочки Project/WinFormsApp
Properties и в появившемся диалоговом окне установите
для вкладки Application свойство Startup
Object в
значение WinFormsApp.Program
Откройте
файл Start.cs в режиме View Code.
Через раскрывающийся список Members в
верхней части окна generalList_SelectedIndexChanged(),
который мы создали ранее, и дополните его вызовом окна
калькулятораprivate void generalList_SelectedIndexChanged(object sender, System.EventArgs e)
{
switch(generalList.SelectedIndex + 1)
{
case 1:
Smiles frm1 = new Smiles();
frm1.ShowDialog();
break;
case 2:
Calculate frm2 = new Calculate();
frm2.ShowDialog();
break;
}
}
В
панели Solution Explorer оболочки щелкните
дважды на пиктограмме файла Start.cs,
чтобы открыть его в режиме View
Designer,
выделите элемент списка в клиентской области формы и через
панель Properties добавьте в свойство Items строку
" 2)
Простой калькулятор "
Запустите
приложение и проверьте его работоспособностьВ C# под коллекцией понимается группа объектов,
возможно, не одинаковых типов. Самым простым примером коллекции
является обычный массив. Но в отличие от массива коллекции
способны хранить объекты разных System.Collections библиотеки mscorlib.dll
C# - классы коллекций по сути аналогичны классам стандартной
библиотеки шаблонов ( - Standard C++. То, что в C++ называется контейнером,
в C# именуется коллекцией. Коллекции
упрощают программирование, предлагая уже готовые решения
для построения структур данных, разработка которых "с нуля"
потребовала бы больших затрат.
Основное достоинство коллекций состоит в том, что они упрощают
работу с группами объектов в , IComparer, IDictionary и т.д.).
Для контроля за запуском форм упражнений и предотвращения
их повторного запуска можно использовать обычный массив,
куда при каждом запуске очередной формы сохранять метку
на форму и при повторной попытке проверять существование
этой метки. Но недостатком использования массива является
его фиксированный размер, определяемый однажды при создании
массива. Коллекцию использовать удобнее, поскольку механизм
автоматического изменения размера в нее уже встроен, и предусмотрен
ряд полезных методов для управления коллекцией. Все коллекции
предполагают использование цикла foreach (в
каждом) для
Мы будем использовать класс ,
представляющий собой массив переменной длины ( динамический
массив ), элементами которого являются объектные ссылки. Только,
для удобства и тренировки мы упакуем этот класс в свой класс,
в котором предусмотрим необходимые нам методы и свойства.
При этом мы не будем создавать для нового класса отдельный
файл, а добавим его в файл Start.cs. Все методы класса и
ссылку на коллекцию сделаем статическими, чтобы не создавать
экземпляр класса в основном
Добавьте
в Start следующий код// Класс для предотвращения повторных запусков форм
public class Restart
{
// Создали коллекцию
private static System.Collections.ArrayList frmList =
new System.Collections.ArrayList();
// Метод для добавления метки в коллекцию
public static void Add(Object frm)
{
frmList.Add(frm);
}
// Метод для удаления метки из коллекции
public static void Remove(String str)
{
frmList.Remove(str);
}
// Метод, который отвечает на вопрос - запущена ли форма
public static bool IsPresent(Object frm)
{
bool flag = false;
foreach(Object x in frmList)
{
if(Object.Equals(x.ToString(), frm.ToString()))
flag = true;
}
return flag;
}
}
Найдите
в файле Start.cs обработчик generalList_SelectedIndexChanged() и
замените его тело на следующий кодprivate void generalList_SelectedIndexChanged(object sender, System.EventArgs e)
{
switch(generalList.SelectedIndex + 1)
{
case 1:
Smiles frm1 = new Smiles();
if(!Restart.IsPresent(frm1))
{
Restart.Add(frm1);
frm1.Show();
}
break;
case 2:
Calculate frm2 = new Calculate();
if(!Restart.IsPresent(frm2))
{
Restart.Add(frm2);
frm2.Show();
}
break;
}
}
В
режиме дизайна форм Smiles и Calculate создайте
обработчики для события FormClosed, которые
заполните кодом удаления метки из коллекции при закрытии
формыprivate void Smiles_FormClosed(object sender, FormClosedEventArgs e)
{
Restart.Remove(this.ToString());
}
private void Calculate_FormClosed(object sender, FormClosedEventArgs e)
{
Restart.Remove(this.ToString());
}
Запустите
приложение и проверьте, что повторный запуск уже запущенной
дочерней формы блокируетсяВ реализациях следующих упражнений этой лабораторной работы
нам необходимо соблюдать введенную нами технологию предотвращения
повторных запусков дочерних форм. Для этого в переключателе switch обработчика generalList_SelectedIndexChanged() нужно
добавлять метку запущенной формы в коллекцию нашего класса , а при закрытии дочерней формы необходимо удалять
эту метку из коллекции в обработчике события FormClosed.
В этом упражнении мы встроим COM -объект
( COM - - оболочки.
Чтобы не смешивать набор элементов стандартных вкладок панели ,
поместим этот элемент в отдельную вкладку.
Через
панель Solution Explorer откройте любой
файл проекта в режиме дизайна, чтобы стала доступна панель
инструментов Toolbox . Щелкните правой
кнопкой мыши на любом месте панели Toolbox и
через контекстное меню выполните команду Add
Tab
Присвойте
добавленной вкладке имя " Моя
вкладка " и раскройте ееMain() в файле Start.cs стоял
атрибут [STAThread],
который сообщает среде исполнения, что основной программный
поток приложения должен использовать однопоточную модель.
Это необходимо для правильного взаимодействия с подсистемой COM.
Щелкните
на новой вкладке правой кнопкой мыши и выполните команду
контекстного меню Choose Items
В
появившемся окне выберите вкладку COM Components,
найдите в списке Windows
Media Player, отметьте его и щелкните на
кнопке OK
После этого в новой вкладке панели появится
пиктограмма выбранного компонента

и его можно размещать на форме обычным образом.
Замечание.
Возможно, что оболочка на Вашем компьютере по умолчанию настроена
на другой тип COM -компонента, который будет
иметь другие свойства и события, чем используемый в этой
работе. В этом случае щелкните на кнопке вкладки COM
Components окна выбора элементов Choose
Toolboxs Items и в системном каталоге Windows/System32 выберите компонент msdxm..
Это и будет интересующий нас компонент

Через
меню оболочки выполните команду Project/Add Windows
Form ,
чтобы добавить к проекту новую форму, и в появившемся диалоговом
окне задайте имя файла формы MediaPlayer.cs
Поместите
на форму с вкладки " Моя вкладка " компонент
плеера. Форма после этого будет иметь такой вид
Выделите
компонент видеоплейера на форме и через панель Properties задайте
ему следующие свойства| Свойство | Значение | Пояснения |
|---|---|---|
Name |
|
Имя компонента |
AutoRewind |
True |
Автоперемотка, чтобы после просмотра видеоплеер устанавливался в начало |
AutoStart |
False |
Чтобы плеер не начинал проигрывать файл сразу после его открытия, а ждал отдельной команды на проигрывание |
ClickToPlay |
False |
Отключили возможность проигрывания/остановки по щелчку на самом плеере |
Size/Width |
286 |
Можно настроить в визуальном режиме |
Size/Height |
280 |
Можно настроить в визуальном режиме |
Перейдите
в режим редактирования кода файла MediaPlayer.cs и
добавьте в конец класса MediaPlayer точку
входа для автономного запуска вместе с атрибутом однопоточности [STAThread]// Точка входа
[STAThread]
static void Main()
{
Application.Run(new MediaPlayer());
}
Выполните
команду меню Project/WinFormsApp Properties и
установите в свойстве Startup Object значение WinFormsApp.MediaPlayer,
чтобы сделать форму плеера стартовой на период отладкиЕсли выделить компонент плеера и посмотреть его свойства
в панели Properties, то можно увидеть много
возможностей для его начальной настройки в режиме дизайна.
Вот некоторые из свойств
| Свойство | Пояснение |
|---|---|
|
Темп воспроизведения. Если установить его значение, например, равным 2, то файл будет проигрываться в удвоенном темпе |
PlayCount |
Сколько раз повторять проигрывание файла. При значении 0 воспроизведение файла будет повторяться бесконечно |
|
Файл для проигрывания |
|
(немой) Начальное состояние кнопки включения звука |
ShowControls |
Показывать или нет встроенную панель управления плеером |
ShowTracker |
(буксир) Показывать или нет ползунок поиска проигрывателя |
ShowAudioControls |
Показывать или нет элементы управления динамиком |
ShowDisplay |
Показывать или нет информационную панель со сведениями о проигрываемом файле |
ShowPosicionControls |
Отключает панель управления позицией головки проигрывателя |
CurrentPosition |
Содержит значение, на какой секунде находится в данный момент воспроизведение файла |
|
Громкость звука. Число 0 - самый громкий звук. Отрицательное число -10000 означает полную тишину |
|
Свойство только для чтения, доступно программно. Содержит общую продолжительность проигрываемого файла в секундах |
Часть из этих свойств можно настроить через окно свойств самого компонента, если щелкнуть на нем правой кнопкой мыши. Это окно устанавливает те же самые свойства через более понятный интерфейс

Продублируем встроенные элементы управления плеером своими. Эти действия будем выполнять последовательно шаг за шагом, сразу программируя и проверяя их работу.
Увеличьте
вниз размер формы так, чтобы освободить место для элементов
управления. Разместите на форме из вкладки Containers панели Toolbox элемент
управления GroupBox , который будет служить контейнером для
наших элементов. Задайте ему свойства: Name = groupBox , Dock =Text =" Мои
элементы управления "
Поместите
в верхней части контейнера groupBox четыре кнопки Button.
Кнопки помещайте так: щелкайте на компоненте Button вкладки Common
Controls панели Toolbox один
раз, затем щелкайте внутри контейнера groupBox .
Контейнер для кнопок будет родителем и
может передавать им значения своих свойств, например, местоположение,
цвет
Выровняйте
кнопки, используя панель инструментов Layout оболочки
Замкните
элементы управления групповой командой Format/Lock
Controls, чтобы случайно не нарушить дизайн
Задайте
кнопкам следующие свойства| Элемент | Свойство | Значение | Пояснения |
|---|---|---|---|
Button |
Name |
btnOpen | Кнопка для открытия диалога выбора проигрываемого файла |
Text |
Open | ||
Button |
Name |
btnPlay | Кнопка для начала воспроизведения |
Text |
|||
Button |
Name |
btnStop | Кнопка для остановки воспроизведения |
Text |
Stop | ||
Button |
Name |
btnRewind | Кнопка установки в начало воспроизведения |
Text |
Теперь нужно запрограммировать наши кнопки в соответствии с решаемой задачей.
Кнопка btnOpen должна
загружать файл, предназначенный для проигрывания. Воспользуемся стандартным
диалогом .
Поместите
из вкладки Dialogs панели Toolbox компонент OpenFileDialog.
Это невизуальный компонент (неотображаемый
на форме на
Настройте
объект диалога Properties, предварительно
выделив его в подвале | Элемент | Свойство | Значение | |
|---|---|---|---|
OpenFileDialog |
Name |
openFilePlayer | |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Wave (Microsoft) (*.wav) |*.wav| Dialogic VOX ADPCM (*.vox) |*.vox| InterVoice (*.ivc) |*.ivc| Macintosh AIFF (*.aif,*.aiff,*.snd) |*.aif,*.aiff,*.snd| MP3 Audio (*.mp3) |*.mp3| NeXT/Sun (Java) File (*.ai,*.snd) |*.ai,*.snd| OggVorbis (*.ogg) |*.ogg| Perfect Clarity Audio (*.pca) |*.pca| QuickTime (*.mov) |*.mov| Raw File (*.raw) |*.raw| RealMedia (*.rm) |*.rm| Sound Designer 1 (*.dig,*.sd) |*.dig,*.sd| Video for Windows (*.avi) |*.avi| Windows Media (*asf) |*asf| Windows Media Audio (*.wma) |*.wma| Windows Media Video (*.wmv) |*.wmv| All Files (*.*) |*.* |
|
FilterIndex |
13 |
Свойство предназначено для управления
пользователем типом отображаемых файлов, а свойство FilterIndex устанавливает,
какой фильтр появится первым при запуске окна. Фильтры в
свойстве следуют парами друг за другом " Название
фильтра|шаблон_фильтра " и разделяются
символом "Вертикальная черта".
Внимание!!! Если
вы будете копировать значение свойства прямо
из этой таблицы, то предварительно нужно убрать все невидимые
символы перевода на новую строку (например, в блокноте),
которые здесь введены в целях форматирования. Строка фильтра
должна быть непрерывной. В шаблонах_фильтране
должно быть пробелов ни внутри, ни в окружении,
иначе фильтр не сработает.
Создадим, как и в случае с калькулятором, один обработчик для всех размещенных ранее кнопок. Для этого выполните следующее...
Перейдите
в режим дизайна для файла MediaPlayer.cs,
выделите первую кнопку btnOpen и через
панель Properties для события Click в
поле его значений установите вручную имя
обработчика btnClick
Разместите
в созданном оболочкой обработчике следующий кодprivate void btnClick(object sender, System.EventArgs e)
{
Button btn = (Button) sender;// Явное приведение типов
switch(btn.Name)
{
case "btnOpen":
openFilePlayer.InitialDirectory = // Начальный каталог для фильтра
System.IO.Directory.GetCurrentDirectory();// Каталог исполнимого файла
openFilePlayer.ShowDialog();// Открываем диалог
Player.FileName = openFilePlayer.FileName;// Передаем имя файла в плеер
break;
}
}
Подсоедините
обработчик btnClick к остальным кнопкам.
Для этого откройте панель Properties в
режиме Events , выделите оставшиеся три
кнопки вместе и
через раскрывающийся список в поле значения свойства Click выберите
обработчик btnClick
Дополните
код обработчика btnClick такprivate void btnClick(object sender, System.EventArgs e)
{
Button btn = (Button) sender;// Явное приведение типов
switch(btn.Name)
{
case "btnOpen":
openFilePlayer.InitialDirectory = // Начальный каталог для фильтра
System.IO.Directory.GetCurrentDirectory();// Каталог исполнимого файла
openFilePlayer.ShowDialog();// Открываем диалог
Player.FileName = openFilePlayer.FileName;// Передаем имя файла в плеер
break;
case "btnPlay":
Player.Play();
break;
case "btnStop":
Player.Stop();
break;
case "btnRewind":
Player.CurrentPosition = 0;
break;
}
}
После завершения работы стандартного диалогового окна OpenFileDialog его
свойство либо содержит полное (вместе
с путем) имя выбранного файла, либо пустую строку, если пользователь
отказался от выбора.
Теперь мы готовы к Source файл " WellWait
- 02. "). Поэкспериментируйте с кнопками
- они все работают.
Но здесь есть одна проблема. Если пользователь после
запуска формы вначале щелкнет на кнопке btnPlay,
то будет сгенерировано исключение, поскольку нечего проигрывать.
Эту проблему можно решить двумя способами:
try...catchbtnPlay до тех
пор, пока не будет загружен файл для проигрыванияМы воспользуемся вторым способом. Для начального блокирования кнопки есть три пути:
Enabled кнопки
на FalseEnabled кнопки
в состояние false в MediaPlayerLoad и
разместить в нем код установки кнопки в недоступное состояниеМы воспользуемся последним способом. При этом будем блокировать
все кнопки, кроме btnOpen, чтобы лишний
раз не вводить в заблуждение нашего дорогого пользователя.
Перейдите
в режим View Designer формы, выделите
форму щелчком на ее заголовке или через раскрывающийся
список панели Properties, установите панель Properties в
режим Events и создайте обработчик события Load формы
двойным щелчком на поле значений этого события. Заполните
обработчик следующим кодомprivate void MediaPlayer_Load(object sender, System.EventArgs e)
{
btnPlay.Enabled = btnStop.Enabled = btnRewind.Enabled = false;
}
Здесь мы употребили сцепленную
Теперь нужно разблокировать кнопки после того, как будет загружен файл в проигрыватель. Для этого
Дополните
обработчик btnClick следующим кодомprivate void btnClick(object sender, System.EventArgs e)
{
Button btn = (Button) sender;// Явное приведение типов
switch(btn.Name)
{
case "btnOpen":
openFilePlayer.InitialDirectory = // Начальный каталог для фильтра
System.IO.Directory.GetCurrentDirectory();// Каталог исполнимого файла
openFilePlayer.ShowDialog();// Открываем диалог
Player.FileName = openFilePlayer.FileName;// Передаем имя файла в плеер
if(Player.FileName.Length > 0)
{
// Перебираем все дочерние элементы контейнера GroupBox
foreach(Control obj in groupBox.Controls)
{
// Выделяем полное имя типа вместе с пространствами имен
String str = obj.GetType().ToString();
// Ищем позицию последней точки
int pos = str.LastIndexOf('.');
// Выделяем имя типа без пути
str = str.Substring(pos + 1);
if(str == "Button")
obj.Enabled = true;
}
}
break;
case "btnPlay":
Player.Play();
break;
case "btnStop":
Player.Stop();
break;
case "btnRewind":
Player.CurrentPosition = 0;
break;
}
}
В добавленном коде мы проверяем, что выбранное пользователем имя файла непустое (надо было все-таки поставить обработчик исключения, поскольку пользователь может выбрать файл, не подлежащий проигрыванию. Но пока хватит и этого!).
Родительские элементы, такие как Panel, , TabControl,
сама форма Form, имеют свойство Controls,
которое является коллекцией и содержит ссылки на все помещенные
на родительский элемент дочерние компоненты - наследники
класса Control.
Мы перебираем в цикле foreach ( -для
каждого ) все элементы коллекции ,
находим среди них кнопки и устанавливаем их доступными.
Здесь мы наворотили лишние проверки на тот случай, если
кроме кнопок в контейнере окажутся
и элементы других типов, хотя на данном этапе кроме кнопок
мы туда ничего не помещали.
Запустите
проект и убедитесь, что все добавленные нами возможности
управления работают правильно.Усовершенствуем схему управления медиаплеером. Задействуем
возможности управления звуком и контроля позиции проигрывающей
головки. Для этого нам понадобятся такие элементы управления
вкладки All , как TrackBar ( ползунок ), ( флажок ), ProgressBar ( индикатор
процесса, индикатор прогресса ), TextBox ( текстовое
поле ).
Сместите
кнопку btnRewind влево на один уровень
с кнопкой btnOpen и поместите на освободившееся
справа место элемент CheckBox (один
щелчок на CheckBox , затем щелчок внутри
контейнера groupBox ). Этот элемент даст
возможность пользователю отключать или включать звук при
воспроизведении файла
Правее
элемента CheckBox разместите в контейнере groupBox текстовое
поле TextBox,
которое мы будем использовать для отображения численного
значения величины звука
Ниже
разместите в контейнере groupBox элемент TrackBar для
плавного регулирования звукаТеперь нужно настроить эти элементы управления. Начнем с
элемента . Этот элемент мы будем
использовать для отключения звука плеера. Настройте его свойства
так
| Свойство | Значение |
|---|---|
Name |
checkVolume |
CheckAlign |
MiddleLeft |
Image |
VOLUME01.ICO (возьмите из данной работы в каталоге
Source. Используйте кнопку Import для
радиокнопки Local ) |
ImageAlign |
BottomRight |
Checked |
True |
Text |
ПУСТО |
Давайте сразу запрограммируем этот элемент. При каждом щелчке
на элементе изменяется его булево
свойство Checked (и CheckState ).
Создайте
в панели Properties обработчик события CheckedChanged элемента checkVolume и
добавьте в него следующий кодprivate void checkVolume_CheckedChanged(object sender, System.EventArgs e)
{
// Это наше извращение, можно сразу обращаться к checkVolume
CheckBox check = (CheckBox) sender;
// В каком состоянии оказался CheckBox
if(check.CheckState == CheckState.Checked)
{
Player.Mute = false;
}
else
{
Player.Mute = true;
}
}
Для плавного изменения звука мы воспользуемся элементом TrackBar.
Свойства и методы элемента TrackBar аналогичны
ScrollBar. Некоторые из
них перечислены в таблице. Причем не все свойства элемента TrackBar доступны
в режиме проектирования, зато все доступны в программном
режиме на этапе выполнения.
| Свойство | Пояснения |
|---|---|
Value |
Главная регулируемая величина, определяющая текущее
состояние головки бегунка. По умолчанию начальное значение
равно значению свойства |
SmallChange |
Минимальная дискретность изменения величины Value при
управлении стрелками или перемещением головки бегунка
с |
LargeChange |
Максимальная дискретность изменения величины Value
при нажатии клавиш PageUp или PageDown, или щелчках мышью
на |
|
Нижний предел значения Value. По умолчанию 0 |
|
Верхний предел значения Value. По умолчанию 10 |
TickFrequency |
Свойство |
TickStyle |
Определяет форму ползунка при отображении пользователю |
Настройте
свойства элемента TrackBar так| Свойство | Значение |
|---|---|
Name |
trackVolume |
Location |
8; 104 |
Size |
272; 53 |
|
0 |
|
50 |
|
|
LargeChange |
5 |
SmallChange |
1 |
TickFrequency |
5 |
TickStyle |
BottomRight |
Присвойте
элементу TextBox имя txtVolume Элемент txtVolume будет только
отображать числовое значение плеера,
поэтому запретим его редактирование пользователем.
Выделите
элемент txtVolume и создайте через панель Properties для
его события KeyPress обработчик,
который заполните такprivate void txtVolume_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
// Запрещаем редактировать поле, кроме клавиши Del
// и горизонтальных стрелок - они встроены в элемент
e.Handled = true;
}
Свойство сообщает элементу, что
все уже обработано и нужно успокоиться и ничего не делать.
Элемент TrackBar имеет
событие , которое происходит каждый
раз, когда изменяется положение головки бегунка. Воспользуемся
этим, чтобы менять численное значение величины плеера.
Создайте
для события Scroll элемента TrackBar обработчик,
который заполните такprivate const int maxVolume = 0;
private const int minVolume = -5000;
private void trackVolume_Scroll(object sender, System.EventArgs e)
{
TrackBar track = (TrackBar) sender;
float minValue = track.Minimum;
float maxValue = track.Maximum;
float value = track.Value;
// Формула линейного изменения свойства Player.Volume
// (самая простая, хотя можно вставить и нелинейный закон)
Player.Volume = minVolume -
(int) ( (value - minValue) /(maxValue - minValue)
* minVolume );
txtVolume.Text = Convert.ToString(Player.Volume);
}
Теперь нужно установить начальные значения текстового поля и положения бегунка при первой загрузке формы
Добавьте
в обработчик события Load формы, который
мы уже создали раньше, следующий кодprivate void MediaPlayer_Load(object sender, System.EventArgs e)
{
btnPlay.Enabled = btnStop.Enabled = btnRewind.Enabled = false;
txtVolume.Text = Convert.ToString(Player.Volume);// Отображаем величину звука
trackVolume.Value = // Устанавливаем бегунок
// Поскольку работаем с целыми, которые округляются,
// то вначале умножаем, потом делим
trackVolume.Minimum + (minVolume - Player.Volume)
* (trackVolume.Maximum - trackVolume.Minimum)
/ minVolume;
}
Чтобы не давать пользователю возможности оперировать элементом TrackBar при
выключенном звуке, будем блокировать этот элемент, когда
звук отключен.
Добавьте
в обработчик checkVolume_CheckedChanged() следующий
код блокирования ползункаprivate void checkVolume_CheckedChanged(object sender, System.EventArgs e)
{
// Это наше извращение, можно сразу обращаться к checkVolume
CheckBox check = (CheckBox) sender;
// В каком состоянии оказался CheckBox
if(check.CheckState == CheckState.Checked)
{
Player.Mute = false;
trackVolume.Enabled = true;
}
else
{
Player.Mute = true;
trackVolume.Enabled = false;
}
}
Теперь мы хотим сделать так, чтобы пользователь мог видеть
по нашему интерфейсу, какая часть файла уже воспроизведена.
Для этого используем ProgressBar.
Есть еще альтернативный вариант - COM-Microsoft
ProgressBar Control 6.0 (SP4).
Этот
Откройте вкладку панели "Моя
вкладка", которую мы создали ранее, щелкните
на ней правой кнопкой мыши и выполните команду Coose Items. Установите в появившемся окне
вкладку COM , найдите
нужный элемент Microsoft ProgressBar Control 6.0 (SP4),
отметьте его и нажмите кнопку OK.
Теперь этот компонент можно помещать на форму обычным
образом.
Некоторые свойства:
Scrolling - гладкий или
прерывистый вид полосыMin , Max - пределы изменения
полосыValue - текущее значениеOrientation - горизонтальное
или вертикальное расположение полосыAppearance , BorderStyle
- внешний вид полосы
Поместите
компонент ProgressBar в
контейнер groupBox (щелчком там и там)
и настройте через панель Properties его
свойства так| Свойство | Значение |
|---|---|
Name |
progressBar |
Location |
16; 160 |
Size |
256; 8 |
Здесь мы установили только интерфейсные свойства элемента, а существенные свойства по управлению элементом будем задавать программно.
Выровняйте
интерфейсные элементы с применением панели инструментов Layout оболочки,
чтобы панель имела на данном этапе примерно такой вид
Выделите
элемент Player и на панели Properties в
режиме Events найдите событие ReadyStateChange.
Создайте двойным щелчком на поле значений этого события
обработчик Player_ReadyStateChange(),
который заполните такprivate void Player_ReadyStateChange(object sender, AxMediaPlayer._MediaPlayerEvents_ReadyStateChangeEvent e)
{
progressBar.Minimum = 0;
int maximum = progressBar.Maximum = (int)Player.Duration;
}
Этот обработчик будет срабатывать каждый раз при загрузке
нового файла и устанавливать новые значения свойств диапазона
Вновь
выделите элемент Player и на панели Properties в
режиме Events найдите событие PositionChange.
Создайте двойным щелчком на поле значений этого события
обработчик Player_PositionChange(), который
заполните такprivate void Player_PositionChange(object sender, AxMediaPlayer._MediaPlayerEvents_PositionChangeEvent e)
{
progressBar.Value = (int)Player.CurrentPosition;
}
Если теперь запустить форму на выполнение, то можно заметить,
что
Добавьте
двойным щелчком во вкладке All Windows Forms на
компоненте Timer timer
Создайте
для его единственного события Tick обработчик,
в котором продублируйте код обработчика Player_PositionChange(),
обновляющий позицию элемента progressBarprivate void timer_Tick(object sender, System.EventArgs e)
{
progressBar.Value = (int)Player.CurrentPosition;
// progressBar.PerformStep();// Для альтернативного способа
}
Дополните
обработчик Player_ReadyStateChange() события
загруки медиафайла кодом настройки и запуска таймераprivate int countSteps;
private void Player_ReadyStateChange(object sender, AxMediaPlayer._MediaPlayerEvents_ReadyStateChangeEvent e)
{
countSteps = 50; // Количество шагов индикатора прогресса
progressBar.Minimum = 0;
progressBar.Maximum = (int)Player.Duration;
timer.Interval = (progressBar.Maximum - progressBar.Minimum)
* 1000 // Переводим секунды в миллисекунды
/ countSteps; // Операция деления на последнем месте
timer.Start();
progressBar.Value = progressBar.Minimum;
/* // Для альтернативного способа
progressBar.Step = (progressBar.Maximum - progressBar.Minimum)
/ countSteps;
*/
}
Красным цветом выделен альтернативный код управления интикатором.
Но если вы его будете использовать, то нужно позаботиться
об остановке таймера при каждой остановке проигрывания и
о его запуске при продолжении проигравания. Если этого не
сделать, то при остановке проигрывания
Выделите
форму через ее заголовок и установите два свойства в следующие
значенияFormBorderStyle=FixedSingleMaximizeBox=FalseТеперь осталось подключить эту форму к основному окну приложения и сделать необходимые настройки.
Создайте
обработчик события FormClosed формы MediaPlayer,
как мы это делали в предыдущих случаях данной работы для
предотвращения повторного запуска, и заполните его такprivate void MediaPlayer_FormClosed(object sender, System.EventArgs e)
{
Restart.Remove(this.ToString());
}
Измените
заголовок формы, задав ее свойству Text значение " Упражнение
№3 - MediaPlayer "
Через
панель Solution Explorer откройте файл Start.cs в
режиме кода и добавьте к обработчику generalList_SelectedIndexChanged() следующий
кодprivate void generalList_SelectedIndexChanged(object sender, System.EventArgs e)
{
switch(generalList.SelectedIndex + 1)
{
.................................................
case 3:
MediaPlayer frm3 = new MediaPlayer();
if(!Restart.IsPresent(frm3))
{
Restart.Add(frm3);
frm3.Show();
}
break;
}
}
Через
панель Solution Explorer откройте файл Start.cs в
режиме дизайна двойным щелчком на пиктограмме. Выделите
через панель Properties список generalList и
добавьте в его свойство Items следующую
строку3) Собственный Windows
Media
Командой
меню оболочки Project/WinFormsApp Properties выберите
вкладку Application
и верните свойство Startup Object в значение WinFormsApp.Program
Запустите
приложение, загрузите медиафайл, испытайте элементы управления
и полюбуйтесь на свою работу. Просмотрите мультик, прилагаемый
к работе
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.