Файлы к лабораторной работе Вы можете скачать здесь.
Изначально все формы отображаются прямоугольными. И все к этому привыкли. Нельзя пытаться удивлять пользователя экзотическими элементами программы. Ему некогда тратить время на привыкание, программа должна согласовываться с его предыдущим опытом и должна быть интуитивно понятной.
Но мы, как проектировщики, должны знать о существовании
возможности создания окон или элементов управления и в
нетрадиционном стиле. При создании непрямоугольных форм и
элементов управления используется свойство базового
класса System.Windows.Forms.Control всех
визуальных компонентов, которое ожидает ссылки на объекты-экземпляры
класса System.Drawing.
Командой File/New/Project создайте
новый проект FormsApp
Через
панель Solution Explorer откройте файл Program.cs и
скопируйте из него в класс Form1 точку
входа для индивидуального запуска новой формыТеперь класс Form1 файла Form1.cs должен
стать таким
public partial class Form1 : Form
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
public Form1()
{
InitializeComponent();
}
}
Выполните
команду Project/FormsApp Properties и
установите в параметре Startup object вкладки Application форму Form1 в качестве
стартовой
Через
панель Solution Explorer удалите файл Program.cs
Откройте
файл Form1.cs в режиме View
Designer, выделите форму щелчком по ее заголовку и через
панель Properties установите
размеры формы в свойствеSize=450;200
Запустите
приложение и убедитесь, что новая форма появляется сразуНа этом подготовительная часть к выполнению упражнения завершена.
В библиотеке .NET Framework (System.Drawing.Drawing2D.GraphicsPath,
который можно использовать как коллекцию для заблаговременного
сохранения различных графических примитивов, которые затем
можно нарисовать все "одним махом", если передать
эту коллекцию в функцию
System.Drawing..
Особенность такого способа рисования состоит в том, что незамкнутые контуры всех входящих в коллекцию фигур автоматически замыкаются функцией рисования. И это позволяет легко заливать сложные замкнутые фигуры функцией
System.Drawing.
Давайте продемонстрируем упомянутые возможности, нарисовав
на новой форме головку Буратино. Код рисования поместим в
отдельную функцию, а вызов этой функции разместим в OnPaint() формы, чтобы при каждом
разрушении окна формы (перемещение, изменение размеров) прорисовка
изображения повторялась.
Подключите
в начале файла Form1.cs пространство
имен System.Drawing.Drawing2D для
сокращенной идентификации класса GraphicsPathusing System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Drawing.Drawing2D;
Добавьте
к классу Form1 новый
метод с именем DrawBuratino(),
который заполните так// Рисование головки Буратино
private void DrawBuratino()
{
GraphicsPath path = new GraphicsPath();
path.AddArc(20, 20, 120, 120, 0, 330); // Голова без носа
path.AddArc(220, 20, 10, 10, 270, 180); // Удаленный кончик носа
path.CloseFigure(); // Замкнули незаконченные дуги
path.AddEllipse(90, 40, 20, 20); // Добавили глаз
Graphics gr = this.CreateGraphics(); // Создаем холст
gr.DrawPath(Pens.Red, path); // Рисуем контур Буратино
gr.TranslateTransform(200, 0); // Смещаемся вправо
gr.FillPath(Brushes.Blue, path); // Рисуем заливку Буратино
gr.DrawPath(Pens.Red, path); // Рисуем контур для заливки
}
Переопределите
метод OnPaint() формы, который наследуется
ею от класса ControlКод начинайте вводить
вручную с ключевого слова .
Когда вы его введете и нажмете клавишу пробела, подсказчик
кода ( суфлер )
выдаст список переопределяемых методов формы, в котором
можно быстро позиционироваться, продолжая набирать имя
переопределяемого метода в любом регистре. Нажатие клавиши
ввода завершит создание правильной заготовки
переопределяемого метода.
Разместите
в // Переопределяем метод перерисовки формы
protected override void OnPaint(PaintEventArgs e)
{
DrawBuratino();
base.OnPaint(e);
}
Запустите
приложение и должен получиться такой результат
Теперь сделаем форму непрямоугольной. Для этого необходимо
воспользоваться свойством формы,
определяющим ее силуэт.
Добавьте
к классу Form1 новую функцию
с именем DrawForm()// Рисование непрямоугольной формы
private void DrawForm()
{
GraphicsPath path = new GraphicsPath();
path.AddEllipse(0, -300, this.Width, 600);
this.Region = new Region(path);
}
В функции
public void AddEllipse (int x, int y, int width,
int height)
первые два параметра определяют координаты левого верхнего
угла прямоугольника, описывающего
Добавьте
в функции OnPaint() вызов этой новой функции DrawForm()// Переопределяем метод перерисовки формы
protected override void OnPaint(PaintEventArgs e)
{
DrawBuratino();
DrawForm();
base.OnPaint(e);
}
Перейдите
в режим View Designer формы, выделите
форму щелчком по ее заголовку и через панель Properties в
режиме Events создайте
обработчик для события Resize , в который
поместите требование перерисовки формы при изменении размеровprivate void Form1_Resize(object sender, EventArgs e)
{
this.Invalidate();
}
Запустите
форму на выполнение - должен получиться такой результат
Событие мы
использовали для прорисовки формы на случай изменения ее
размеров в сторону возрастания.
В заключение выполнения этого упражнения введем
возможность перетаскивания формы не только за ее заголовок,
но и за клиентскую область.
Добавьте
к классу Form1 объявления
двух локальных полей int x, y;
Создайте
для формы через панель Properties в режиме Events обработчики для событий MouseDown и MouseMove,
которые заполните такprivate void Form1_MouseDown(object sender, MouseEventArgs e)
{
// Сохраняем координаты мыши на момент щелчка относительно формы
if (e.Button == MouseButtons.Left)
{
x = e.X;
y = e.Y;
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
// Измеряем смещение относительно щелчка
// и подвигаем форму на это смещение
if (e.Button == MouseButtons.Left)
{
this.Left += e.X - x;
this.Top += e.Y - y;
}
}
Этот код обеспечивает перемещение формы относительно начального положения, которое она имела до нажатия левой кнопки мыши, ровно настолько, на сколько переместился курсор мыши после нажатия кнопки. Поэтому нажатый курсор и форма перемещаются синхронно.
Остался последний штрих для этого упражнения - изменять
форму курсора при
Добавьте
в код обработчика нажатия кнопки мыши строку изменения
формы курсораprivate void Form1_MouseDown(object sender, MouseEventArgs e)
{
// Сохраняем координаты мыши на момент щелчка относительно формы
if (e.Button == MouseButtons.Left)
{
x = e.X;
y = e.Y;
// Форма курсора
Cursor.Current = Cursors.SizeAll;
}
}
Измените
заголовок формы, задав ее свойству Text значение " Упражнение
1. Непрямоугольная форма "
Запустите
приложение и убедитесь, что при нажатии левой кнопки мыши
на клиентской области форма курсора меняется и окно послушно
следует за нимЭлемент управления TabControl ( вкладки,
закладки, страницы свойств )
создает одну или несколько вкладок, на каждой из которых
могут быть размещены другие объекты. Мы воспользуемся этим
элементом, чтобы упаковать примеры со стандартными
диалогами в одну форму.
Стандартные диалоговые окна являются хорошим подспорьем
для программиста, поскольку позволяют воспользоваться
при создании интерфейса хорошо оформленными и отлаженными
инструментами, которые создали разработчики
System.Windows.Forms.MessageBox -
простое диалоговое окно сообщенийSystem.Windows.Forms.OpenFileDialog -
диалоговое окно System.Windows.Forms.SaveFileDialog -
диалоговое окно сохранения файлаSystem.Windows.Forms.ColorDialog -
диалоговое окно выбора цветаSystem.Windows.Forms.FontDialog -
диалоговое окно выбора шрифтаSystem.Windows.Forms.PrintDialog -
окно задания на печать документаSystem.Windows.Forms.PrintPreviewDialog -
окно предварительного просмотра документа перед печатьюSystem.Windows.Forms.PageSetupDialog -
настройка параметров страницыSystem.Windows.Forms.FolderBrowserDialog -
диалоговое окно для навигации по папкам файловой системы
компьютера
Добавьте
к проекту новую форму командой Project/Add Windows
Form с именем StandardDialogs.cs
Добавьте
к классу StandardDialogs точку
входа вместе с атрибутом однопоточности для автономного
запуска формы[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new StandardDialogs());
}
Установите
в свойствах проекта форму StandardDialogs стартовой
Настройте
свойства формы StandardDialogs в соответствии
с таблицей| Свойство | Значение | Пояснения |
|---|---|---|
StartPosition |
CenterScreen |
Открывать в центре экрана |
FormBorderStyle |
FixedDialog |
Запретить пользователю менять размер |
MaximizeBox |
false |
Отключить системную кнопку |
MinimizeBox |
false |
Отключить системную кнопку свертывания |
ShowInTaskbar |
false |
Запретить появление в панели задач |
Size |
576; 488 |
Размер формы |
Text |
Упражнение 2. StandardDialogs |
Заголовок окна |
В этом упражнении мы будем рассматривать ряд стандартных
диалогов по отдельности. Для настройки и управления каждым
рассматриваемым диалогом организуем свое окно, которое
будет являться вкладкой компонента TabControl.
Это компонент является контейнером для заданного количества
вкладак и существенно экономит место на экране. Отметим
некоторые его свойства
| Свойство | Пояснения |
|---|---|
|
Определяет форму курсора, отображаемого над элементом |
Multiline |
Разрешает поддерживать несколько вкладак |
TabCount |
Количество вкладок |
TabPages |
Коллекция вкладок в элементе |
Поместите
на форму из вкладки Containers панели Toolbox
компонент TabControl и
задайте ему через панель Properties следующие
свойства| Свойство | Значение |
|---|---|
Name |
tabControl |
|
Fill |
Multiline |
True |
TabPages.Name |
tabPage0 |
TabPages.Text |
Обзор |
TabPages.Name |
tabPage1 |
TabPages.Text |
MessageBox |
TabPages.Name |
tabPage2 |
TabPages.Text |
OpenFileDialog |
TabPages.Name |
tabPage3 |
TabPages.Text |
SaveFileDialog |
TabPages.Name |
tabPage4 |
TabPages.Text |
ColorDialog |
TabPages.Name |
tabPage5 |
TabPages.Text |
FontDialog |
TabPages.Name |
tabPage6 |
TabPages.Text |
PrintDialog |
TabPages.Name |
tabPage7 |
TabPages.Text |
PrintPreviewDialog |
TabPages.Name |
tabPage8 |
TabPages.Text |
PageSetupDialog |
TabPages.Name |
tabPage9 |
TabPages.Text |
FolderBrowserDialog |
TabPages.Name |
tabPage10 |
TabPages.Text |
MyDialog |
При программировании отдельных вкладок элемента TabControl важно
понимать, что компоненты каждой вкладки находятся в одной
и той же Name ).

На этой вкладке мы разместим радиокнопки, при нажатии на которых будет появляться соответствующее стандартное диалоговое окно с минимальными настройками, определенными в коде при его создании.
В
режиме View Designer выделите вкладку " Обзор " и
поместите на нее компонент GroupBox как
контейнер для красоты оформления. Настройте его так| Свойство | Значение |
|---|---|
Name |
groupReview |
|
Fill |
Text |
Пусто |
Выделив
компонент groupReview, поместите
внутрь этого контейнера две текстовых
метки Label и
10 радиокнопок (элемент RadioButton ).
Выровняйте их и настройте как показано на снимке
Для
текстовой метки с белым фоном установите такие свойства| Свойство | Значение |
|---|---|
|
false |
Location |
79, 18 |
Size |
364, 126 |
BackColor |
White |
Font.Name |
Arial |
|
20 |
Font.Bold |
True |
ForeColor |
Blue |
Text |
Визуальный обзор окон стандартных диалогов |
TextAlign |
MiddleCenter |
Радиокнопки согласованно работают только тогда, когда
они помещены в контейнер. Это может быть форма Form,
элемент или элемент Panel.
Если требуется создать несколько отдельных групп радиокнопок,
то их нужно скомпоновать по отдельным контейнерам.
Элемент Panel для этих целей
хорош тем, что его границы могут быть невидимыми. Любой
контейнер является родителем для размещенных в нем
элементов. Изменяя свойства контейнера (перемещение,
видимость, цвет, стиль), можно управлять аналогичными
свойствами всей группы дочерних элементов.
Теперь необходимо запрограммировать эту вкладку. Для всех
радиокнопок мы создадим общий обработчик события Click,
в котором будем анализировать, какая радиокнопка нажата,
чтобы вызвать соответствующий диалог.
Предварительно
замкните интерфейс, выполнив групповую команду Format/Lock
Controls
Выделите
все радиокнопки вкладки, обведя их курсором. В панели Properties создайте
общий для всех радиокнопок обработчик для события Click двойным
щелчком на поле этого события
Опять
выделите все радиокнопки и в панели Properties скорректируйте
имя обработчика события Click,
сгенерированное автоматически, на свое - standardDialogs_ClickОболочка с обработчиками работает так: если тело обработчика пустое и нет иных подключений, то он переименовывается, если непустое или есть на него ссылки иных элементов, то создается пустой обработчик с новым именем.
В теле обработчика воспользуемся тем фактом, что значение
свойства Text всех радиокнопок мы задали
по имени соответствующего диалога, кроме последнего, который
разработаем позднее. При каждом срабатывании события Click мы
по свойству Text радиокнопки
определим, какой диалог создать и вывести на экран.
Заполните
обработчик standardDialogs_Click() следующим кодом#region Вкладка "Обзор"
private void standardDialogs_Click(object sender, System.EventArgs e)
{
RadioButton radio = (RadioButton)sender;
// Для контроля при отладке
System.Diagnostics.Debug.WriteLine("Нажата радиокнопка " + radio.Text);
switch (radio.Text.Trim())// Чтобы убрать возможные пробелы
{
case "MessageBox":
MessageBox.Show( // Статический метод - модальный вызов
"Это удобная форма выдачи сообщений!", // Сообщение
"Стандартный диалог MessageBox", // Заголовок окна
MessageBoxButtons.OK, // Кнопка OK
MessageBoxIcon.Stop);// Критическая иконка
break;
case "OpenFileDialog":
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Title = "OpenFileDialog";
openFileDialog.ShowDialog();// Модальный вызов
openFileDialog.Dispose();// Вызов сборщика мусора
break;
case "SaveFileDialog":
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Title = "SaveFileDialog";
saveFileDialog.ShowDialog();// Модальный вызов
saveFileDialog.Dispose();// Вызов сборщика мусора
break;
case "ColorDialog":
ColorDialog colorDialog = new ColorDialog();
colorDialog.ShowDialog();// Модальный вызов
colorDialog.Dispose();// Вызов сборщика мусора
break;
case "FontDialog":
FontDialog fontDialog = new FontDialog();
fontDialog.ShowDialog();// Модальный вызов
fontDialog.Dispose();// Вызов сборщика мусора
break;
case "PrintDialog":
PrintDialog printDialog = new PrintDialog();
printDialog.AllowSomePages = true;// Настраиваем доступ к выбору страниц
printDialog.ShowHelp = true; // Отображать кнопку помощи
printDialog.Document =
new System.Drawing.Printing.PrintDocument();
DialogResult result = printDialog.ShowDialog();// Модальный вызов
if (result == DialogResult.OK)
MessageBox.Show("Пользователь хотел печатать");
printDialog.Dispose();// Вызов сборщика мусора
break;
case "PrintPreviewDialog":
PrintPreviewDialog printPreviewDialog =
new PrintPreviewDialog();
printPreviewDialog.Document =
new System.Drawing.Printing.PrintDocument();
printPreviewDialog.ShowDialog();// Модальный вызов
printPreviewDialog.Dispose();// Вызов сборщика мусора
break;
case "PageSetupDialog":
PageSetupDialog pageSetupDialog = new PageSetupDialog();
pageSetupDialog.PageSettings =
new System.Drawing.Printing.PageSettings();
pageSetupDialog.PrinterSettings =
new System.Drawing.Printing.PrinterSettings();
//Не показывать сеть в диалоге принтера
pageSetupDialog.ShowNetwork = false;
pageSetupDialog.ShowDialog();// Модальный вызов
pageSetupDialog.Dispose();// Вызов сборщика мусора
break;
case "FolderBrowserDialog":
FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
folderBrowserDialog.Description = "Установите нужный каталог текущим";
// Каталог по умолчанию - "Мои документы"
folderBrowserDialog.RootFolder = Environment.SpecialFolder.Personal;
folderBrowserDialog.ShowDialog();// Модальный вызов
folderBrowserDialog.Dispose();// Вызов сборщика мусора
break;
default:
MessageBox.Show("Пока нет - создадим позднее",
"Самодельный диалог",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
break;
}
}
#endregion
Здесь мы применили операторы #... #endregion,
чтобы для удобства редактирования разместить код, относящийся
к каждой вкладке, в отдельные секции.
Запустите
приложение и испытайте вкладку "Обзор" .
Должны вызываться окна всех упомянутых диалогов, например, ColorDialog
Заметьте, что все диалоги мы создаем и вызываем через
код, хотя каждый из них имеет визуальный аналог во вкладке Toolbox. Здесь всю работу графических
возможностей среды разработки мы сделали вручную. Это не
всегда лучший вариант для быстрой разработки интерфейса,
но всегда нужно понимать, что делает оболочка с кодом,
чтобы в любой момент можно было вмешаться и подправить
код более тонко.
Аналогичная ситуация при работе с Web -редакторами:
основную работу можно автоматизировать через графическую
среду, но может возникнуть необходимость вмешиваться в
генерируемый ею HTML -код.
На этой вкладке нашего упражнения мы испытаем возможности
простейшего стандартного диалогового окна MessageBox,
которое применяется разработчиками для быстрого оформления
сообщений пользователю. Это окно реализуется классом System.Windows.Forms.MessageBox,
который имеет 12 перегружаемых статических методов Show() для отображения сообщений в различной
форме. Чтобы воспользоваться этим классом, не нужно создавать
его экземпляры, а можно сразу вызывать метод MessageBox.Show(),
в который помещать нужные аргументы. Show() имеют следующий синтаксис
public static System.Windows.Forms.DialogResult
Show ( System.String text )public static System.Windows.Forms.DialogResult
Show ( System.String text , System.String caption )public static System.Windows.Forms.DialogResult
Show ( System.String text , System.String caption ,
System.Windows.Forms.MessageBoxButtons buttons )public static System.Windows.Forms.DialogResult
Show ( System.String text , System.String caption ,
System.Windows.Forms.MessageBoxButtons buttons , System.Windows.Forms.MessageBoxIcon
icon )public static System.Windows.Forms.DialogResult
Show ( System.String text , System.String caption ,
System.Windows.Forms.MessageBoxButtons buttons , System.Windows.Forms.MessageBoxIcon
icon , System.Windows.Forms.MessageBoxDefaultButton
defaultButton )public static System.Windows.Forms.DialogResult
Show ( System.String text , System.String caption ,
System.Windows.Forms.MessageBoxButtons buttons , System.Windows.Forms.MessageBoxIcon
icon , System.Windows.Forms.MessageBoxDefaultButton
defaultButton , System.Windows.Forms.MessageBoxOptions
options )public static System.Windows.Forms.DialogResult Show
( System.Windows.Forms.IWin32Window owner , System.String
text )public static System.Windows.Forms.DialogResult Show
( System.Windows.Forms.IWin32Window owner , System.String
text , System.String caption )public static System.Windows.Forms.DialogResult Show
( System.Windows.Forms.IWin32Window owner , System.String
text , System.String caption , System.Windows.Forms.MessageBoxButtons
buttons )public static System.Windows.Forms.DialogResult Show
( System.Windows.Forms.IWin32Window owner , System.String
text , System.String caption , System.Windows.Forms.MessageBoxButtons
buttons , System.Windows.Forms.MessageBoxIcon icon )public static System.Windows.Forms.DialogResult Show
( System.Windows.Forms.IWin32Window owner , System.String
text , System.String caption , System.Windows.Forms.MessageBoxButtons
buttons , System.Windows.Forms.MessageBoxIcon icon ,
System.Windows.Forms.MessageBoxDefaultButton defaultButton
)public static System.Windows.Forms.DialogResult Show
( System.Windows.Forms.IWin32Window owner , System.String
text , System.String caption , System.Windows.Forms.MessageBoxButtons
buttons , System.Windows.Forms.MessageBoxIcon icon ,
System.Windows.Forms.MessageBoxDefaultButton defaultButton
, System.Windows.Forms.MessageBoxOptions options )В нашей вкладке мы реализуем вызовы наиболее распространенных
( шесть первых в списке ) перегрузок метода MessageBox.Show().
Для этого нам еще понадобятся раскрывающиеся
списки ComboBox,
текстовые поля TextBox, текстовые метки Label, чтобы выбирать настройки каждой System.Windows.Forms.DialogResult,
по которому можно определить выбор пользователя.
Метод MessageBox.Show() в выделенных
перегрузках имеет следующие параметры:
System.String text -
сообщение пользователюSystem.String caption -
заголовок окнаSystem.Windows.Forms.MessageBoxButtons buttons -
состав кнопок ( перечисление )AbortRetryIgnoreOKOKCancelRetryCancel18_23No18_23NoCancelSystem.Windows.Forms.MessageBoxIcon
icon -
пиктограмма ( перечисление )Asterisk ErrorExclamationHand InformationNoneQuestion StopWarning System.Windows.Forms.MessageBoxDefaultButton defaultButton -
кнопка, имеющая при запуске фокус ввода по умолчанию
( перечисление )Button1Button2Button3System.Windows.Forms.MessageBoxOptions options -
настройки ( перечисление )DefaultDesktopOnlyRightAlignRtlReadingServiceNotificationВсе перечисленные настройки мы реализуем в нашей вкладке, чтобы продемонстрировать, как они выглядят.
Оформим вкладку MessageBox, чтобы удобно
было испытывать стандартное окно сообщений.
Разместите
на вкладке MessageBox элементы управления
и частично оформите их, как показано на снимке
Заполните
свойство Items элемента comboBox1 следующими строками1) MessageBox.Show(text); 2) MessageBox.Show(text, caption); 3) MessageBox.Show(text, caption, buttons); 4) MessageBox.Show(text, caption, buttons, icon); 5) MessageBox.Show(text, caption, buttons, icon, defaultButton); 6) MessageBox.Show(text, caption, buttons, icon, defaultButton, options);
Заполните
свойство Items элемента comboBox2 следующими
строкамиAbortRetryIgnore OK OKCancel RetryCancel 18_23No 18_23NoCancel
Заполните
свойство Items элемента comboBox3 следующими
строкамиAsterisk Error Exclamation Hand Information None Question Stop Warning
Заполните
свойство Items элемента comboBox4 следующими
строкамиButton1 Button2 Button3
Заполните
свойство Items элемента comboBox5 следующими
строкамиDefaultDesktopOnly RightAlign RtlReading ServiceNotification
Выделите
на вкладке MessageBox все списки и
текстовые поля (текстовые
метки Label оставьте в покое ),
входящие в контейнер groupBox1.
Установите для них следующие значения свойств:Text = ПУСТОEnabled = False
Проверьте,
что для элемента comboBox1 установлено
свойство Enabled = True
Создайте
для элемента comboBox1 обработчик события SelectedIndexChanged с
именем comboBox1_SelectedIndexChanged(),
который заполните такprivate void comboBox1_SelectedIndexChanged(object sender, System.EventArgs e)
{
// Перебираем все элементы контейнера groupBox1
// и все, кроме текстовых меток, делаем недоступными
foreach(Control box in groupBox1.Controls)
{
String type = box.GetType().ToString();
// Выделяем чистый тип без пути
type = type.Substring(type.LastIndexOf('.') + 1);
if( type == "Label")
continue;
else
box.Enabled = false;
}
// Открываем нужные списки параметров
// Организуем цепочку выбора
switch(comboBox1.SelectedIndex + 1)
{
case 6:
comboBox5.Enabled = true;
goto case 5;
case 5:
comboBox4.Enabled = true;
goto case 4;
case 4:
comboBox3.Enabled = true;
goto case 3;
case 3:
comboBox2.Enabled = true;
goto case 2;
case 2:
textBox2.Enabled = true;
goto case 1;
case 1:
textBox1.Enabled = true;
break;
}
}
В этом коде при каждом новом выборе пользователя в списке comboBox1 мы
вначале закрываем все списки и текстовые поля для параметров,
затем открываем нужные в зависимости от выбранного варианта.
Здесь мы вынужденно используем ,
так как синтаксис C# требует, чтобы непустое
тело каждого варианта case заканчивалось break или .
В языке C++ обязательного выполнения этого условия не требуется.
Но пустые case могут следовать друг за другом
перед первым непустым.
Задайте
кнопке значение Name = btnShow и
создайте для нее обработчик. Заполните обработчик такprivate void btnShow_Click(object sender, EventArgs e)
{
// Проверяем, выбрана ли перегрузка
if (comboBox1.Text == "")
{
MessageBox.Show("Выберите перегрузку метода Show()");
return;
}
// Проверяем, все ли параметры заданы
foreach (Control box in groupBox1.Controls)
{
String type = box.GetType().ToString();
type = type.Substring(type.LastIndexOf('.') + 1);
// Пропускаем метки и все закрытые элементы
if (type == "Label" || box.Enabled == false)
continue;
// Убираем пробелы и определяем, что незаполнено
else if (box.Text.Trim().Length <= 0)
{
MessageBox.Show("Задайте все необходимые параметры");
return;
}
}
// Формируем массивы ссылок на перечисления
MessageBoxButtons[] buttons = {
MessageBoxButtons.AbortRetryIgnore,
MessageBoxButtons.OK,
MessageBoxButtons.OKCancel,
MessageBoxButtons.RetryCancel,
MessageBoxButtons.18_23No,
MessageBoxButtons.18_23NoCancel
};
MessageBoxIcon[] icon = {
MessageBoxIcon.Asterisk,
MessageBoxIcon.Error,
MessageBoxIcon.Exclamation,
MessageBoxIcon.Hand,
MessageBoxIcon.Information,
MessageBoxIcon.None,
MessageBoxIcon.Question,
MessageBoxIcon.Stop,
MessageBoxIcon.Warning
};
MessageBoxDefaultButton[] defaultButton = {
MessageBoxDefaultButton.Button1,
MessageBoxDefaultButton.Button2,
MessageBoxDefaultButton.Button3
};
MessageBoxOptions[] options = {
MessageBoxOptions.DefaultDesktopOnly,
MessageBoxOptions.RightAlign,
MessageBoxOptions.RtlReading,
MessageBoxOptions.ServiceNotification
};
// Безопасно отображаем простое диалоговое окно сообщений
try
{
switch (comboBox1.SelectedIndex)
{
case 0:
MessageBox.Show(textBox1.Text);
break;
case 1:
MessageBox.Show(textBox1.Text, textBox2.Text);
break;
case 2:
MessageBox.Show(textBox1.Text, textBox2.Text,
buttons[comboBox2.SelectedIndex]);
break;
case 3:
MessageBox.Show(textBox1.Text, textBox2.Text,
buttons[comboBox2.SelectedIndex],
icon[comboBox3.SelectedIndex]);
break;
case 4:
MessageBox.Show(textBox1.Text, textBox2.Text,
buttons[comboBox2.SelectedIndex],
icon[comboBox3.SelectedIndex],
defaultButton[comboBox4.SelectedIndex]);
break;
case 5:
MessageBox.Show(textBox1.Text, textBox2.Text,
buttons[comboBox2.SelectedIndex],
icon[comboBox3.SelectedIndex],
defaultButton[comboBox4.SelectedIndex],
options[comboBox5.SelectedIndex]);
break;
}
}
catch (System.Exception exc)
{
MessageBox.Show("Внимательно проверьте параметры метода!"
+ Environment.NewLine
+ exc.Message,
"Ошибка",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
}
Здесь мы применили операторы try ( попытка )
... catch ( ловушка ),
которые позволяют сделать код более безопасным.
И последнее, что необходимо сделать для вкладки MessageBox,
- запретить редактирование списков пользователем. Здесь мы
полностью этого не достигнем, поскольку клавиша всегда остается
доступной для редактирования поля списка ComboBox.
Выделите
все раскрывающиеся списки ComboBox в контейнере groupBox1 (текстовые
поля не трогайте!) и задайте вручную для
их события KeyPress имя
обработчика lockBox_KeyPress,
который заполните так// Запрещаем раскрывающиеся списки для редактирования
private void lockBox_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
e.Handled = true;
}
Заключите
код для вкладки MessageBox в секционные
скобки для удобства редактирования#region Вкладка MessageBox
..............................................
#endregion
Постройте
приложение и испытайте работу вкладки MessageBox. Все должно
работать, как мы задумали.Этап
Не стесняйтесь советываться
с пользователями на всех стадиях разработки, выпытывайте
все, что вам может помочь. Чувствуя себя соучастниками, они
с удовольствием будут вам помогать. Прикидывайтесь несведующими
в их
Классы System.Windows.Forms.OpenFileDialog и System.Windows.Forms.SaveFileDialog являются
законченными ( sealed ) классами, поэтому не
могут иметь потомков. Зато общим предком для этих двух классов
является System.Windows.Forms.FileDialog,
который передает им много полезных общих свойств настройки.
| Свойство | Тип | Пояснения |
|---|---|---|
AddExtension |
bool |
Получает или устанавливает флаг, указывающий, должно
ли диалоговое окно автоматически добавляь расширение к
имени файла, если пользователь опускает расширение при
ручном вводе имени файла. Значение по умолчанию true -
должно |
CheckFileExists |
bool |
Получает или устанавливает флаг, указывающий, отображает
ли диалоговое false - не отображает |
CheckPathExists |
bool |
Получает или устанавливает флаг, указывающий, отображает
ли диалоговое true - отображает |
DefaultExt |
string |
Получает или устанавливает заданное по умолчанию расширение имени файла. По умолчанию - пустая строка |
DereferenceLinks |
bool |
Получает или устанавливает флаг, указывающий, возвращает
ли диалоговое окно в свойстве местоположение файла,
который адресуется ярлыком, или возвращает местоположение
самого ярлыка (.lnk). Значение по умолчанию true - местоположение
адресуемого |
|
string |
Получает или устанавливает строку, содержащую имя файла, выбранное в диалоговом окне. До выбора по умолчанию - пустая строка |
FileNames |
string[ ] |
Получает имена всех файлов, выбранных в диалоговом окне OpenFileDialog, если его свойство Multiselect равно true |
|
string |
Получает или устанавливает строку фильтров, содержащую варианты расширений файлов, доступных для выбора в диалоговом окне |
FilterIndex |
int |
Получает или устанавливает индекс текущего фильтра, установленного в диалоговом окне. По умолчанию 1 - действует первый фильтр |
InitialDirectory |
string |
Получает или устанавливает начальный каталог, отображенный диалоговым окном. По умолчанию - пустая строка |
RestoreDirectory |
bool |
Получает или устанавливает флаг, указывающий, восстанавливает
ли диалоговое окно false - не восстанавливать
первоначальный каталог, а запоминать новый каталог в системном
реестре |
ShowHelp |
bool |
Получает или устанавливает флаг, указывающий, отображена
ли кнопка false -
не включать кнопку |
SupportMultiDottedExtensions |
bool |
Получает или устанавливает флаг, указывающий, поддерживает ли диалоговое окно многоточечные (составные) расширения |
Title |
string |
Получает или устанавливает заголовок диалогового окна |
ValidateNames |
bool |
Получает или устанавливает флаг, указывающий, принимает
ли диалоговое окно только правильные (допустимые) имена
файлов true - принимает только
правильные имена файлов |
Следует помнить, что при перемещении по каталогам через OpenFileDialog или SaveFileDialog,
если не была выбрана кнопка отмены, меняется RestoreDirectory=false ).
Установить начальный каталог диалогового окна или восстановить
InitialDirectory и RestoreDirectory.
Хотя большинство пользователей перемещается по каталогам и
выбирает файлы из предложенного, кто-то может ввести имя файла
или каталога вручную. В этом случае, если подняты флаги CheckFileExists и CheckPathExists,
перед закрытием диалоговое окно само проверяет допустимость пути
или имени файла и выдает соответствующее сообщение.
Фильтры в свойстве следуют парами
друг за другом " Название
фильтра|шаблон_фильтра ". Разделитель "Вертикальная
черта" используется как внутри пары, отделяя видимое название
фильтра от шаблона, так и между парами. Строка фильтра должна
быть непрерывной. В шаблонах_фильтра не
должно быть пробелов ни внутри, ни в окружении, иначе фильтр не сработает. Особенно нужно проверять, чтобы в
последнем шаблоне строки фильтра не остался невидимый пробел.
Кроме свойств, унаследованных от класса FileDialog,
класс OpenFileDialog расширяется своими индивидуальными
свойствами. Вот они
| Свойство | Тип | Пояснения |
|---|---|---|
CheckFileExists |
bool |
Получает или устанавливает флаг, указывающий, отображает
ли диалоговое FileDialog. Значение
по умолчанию true - проверяет и отображает |
Multiselect |
bool |
Получает или устанавливает флаг, разрешающий пользователю
множественный выбор файлов с помощью клавиш Ctrl или Shift.
Значение по умолчанию false - одиночный выбор |
ShowReadOnly |
bool |
Определяет, показывать ли в диалоговом окне флажок "Только
чтение", или показан ли он.
Значение по умолчанию false - не показывать |
ReadOnlyChecked |
bool |
Определяет, установил ли пользователь показанный флажок "Только чтение" |
Если нужно разрешить пользователю создать новый файл при
помощи OpenFileDialog, следует установить CheckFileExists в
значение false.
Кратко ознакомившись со свойствами диалогового
окна OpenFileDialog, далее продемонстрируем
некоторые возможности по использованию стандартного
диалога FileDialog,
реализуем чуть позже, во вкладке SaveFileDialog,
поскольку оба диалога работы с файлами имеют общего родителя.
Поместите
на вкладку OpenFileDialog приложения контейнер Panel и
две кнопки Button вне контейнера PanelКнопки помещайте так: удерживая клавишу Ctrl, щелкните на компоненте Button вкладки Common Controls панели Toolbox. Не отпускайте клавишу Ctrl и щелкните два раза на вкладке редактируемой формы вне элемента Panel и справа от него. Щелкните на компоненте Pointer вкладки Common Controls, чтобы освободить курсор.
Установите
для компонента Panel свойство Dock в значение Left
Поместите
внутрь контейнера Panel компонент TextBox
Добавьте
к форме компоненты OpenFileDialog и SaveFileDialog,
которые оболочка разместит в подвале формы как невизуальные
Задайте
свойства новых элементов так| Элемент | Свойство | Значение |
|---|---|---|
TextBox |
Name |
txtSimpleEdit |
|
Text |
Пусто |
|
Multiline |
True |
|
|
Fill |
|
ScrollBars |
Both |
|
|
False |
|
MaxLength |
60000 |
Button |
Name |
btnOpenFile |
|
|
true |
|
Text |
Open |
Button |
Name |
btnSaveFile |
|
|
true |
|
Text |
Save |
OpenFileDialog |
Name |
openFileDialog |
|
|
Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.* |
|
Title |
Открыть текстовый файл |
SaveFileDialog |
Name |
saveFileDialog |
Создайте
обработчики для кнопок btnOpenFile и btnSaveFile,
которые заполните так#region Вкладка OpenFileDialog
String fileName = ""; // Имя текстового файла
StreamReader readFile; // Дескриптор файла
private void btnOpenFile_Click(object sender, EventArgs e)
{
openFileDialog.FileName = String.Empty; // Очищаем текстовое поле
DialogResult result = openFileDialog.ShowDialog();
if (result == DialogResult.OK)
{
try // Попытка
{
fileName = openFileDialog.FileName;// Сохранить имя файла
readFile = new StreamReader(fileName);// Открыть поток
txtSimpleEdit.Text = readFile.ReadToEnd();// Читать до конца
}
catch // Перехват всех исключений
{
MessageBox.Show("Не могу открыть файл\n",
"Ошибка",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
finally // Выполняется в любом случае
{
readFile.Close();
}
}
}
StreamWriter writeFile; // Дескриптор файла
private void btnSaveFile_Click(object sender, EventArgs e)
{
// Динамические настройки
saveFileDialog.Title = "Сохранить текстовый файл";
saveFileDialog.Filter = "Текстовые файлы (*.txt)|*.txt";
// Если не открывали и не сохраняли, то открыть диалог
if (fileName.Length <= 0)
{
DialogResult result = saveFileDialog.ShowDialog();
if (result == DialogResult.OK)
{
fileName = saveFileDialog.FileName;// Сохранить имя файла
}
else
return;
}
try
{
writeFile = new StreamWriter(fileName);// Открыть поток
writeFile.Write(txtSimpleEdit.Text);// Сохранить все
}
catch
{
MessageBox.Show("Не могу сохранить текст\n",
"Ошибка",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
finally
{
writeFile.Close();
}
}
#endregion
Здесь мы снова применили блоки для отлавливания исключений, причем любых.
В начале
файла StandardDialogs.cs пропишите инструкциюusing System.IO;
чтобы подключить пространство имен с классами ввода-вывода
Обратите внимание, что мы заключили
код для вкладки OpenFileDialog в секционные
скобки #... #endregion для
удобства редактирования
Постройте
приложение и испытайте работу вкладки OpenFileDialog.
Внешне она должна выглядеть примерно так
Обратите внимание, что после закрытия приложения и повторном
его запуске стандартное диалоговое окно OpenFileDialog открывается
в каталоге последнего загруженного файла. Это происходит потому,
что путь к выбранному
в конечном итоге каталогу OpenFileDialog каждый
раз автоматически сохраняет в системном реестре.
Метод ShowDialog() возвращает одно из значений
перечисления System.Windows.Forms.DialogResult,
которое соответствует выбранной пользователем кнопке в этом
диалоговом окне. В зависимости от этого наш код может принимать
то или иное решение о дальнейших действиях.
Кроме свойств, унаследованных от класса FileDialog,
класс SaveFileDialog расширяется своими индивидуальными
свойствами. Вот они
| Свойство | Тип | Пояснения |
|---|---|---|
CreatePrompt |
bool |
Получает или устанавливает флаг, определяющий, должно ли диалоговое окно запрашивать у пользователя разрешение создать файл, если пользователь указал имя файла, который не существует. Значение по умолчанию равно false - не запрашивать, а сразу записывать в новый файл |
OverwritePrompt |
bool |
Получает или устанавливает флаг, определяющий, отображать
ли предупреждение, если пользователь
указал имя файла, который уже существует. Значение по умолчанию
равно true - запрашивать подтверждение на перезапись содержимого
существующего файла |
При разработке вкладки OpenFileDialog мы
в режиме проектирования уже добавили к приложению экземпляр
класса SaveFileDialog и оболочка сохранила
ссылку на него как saveFileDialog.
В обработчике btnSaveFile_Click() события Click кнопки
мы использовали этот экземпляр и динамически настраивали
его свойства. В новой вкладке SaveFileDialog мы
будем использовать тот же самый объект saveFileDialog,
но будем запускать его каждый раз с новыми настройками. Для
того, чтобы вернуться к первоначальным настройкам, а затем
программно применить новые, каждый раз нужно использовать
метод этого
объекта для восстановления настроек по умолчанию.
Сначала мы оформим интерфейс вкладки изучения настроек диалогового
окна SaveFileDialog, а потом определим ее
функциональность. На самой вкладке мы определим список флажков,
устанавливающих булевы свойства диалогового окна SaveFileDialog,
ряд текстовых полей, устанавливающих значения строковых свойств,
и кнопку вызова диалогового окна с установленными настройками.
Никакого кода записи в выбранные файлы мы писать не будем,
а только познакомимся с функциональностями самого диалогового
окна.
Оформите
вкладку SaveFileDialog в соответствии со
снимком. Список флажков checkedListBox заполните
через коллекцию Items строго по названиям
свойств класса FileDialog, поскольку далее они будут участвовать в
коде
Для
всех трех кнопок вкладки создайте обработчики события Click,
оберните их секцией #region , чтобы с учетом
#region Вкладка SaveFileDialog
private void btnBrowseFileName_Click(object sender, EventArgs e)
{
openFileDialog.CheckFileExists = false;
openFileDialog.CheckPathExists = false;
openFileDialog.ShowDialog();
String str =openFileDialog.FileName;
txtFileName.Text = str;
txtInitialDirectory.Text = Path.GetDirectoryName(str);
}
private void btnShowDialog_Click(object sender, EventArgs e)
{
CheckToSaveFileDialog(); // Настраиваем окно
saveFileDialog.ShowDialog();// Показать окно
SaveFileDialogToCheck(); // Обновить интерфейс
}
private void btnReset_Click(object sender, EventArgs e)
{
// Сбрасываем состояние диалогового окна
// в значения по умолчанию
saveFileDialog.Reset();
SaveFileDialogToCheck();
}
void CheckToSaveFileDialog()
{
// Корректируем диапазон значений NumericUpDown
filterIndex.Minimum = 1;
filterIndex.Maximum = txtFilter.Text.Split('|').Length / 2;
// Устанавливаем булевы свойства
saveFileDialog.AddExtension =
checkedListBox.GetItemChecked(
checkedListBox.Items.IndexOf("AddExtension"));
saveFileDialog.CheckFileExists =
checkedListBox.GetItemChecked(
checkedListBox.Items.IndexOf("CheckFileExists"));
saveFileDialog.CheckPathExists =
checkedListBox.GetItemChecked(
checkedListBox.Items.IndexOf("CheckPathExists"));
saveFileDialog.DereferenceLinks =
checkedListBox.GetItemChecked(
checkedListBox.Items.IndexOf("DereferenceLinks"));
saveFileDialog.RestoreDirectory =
checkedListBox.GetItemChecked(
checkedListBox.Items.IndexOf("RestoreDirectory"));
saveFileDialog.ShowHelp =
checkedListBox.GetItemChecked(
checkedListBox.Items.IndexOf("ShowHelp"));
saveFileDialog.ValidateNames =
checkedListBox.GetItemChecked(
checkedListBox.Items.IndexOf("ValidateNames"));
saveFileDialog.CreatePrompt =
checkedListBox.GetItemChecked(
checkedListBox.Items.IndexOf("CreatePrompt"));
saveFileDialog.OverwritePrompt =
checkedListBox.GetItemChecked(
checkedListBox.Items.IndexOf("OverwritePrompt"));
// Устанавливаем свойства из полей интерфейса
saveFileDialog.DefaultExt = txtDefaultExt.Text;
saveFileDialog.FileName = txtFileName.Text;
saveFileDialog.Filter = txtFilter.Text;
saveFileDialog.FilterIndex = (int)filterIndex.Value;
saveFileDialog.InitialDirectory = txtInitialDirectory.Text;
saveFileDialog.Title = txtTitle.Text;
}
void SaveFileDialogToCheck()
{
// Настраиваем список флажков интерфейса
// в соответствии со свойствами
checkedListBox.SetItemChecked(
checkedListBox.Items.IndexOf("AddExtension"),
saveFileDialog.AddExtension);
checkedListBox.SetItemChecked(
checkedListBox.Items.IndexOf("CheckFileExists"),
saveFileDialog.CheckFileExists);
checkedListBox.SetItemChecked(
checkedListBox.Items.IndexOf("CheckPathExists"),
saveFileDialog.CheckPathExists);
checkedListBox.SetItemChecked(
checkedListBox.Items.IndexOf("DereferenceLinks"),
saveFileDialog.DereferenceLinks);
checkedListBox.SetItemChecked(
checkedListBox.Items.IndexOf("RestoreDirectory"),
saveFileDialog.RestoreDirectory);
checkedListBox.SetItemChecked(
checkedListBox.Items.IndexOf("ShowHelp"),
saveFileDialog.ShowHelp);
checkedListBox.SetItemChecked(
checkedListBox.Items.IndexOf("ValidateNames"),
saveFileDialog.ValidateNames);
checkedListBox.SetItemChecked(
checkedListBox.Items.IndexOf("CreatePrompt"),
saveFileDialog.CreatePrompt);
checkedListBox.SetItemChecked(
checkedListBox.Items.IndexOf("OverwritePrompt"),
saveFileDialog.OverwritePrompt);
// Настроиваем те поля интерфейса, которые можно изменить в окне
// txtDefaultExt.Text = saveFileDialog.DefaultExt;
txtFileName.Text = saveFileDialog.FileName;
// txtFilter.Text = saveFileDialog.Filter;
// filterIndex.Value = saveFileDialog.FilterIndex;
// txtInitialDirectory.Text = saveFileDialog.InitialDirectory;
// txtTitle.Text = saveFileDialog.Title;
}
#endregion
Запустите
приложение и испытайте работу вкладки SaveFileDialog
Разберитесь
в коде...Мы программируем большую задачу по изучению стандартных диалогов
и весь код размещаем в двух файлах: StandardDialogs.cs и StandardDialogs.Designer.cs.
Для обозримости мы коды для отдельных вкладок упаковали в секции #. Но у нас осталось еще много диалогов,
поэтому для удобства разместим эти секции в отдельных файлах
как отдельные части одного класса StandardDialogs.
В панели Solution Explorer вызовите для корневого
узла проекта контекстное меню и командой Add/New
Item добавьте
новый пустой файл с именем MessageBox.cs
Откройте
файл StandardDialogs.cs в режиме View
Em, выполните
команду меню Edit/Select All и скопируйте все
содержимое в
новый файл MessageBox.cs
В файле MessageBox.cs вызовите для рабочей области
контекстное меню и выполните команду Outlining/Collapse
to Definitions,
чтобы свернуть все секции кода
Отредактируйте
файл MessageBox.cs так, чтобы в свернутом
состоянии он выглядел следующим образом (убрали базовый класс
Form и ключевое слово public в объявлении класса)
В панели Solution Explorer сделайте две
копии теперь уже файла MessageBox.cs и
присвойте им имена OpenFileDialog.cs, SaveFileDialog.cs
Щелкните
правой кнопкой мыши на вкладке StandardDialogs.cs редактора
и выполните команду Close All But This, чтобы закрыть все
иные ненужные вкладки
Выбирайте
поочередно в файле StandardDialogs.cs свернутые
коды для соответствующих вкладок и перенесите (в
новое скопировать, а в старом убрать) в свои одноименные
файлы как члены частичного класса, открывая файлы в режиме View
Em.
В файле StandardDialogs.cs должен
остаться только код для вкладки "Обзор"
В панели Solution
Explorer щелкните правой кнопкой мыши на корневом
узле проекта и командой Add/New Folder добавьте
новую папку с именем ItemsDialogs
Удерживая
клавишу Ctrl, выделите файлы MessageBox.cs, OpenFileDialog.cs, SaveFileDialog.cs и
мышью переместите их в новую папку
Выполните
команду меню Window/Close All Documents, чтобы закрыть все
редактируемые файлы
Запустите
приложение и убедитесь, что работоспособность его не изменилась,
но код расфасован удобнееДиалоговое окно ColorDialog порождается классом System.Windows.Forms.ColorDialog. Оно позволяет
выбрать цвет, который содержится в свойстве Color типа System.Drawing.Color и может открываться в
обычном или расширенном варианте.
Несколько других свойств типа управляют
различными настройками диалогового окна ColorDialog.
Вот они
| Свойство | Тип | Пояснения |
|---|---|---|
Color |
System.Drawing.Color |
Выбранный пользователем цвет |
AllowFullOpen |
bool |
При значении true, установленном по умолчанию, окно готово раскрываеться в расширенном варианте с возможностью выбора любых дополнительных цветов |
AnyColor |
bool |
Любой цвет |
FullOpen |
bool |
Раскрывается в расширенном варианте |
SolidColorOnly |
bool |
Только основные цвета |
ShowHelp |
bool |
Отобразить кнопку справки |
CustomColors |
int[ ] |
Массив дополнительных цветов |
Булевыми значениями этих публичных свойств мы и будем управлять
из вкладки ColorDialog.
Поместите
на вкладку ColorDialog необходимые элементы
управления и настройте их в соответствии с таблицей| Элемент | Свойство | Значение |
|---|---|---|
Panel |
Name |
panelColorDialog |
|
|
Left |
|
|
Fixed3D |
Label |
Name |
lblColorDialog |
|
Text |
Булевы свойства диалога ColorDialog: |
|
TextAlign |
MiddleCenter |
|
Name |
AllowFullOpen |
|
Text |
AllowFullOpen |
|
Checked |
true |
|
Name |
AnyColor |
|
Text |
AnyColor |
|
Name |
FullOpen |
|
Text |
FullOpen |
|
Name |
SolidColorOnly |
|
Text |
SolidColorOnly |
|
Name |
ShowHelp |
|
Text |
ShowHelp |
Label |
Name |
lblColorTitle |
|
Text |
Наименование выбранного цвета: |
Label |
Name |
lblColorName |
|
Text |
DefaultColor |
|
|
true |
Button |
Name |
btnResetColorDialog |
|
|
true |
|
Text |
|
Button |
Name |
btnShowColorDialog |
|
|
true |
|
Text |
Show |
В итоге пользовательский интерфейс вкладки должен выглядеть примерно так

Из
панели Toolbox поместите на форму двойным
щелчком компонент ColorDialog и присвойте
ему имя colorDialog
Создайте
для кнопки Show обработчик с именем btnShowColorDialog_Click
Создайте
для кнопки Reset обработчик с именем btnResetColorDialog_Click
Упакуйте
обработчики в секцию #region Вкладка ColorDialog...#endregion
Через
панель Solution Explorer создайте в папке ItemsDialogs копию
файла SaveFileDialog.cs и присвойте ей имя ColorDialog.cs
Разместите
в файле ColorDialog.cs секцию #region с
заготовками обработчиков btnShowColorDialog_Click и btnResetColorDialog_Click, автоматически
помещенными оболочкой при создании в основную часть класса
в файле StandardDialogs.cs,
и заполните их кодом. Общее содержимое файла ColorDialog.cs должно
быть примерно такимusing System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
namespace FormsApp
{
partial class StandardDialogs
{
#region Вкладка ColorDialog
// Поле для хранения дополнительных цветов
int[] customColors = new int[16]
{
0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF
};
private void btnShowColorDialog_Click(object sender, EventArgs e)
{
// Создаем совершенно новое диалоговое окно
ColorDialog dlg = new ColorDialog();
// Настраиваем диалоговое окно
dlg.CustomColors = customColors;
foreach (Control ctrl in this.tabPage4.Controls)
{
// Ищем наши флажки на дочерней вкладке
if (ctrl is CheckBox)
{
// Позиционируемся по имени флажка
switch (ctrl.Name.ToString())
{
case "AllowFullOpen":
dlg.AllowFullOpen = ((CheckBox)ctrl).Checked;
break;
case "AnyColor":
dlg.AnyColor = ((CheckBox)ctrl).Checked;
break;
case "FullOpen":
dlg.FullOpen = ((CheckBox)ctrl).Checked;
break;
case "SolidColorOnly":
dlg.SolidColorOnly = ((CheckBox)ctrl).Checked;
break;
case "ShowHelp":
dlg.ShowHelp = ((CheckBox)ctrl).Checked;
break;
}
}
}
// Инициируем предыдущий цвет
dlg.Color = panelColorDialog.BackColor;
// Показываем диалоговое окно и извлекаем
// выбранный пользователем цвет
if (dlg.ShowDialog() == DialogResult.OK)
{
panelColorDialog.BackColor = dlg.Color;
lblColorName.Text = dlg.Color.Name;
// Сохранить выбор дополнительных цветов
customColors = dlg.CustomColors;
}
}
private void btnResetColorDialog_Click(object sender, EventArgs e)
{
// Создаем псевдоним постоянно существующего экземпляра окна
ColorDialog dlg = colorDialog;
// Восстанавливаем окно
dlg.Reset();
// Применяем рефлексию для перебора свойств в цикле
// и передачи их значений флагам интерфейса
PropertyInfo[] props =
typeof(ColorDialog).GetProperties();// Получаем все свойства
// Перебираем свойства
foreach (PropertyInfo prop in props)
{
// Выбираем только логические свойства
if (prop.PropertyType == typeof(bool))
{
// Ищем все элементы-флажки с именем свойства
// У нас только один флажок с уникальным именем
Control[] controls = this.Controls.Find(prop.Name, true);
// Извлекаем значение свойства и присваиваем флажку
((CheckBox)controls[0]).Checked =
(bool)prop.GetGetMethod().Invoke(dlg, null);
}
}
// Восстанавливаем элементы интерфейса
panelColorDialog.BackColor = dlg.Color;
lblColorName.Text = dlg.Color.Name;
}
#endregion
}
}
Свойство CustomColors содержит массив из
16 четырехбайтных целых, в которых содержаться коды дополнительных
цветов RGB -модели, представленных в окне
16 плашками. В каждом элементе массива младший байт соответствует
цвету Red, затем Green и предпоследний байт - цвету Blue.
Последний байт не используется. При RGB -байты единицами, что соответствует изначально
белому цвету.
Для демонстрации того, что механизм сохранения
дополнительных цветов работает, мы специально в обработчике
кнопки Show каждый раз создаем диалоговое
окно dlg заново и восстанавливаем в нем
сохраненные в массиве customColors дополнительные цвета.
Постоянное же диалоговое окно colorDialog мы
используем только для сброса пользовательского интерфейса.
В обработчике btnResetColorDialog_Click() мы
используем механизм отражения ( рефлексию ) для динамического
анализа свойств порождающего класса диалогового окна и извлечения
их значений из существующего объекта. Для этой цели мы подключили
пространство имен System. Элементы
флажков методом Find() мы ищем во всей форме по их именам,
совпадающим с именами свойств, и присваиваем им значения динамически
извлеченных свойств. Это сделало программу несколько запутанной,
но для большого количества элементов такой подход позволил
бы значительно сократить объем кода. Кроме того, таким образом
мы знакомимся с разными возможностями языка C#.
Запустите
приложение и испытайте работу вкладки ColorDialogНа простом примере добавления иконок к формам познакомимся
с
В панели Solution Explorer вызовите контекстное меню
для узла проекта и командой Add/New Folder создайте
новую папку с именем Resources
Вызовите
контекстное меню для папки Resources и командой Add/New
Item добавьте в нее 
Двойным
щелчком на файле Resource1.resx вызовите
графический редактор ресурсов, раскройте в его верхней части
выпадающий список Add Resource и опцией Add
Existing File добавьте в каталог 
Установите
в 
В панели Solution Explorer выделите файлы формы и
через контекстное меню откройте их в режиме View
Em
Добавьте
в конструктор каждой формы после вызова функции InitializeComponent() код
присоединения соответствующей иконки из файла ресурсов,
например, для конструктора Form1() код будет такимpublic Form1()
{
InitializeComponent();
this.Icon = Resources.Resource1.Icon1;
}
Запустите
приложение для каждой формы и убедитесь, что иконки присоединяются
к окну формы, например
Перейдите
к следующей части работы (если она уже есть)
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.