Чтобы продемонстрировать пользу типа PictureBox, давайте создадим простую "игру", которая будет способна "распознать" присутствие указателя мыши на графическом изображении. При щелчке пользователя кнопкой мыши в границах изображения включается режим "перетаскивания", и пользователь может перемещать изображение по форме. Чтобы сделать ситуацию интереснее, давайте проконтролируем, где пользователь "отпустит" изображение. Если это произойдет в рамках некоторого прямоугольника визуализации GDI+, будет выполнено некоторое заданное действие (оно будет описано чуть позже). Вы, возможно, знаете, что процесс обнаружения событий мыши в заданной области называется проверкой попадания в заданную область.
Тип PictureBox наследует большинство своих функциональных возможностей от базового класса Control. Ряд членов Control был уже рассмотрен в предыдущей главе, и это позволяет нам сразу перейти к обсуждению вопроса назначения изображения члену PictureBox с помощью свойства Image (снова заметим, что файл happyDude.bmp должен находиться в каталоге приложения).
public partial class MainForm: Form {
// Содержит изображение улыбающегося лица.
private PictureBox happyBox = new PictureBox();
public MainForm() {
// Конфигурация PictureBox.
happyBox.SizeMode = PictureBoxSizeMode.StretchImage;
happyBox.Locaton = new System.Drawing.Point(64, 32);
happyBox.Size = new System.Drawing.Size(50, 50);
happyBox.Cursor = Cursors.Hand;
happyBox.Image = new Bitmap("happyDude.bmp");
// Добавление в коллекцию Controls формы.
Controls.Add(happyBox);
}
}
Кроме свойства Image, нам будет интересно только свойство SizeMode, для которого используются значения перечня PiсtureBoxSizeMode. Этот тип используется для контроля того, как соответствующее изображение должно отображаться в рамках рабочего прямоугольника PictureBox. Здесь мы используем PictureBoxSizeMode.StretchImage, означающее то, что изображение следует растянуть на всю заданную типом PictureBox область (которая в данном случае имеет размеры 50×50 пикселей).
Следующей задачей является обработка событий MouseMove.MouseUр и MouseDown для члена-переменной PictureBox с помощью вполне стандартного синтаксиса обработки событий C#.
public MainForm() {
…
// Добавление обработчиков для ряда событий.
happyBox.MouseDown += new MouseEventHandler(happyBox_MouseDown);
happyBox.MouseUp += new MouseEventHandler(happyBox_MouseUp);
happyBox.MouseMove += new MouseEventHandler(hарруВох_MouseMove);
Controls.Add(happyBox);
InitializeComponent();
}
Обработчик событий MouseDown сохраняет поступающие на вход значения координат (х, у) местоположения указателя в двух членах-переменных (oldX и oldY) для использования в дальнейшем, а также устанавливает значение true (истина) для члена-переменной (isDragging) типа System.Boolean, когда происходит перетаскивание. Добавьте эти члены-переменные в форму и реализуйте обработчик события MouseDown так, как предлагается ниже.
private void happyBox_MouseDown(object sender, MouseEventArgs e) {
isDragging = true;
oldX = e.X;
oldY = e.Y;
}
Обработчик события MouseMove просто изменяет местоположение PictureBox (с помощью свойств Тор и Left), в зависимости от сдвига положения указателя по сравнению со значениями, полученными при обработке события MouseDown.
private void happyBox_MouseMove(object sender, MouseEventArgs e) {
if (isDragging) {
// Необходимо для вычисления нового значения Y в зависимости
// от того, где была нажата кнопка мыши.
happyBox.Top = happyBox.Top + (e.Y – oldY);
// То же для X (используя в качестве основы oldX).
happyBox.Left = happyBox.Left + (e.X – oldX);
}
}
Обработчик события MouseUp устанавливает для isDragging значение false (ложь), чтобы сигнализировать об окончаний операции перетаскивания. Кроме того, если событие MouseUp происходит в тот момент, когда PictureBox содержится в пределах отображаемого средствами GDI+ Rectangle, мы будем считать, что пользователь победил в этой (очень примитивной) игре. Сначала добавьте в класс Form член Rectangle (с именем dropRect и заданными размерами).
public partial class MainForm: Form {
private PictureBox happyBox = new PictureBox();
private int oldX, oldY;
private bool isDragging;
private Rectangle dropRect = new Rectangle(100, 100, 140, 170);
…
}
Обработчик события MouseUp теперь можно реализовать так.
private void happyBox_MouseUp(object sender, MouseEventArgs e) {
isDragging = false;
// Находится ли указатель внутри заданного прямоугольника?
if (dropRect.Contains(happyBox.Bounds)) MessageBox.Show("Вы победили!", "Этот сладкий вкус умения…");
}
Читать дальше