![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Перетаскивание, проверка попадания в область, занимаемую изображением. Элемент управления PictureBox
PictureBox — это класс, производный от Control, поэтому можно использовать множество событий, всплывающую подсказку, контекстное меню и прочие возможности элемента управления. Проиллюстрируем применение PictureBox на примере. Создадим приложение, которое будет захватывать события MouseUp, MouseDown и MouseMove для области, занятой на форме изображением (которое помещено в PictureBox). Добавим код для работы с перетаскиванием (drag-and-drop). Пользователь сможет перетаскивать одно из изображений по всей форме. Кроме того, будем осуществлять проверку того, где оказалось перетаскиваемое изображение после того, как пользователь его отпустит. Если оно попало в область, занимаемую заданным прямоугольником, будет выводиться специальное сообщение. Таким образом, реализуем механизм, называемый «проверкой попадания» — hit testing. Назначение объекту PictureBox изображения, которое будет в нем содержаться, выглядит следующим образом:
Свойство PictureBox, — SizeMode, для него используются значения из перечисления PictureBoxSizeMode. Это свойство позволяет определить, как именно будет выводиться изображение внутри PictureBox. В нашем случае было использовано значение StretchImage, которое означает, что изображение должно быть сжато или растянуто таким образом, чтобы полностью соответствовать размерам PictureBoх. Другие возможные значения представлены в таблице 9.8. Таблица 9.8.Значения перечисления PictureBoxSizeMode
Выберите ChooseImage для выбора изображения для отображения в PictureBox. После того как создали PictureBox и настроили его свойства, следующая задача — обеспечить обработчики для событий MouseMove, MouseUp и MouseDown. // Добавляем обработчики для следующих событий pictureBox1.MouseDown +=new MouseEventHandler(pictureBox1_MouseDown); pictureBox1.MouseUp +=new MouseEventHandler(pictureBox1_MouseUp); pictureBox1.MouseMove +=new MouseEventHandler(pictureBox1_MouseMove); this.Paint +=new PaintEventHandler(Form1_Paint); В обработчике события MouseDown, во-первых, устанавливается значение true для переменной isDragging (началась операция перетаскивания), а во-вторых, фиксируются координаты указателя мыши при наступлении этого события: // Обработчик события MouseDown для объекта PictureBox private void pictureBox1_MouseDown(Object sender, MouseEventArgs e) { isDragging = true; oldX = e.X; oldY = e.Y; } Обработчик события MouseMove обеспечивает перемещение PictureBox по форме (изменяя значения свойств Тор и Left). Для расчета нового положения PictureBox используется смещение указателя мыши относительно исходной позиции: Если пользователь производит щелчок на изображении и, не отпуская кнопку, перемещает мышь. PictureBox вместе с изображением будет перерисовываться в новой месте private void pictureBox1_MouseMove(Object sender, MouseEventArgs e) { if(isDragging) { // Определяем новые координаты для PictureBox по разности между // старым и новым положением указателя мыши pictureBox1.Top =pictureBox1.Top + (e.Y - oldY); pictureBox1.Left = pictureBox1.Left + (e.X - oldX); } } Далее обработчик события MouseUp должен установить значение переменной isDragging равным false — это признак окончания операции перетаскивания. Кроме того, по условиям задачи должна производиться проверка: если перемещаемый PictureBox отпущен внутри определенной области формы (ограниченной размерами объекта Rectangle), то пользователь добился успеха. Таким образом, весь оставшийся необходимый код выглядит следующим образом: private void pictureBox1_MouseUp(Object sender, MouseEventArgs e) { Rectangle dropRect = new Rectangle(200, 100, 350, 250); isDragging = false; if(dropRect.Contains(pictureBox1.Bounds)) MessageBox.Show(" Вы победили! ", " Проверка попадания"); } private void Form1_Paint(Object sender, PaintEventArgs e) { // Выводим " прямоугольник сбрасывания" Graphics g = e.Graphics; Rectangle dropRect = new Rectangle(200, 100, 350, 250); g.FillRectangle(Brushes.Blue, dropRect); g.DrawString(" Перетащите картинку в эту область.", this.Font, Brushes.Red, 200, 100); } Не забудьте объявить переменные перед классом формы, например, bool isDragging; int oldX, oldY; Главную роль в проверке попадания играет метод Rectangle.Contains (). Этот метод перегружен и может принимать другой прямоугольник, точку или два значения типа int в качестве координат. Этот метод удобен в ситуации, когда необходимо проверить, попал ли пользователь щелчком мыши в прямоугольную область на форме или нет. Рассмотрим следующую задачу: Если щелчок пришелся на какое-либо из изображений, заключить это изображение в красную рамку и изменить заголовок формы (это делается при помощи свойства Form.Text). Первое, необходимо обеспечить перехват события MouseDown для самой формы. После этого осуществлять проверку — попадает или нет указатель мыши в область, занимаемую одним из изображений. Если ответ положительный, то значения двух переменных изменятся: переменной IsImageClicked (типа bool) будет присвоено значение true, а переменной imag (типа int) - значение, соответствующее номеру выбранного пользователем изображения. Пример кода может быть таким: public class Form1: Form { private bool isImageclicked; private int imag; private Rectangle rectA; private Rectangle rectB; private Rectangle rectC;
public Form1() { InitializeComponent(); rectA= new Rectangle(15, 15, 125, 75); rectB = new Rectangle(15, 95, 125, 75); rectC = new Rectangle(15, 175, 125, 75); isImageclicked = false; this.MouseDown+=new MouseEventHandler(Form1_MouseDown); this.Paint +=new PaintEventHandler(Form1_Paint); } private void Form1_Paint(Object sender, PaintEventArgs e) { Graphics g= e. Graphics; Pen outline = new Pen(Color.Red, 5); // Выводим все три изображения g.FillRectangle(Brushes.Blue, 20, 20, 120, 70); g.FillRectangle(Brushes.Aqua, 20, 100, 120, 70); g.FillRectangle(Brushes.BlueViolet, 20, 180, 120, 70); // Выводим рамку (по щелчку пользователя) if(isImageclicked == true){ if (imag==0) g.DrawRectangle(outline, rectA); if (imag==1) g.DrawRectangle(outline, rectB); if (imag==2) g.DrawRectangle(outline, rectC); } } private void Form1_MouseDown(Object sender, MouseEventArgs e) { // Получаем координаты указателя мыши в момент щелчка Point mousePt = new Point(e.X, e.Y); // Проверяем, не попадает ли указатель мыши в одну из трех областей, // занимаемых изображениями. if (rectA.Contains(mousePt)) { isImageclicked = true; imag = 0; this.Text = " Вы кликнули изображение A"; } else { if (rectB.Contains(mousePt)) { isImageclicked = true; imag = 1; this.Text = " Вы кликнули изображение B"; } else if (rectC.Contains(mousePt)) { isImageclicked = true; imag = 2; this.Text = " Вы кликнули изображение C"; } else { isImageclicked = false; this.Text = " Изображения"; } } // Перерисовываем форму Invalidate(); } В приложение добавлена еще одна проверка: для щелчка мыши, который не попадает ни в одно из трех изображений. Эта проверка нужна для удаления рамки с выбранного перед этим изображения.
|