При нажатии на Сумма в примере ArbitraryMethod из Лекция 7, VS 2013 выдается ошибка: Необработанное исключение типа "System.InvalidOperationException" в System.Windows.Forms.dll Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "lblResult" не из того потока, в котором он был создан. Затем: Необработанное исключение типа "System.InvalidOperationException" в mscorlib.dll Дополнительные сведения: Для каждой асинхронной операции метод EndInvoke может вызываться только один раз. |
Работа с печатью и изображениями
Работа с изображениями. Программа Picture Viewer
Работа с изображениями — одно из самых увлекательных занятий на компьютере. Не менее интересно создавать графические программы. Во второй лекции мы сталкивались с элементом PictureBox, в который помещали рисунок для окна "О программе". Теперь мы научимся загружать в этот элемент изображения, сохранять их в другом формате и распечатывать. Создайте новое приложение и назовите его PictureViewer. Добавляем на форму меню (рис. 6.8), контекстное меню, OpenFileDialog, SaveFileDialog, PictureBox, устанавливаем следующие свойства элементов управления:
mainMenu1, Name | Text | Shortcut |
---|---|---|
mnuFile | &Файл | |
mnuOpen | &Открыть | CtrlO |
mnuSave | &Сохранить | CtrlS |
menuItem1 | — | |
mnuPageSetup | Пара&метры страницы | |
mnuPrintPreview | Пред&варительный просмотр | |
mnuPrint | &Печать | CtrlP |
mnuExit | &Exit | AltF4 |
mnuView | &Вид | |
mnuResize | &Подогнать размер | |
mnuActual | &Истинный размер | |
mnuCenterImage | &По центру | |
mnuAutoSize | &Автоматический размер |
contextMenu1, Name | Text |
---|---|
mnuResize | &Подогнать размер |
mnuActual | &Истинный размер |
mnuCenterImage | &По центру |
mnuAutoSize | &Автоматический размер |
Приложение будет отображать в элементе управления PictureBox загруженный рисунок. Добавляем обработчик пункта меню mnuOpen:
private void mnuOpen_Click(object sender, System.EventArgs e) { OpenFileDialog diag = new OpenFileDialog(); diag.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*" ; if (diag.ShowDialog() == DialogResult.OK) { pictureBox1.Image = new Bitmap(diag.OpenFile()); } }
Несмотря на определение формата jpeg в качестве основного, элемент PictureBox поддерживает также работу с форматами Bitmap (.bmp), Icon (.ico), GIF (.gif), Metafile (.wmf). Сохранения файла практически не отличается от сохранения содержимого текстового поля:
private void mnuSave_Click(object sender, System.EventArgs e) { SaveFileDialog diag = new SaveFileDialog(); diag.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*" ; if(diag.ShowDialog() != DialogResult.OK) return; // Получаем адрес файла. string filename = diag.FileName; FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite); pictureBox1.Image.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg); fs.Close(); }Листинг 6.6.
Обратите внимание на возможность конвертирования форматов — метод Save свойства предоставляет возможность сохранения содержимого PictureBox в различных форматах (рис. 6.9).
Мы выбрали формат Jpeg — при открытии рисунка в другом формате, например, Bmp, и последующем сохранении он будет конвертирован в этот формат.
Элемент управления PictureBox поддерживает несколько вариантов отображения загружаемого рисунка (рис. 6.10).
увеличить изображение
Рис. 6.10. Режимы отображения рисунка элементов PictureBox: подогнать размер (StretchImage), истинный размер (Normal), по центру (CenterImage), автоматический размер (AutoSize)
Мы установили свойству SizeMode значение StretchImage, и поэтому при открывании рисунка его размер автоматически подгоняется под размер PictureBox и, соответственно, формы. Истинный размер выводит рисунок в его действительных пропорциях; при этом на экране помещается только его часть. Конечно, в этом режиме необходима прокрутка рисунка — об этом чуть позже. Режим по центру располагает рисунок в его реальных пропорциях так, чтобы его центр совпадал с центром PictureBox. Последний режим — автоматический размер — подгоняет размеры PictureBox под размер открываемого изображения. На рис. 6.10 он визуально совпадает с режимом StretchImage — дело в том, что мы установили свойству Dock значение Fill и поэтому PictureBox уже имеет максимально большой размер.
В классе формы создадим массив ArrayMenu, в котором будут содержаться значения режимов:
private PictureBoxSizeMode[] ArrayMenu = { PictureBoxSizeMode.StretchImage, PictureBoxSizeMode.Normal, PictureBoxSizeMode.CenterImage, PictureBoxSizeMode.AutoSize };
Переменная selectedMode будет возвращать выбранное значение:
private int selectedMode = 0;
В обработчиках пунктов меню будем выбирать одно значение из массива:
private void mnuResize_Click(object sender, System.EventArgs e) { if (sender is MenuItem) { MenuItem menuitem = (MenuItem)sender; selectedMode = menuitem.Index; pictureBox1.SizeMode = ArrayMenu[0]; pictureBox1.Invalidate(); } } private void mnuActual_Click(object sender, System.EventArgs e) { if (sender is MenuItem) { MenuItem menuitem = (MenuItem)sender; selectedMode = menuitem.Index; pictureBox1.SizeMode = ArrayMenu[1]; pictureBox1.Invalidate(); } } private void mnuCenterImage_Click(object sender, System.EventArgs e) { if (sender is MenuItem) { MenuItem menuitem = (MenuItem)sender; selectedMode = menuitem.Index; pictureBox1.SizeMode = ArrayMenu[2]; pictureBox1.Invalidate(); } } private void mnuAutoSize_Click(object sender, System.EventArgs e) { if (sender is MenuItem) { MenuItem menuitem = (MenuItem)sender; selectedMode = menuitem.Index; pictureBox1.SizeMode = ArrayMenu[3]; pictureBox1.Invalidate(); } }Листинг 6.7.