Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# Windows Forms
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.56/16: Рейтинг темы: голосов - 16, средняя оценка - 4.56
romanroman
0 / 0 / 2
Регистрация: 24.04.2013
Сообщений: 135
1

Перетаскивание мышкой нарисованных объектов

14.10.2014, 01:40. Просмотров 3114. Ответов 10
Метки нет (Все метки)

Доброго времени суток! Как сделать перетаскивание нарисованного объекта по щелчку мыши нарисованного с помощью метода DrawEllipse класса Rectangle?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.10.2014, 01:40
Ответы с готовыми решениями:

Перетаскивание нарисованных объектов
using System; using System.Collections.Generic; using System.ComponentModel;...

Перемещение мышкой нарисованных объектов
Помогите мне пожалуйста. Мне нужно чтобы нарисованный в программе прямоугольник...

Метод коэна сазерленда: сделать перетаскивание квадрата мышкой
Подскажите как реализовать что бы этот метод.Нашел такой код ,не могу сделать...

Перетаскивание объектов
Всем привет) Пишу программу которая рисует схемы сети(картинка снизу), хочу...

Перетаскивание объектов на форме, исправить код
Доброго времени суток. Вот такой код : public Form1() {...

10
jetyb
170 / 168 / 73
Регистрация: 26.10.2012
Сообщений: 513
Завершенные тесты: 1
14.10.2014, 08:25 2
У графического контейнера (на чем рисуете) должны быть события
MouseDown, MouseMove и MouseUp.
На MouseDown надо проверять попадание мыши в фигуру и входить в режим переноса
На MouseMove - перетаскивать объект (можно не перерисовывать картинку( недостаток WinForms) а менять тип курсора на фигуру.
На MouseUp - окончательбно изменять к-ты фигуры и выходить из режима перетаскивания.

Вообще для этого лучше подходит Wpf
0
ViterAlex
6822 / 3797 / 1552
Регистрация: 11.02.2013
Сообщений: 8,343
Завершенные тесты: 3
14.10.2014, 08:37 3
jetyb, менять курсор на изображение фигуры, это нетривиальная идея. Спасибо.
Предложу реализацию почти того, что написал jetyb. Объекты хранятся в списке. Сами объекты представляют собой класс, хранящий информацию о форме объекта (GraphicsPath) и о пере, которым объект нарисован.
Класс формы
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
 
namespace PaintedObjectsMoving {
    public partial class MainForm : Form {
        List<PaintedObject> list;//Список с объектами для прорисовки
        PaintedObject currObj;//Объект, который в данный момент перемещается
        Point oldPoint;
        Bitmap bmp;
        public MainForm() {
            InitializeComponent();
            list = new List<PaintedObject>();
            bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
            //Заполнение списка случайными объектами для прорисовки
            Init();
            //Обновление битмапа
            RefreshBitmap();
            this.DoubleBuffered = true;
            this.MouseDown += Form1_MouseDown;
            this.MouseUp += Form1_MouseUp;
            this.MouseMove += Form1_MouseMove;
            this.Paint += Form1_Paint;
        }
 
        void Form1_Paint(object sender, PaintEventArgs e) {
            if (bmp == null) return;
            RefreshBitmap();
            e.Graphics.DrawImage(bmp, 0, 0);
        }
 
        void Form1_MouseMove(object sender, MouseEventArgs e) {
            switch (e.Button) {
                case MouseButtons.Left:
                    //Считаем смещение курсора
                    int deltaX, deltaY;
                    deltaX = e.Location.X - oldPoint.X;
                    deltaY = e.Location.Y - oldPoint.Y;
                    //Смещаем нарисованный объект
                    currObj.Path.Transform(new Matrix(1, 0, 0, 1, deltaX, deltaY));
                    //Запоминаем новое положение курсора
                    oldPoint = e.Location;
                    break;
                default:
                    break;
            }
            //Обновляем форму
            this.Refresh();
        }
 
        void Form1_MouseUp(object sender, MouseEventArgs e) {
            currObj.Pen.Width -= 1;//Возвращаем ширину пера
            currObj = null;//Убираем ссылку на объект
        }
 
        void Form1_MouseDown(object sender, MouseEventArgs e) {
            //Запоминаем положение курсора
            oldPoint = e.Location;
            //Ищем объект, в который попала точка. Если таких несколько, то найден будет первый по списку
            foreach (PaintedObject po in list) {
                if (po.Path.GetBounds().Contains(e.Location)) {
                    currObj = po;//Запоминаем найденный объект
                    currObj.Pen.Width += 1;//Делаем перо жирнее
                    return;
                }
            }
        }
        void RefreshBitmap() {
            if (bmp != null) bmp.Dispose();
            bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
            //Прорисовка всех объектов из списка
            using (Graphics g = Graphics.FromImage(bmp)) {
                foreach (PaintedObject po in list) {
                    g.DrawPath(po.Pen, po.Path);
                }
            }
        }
 
        void Init() {
            PaintedObject po;
            Random rnd = new Random(DateTime.Now.Millisecond);
            int w = this.ClientSize.Width,
                w1 = this.ClientSize.Width / 2,
                h = this.ClientSize.Height,
                h1 = this.ClientSize.Height / 2;
            for (int i = 0; i < 5; i++) {
                po = new PaintedObject(new Pen(Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256))), new GraphicsPath());
                po.Path.AddEllipse(Rectangle.FromLTRB(rnd.Next(w1), rnd.Next(h1), rnd.Next(w1, w), rnd.Next(h1, h)));
                list.Add(po);
            }
        }
    }
}

Класс PaintedObject
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
 
namespace PaintedObjectsMoving {
    class PaintedObject : ICloneable {
        private GraphicsPath path;
 
        public GraphicsPath Path {
            get { return path; }
            set { path = value; }
        }
        private Pen pen;
 
        public Pen @Pen {
            get { return pen; }
            set { pen = value; }
        }
        public PaintedObject(Pen pen, GraphicsPath path) {
            this.path = path;
            this.pen = pen;
        }
 
        #region ICloneable Members
 
        public object Clone() {
            return new PaintedObject(this.Pen, this.Path.Clone() as GraphicsPath);
        }
 
        #endregion
    }
}

Весь проект — во вложении
3
Вложения
Тип файла: zip sourceCode.zip (15.1 Кб, 109 просмотров)
romanroman
0 / 0 / 2
Регистрация: 24.04.2013
Сообщений: 135
15.10.2014, 13:54  [ТС] 4
а если допустим, у меня есть методы "выбор и рисование" и "рисования прямоугольника", и я хочу сначала нарисовать, а потом перетащить фигуру, например, как в paint
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  // Выбор и рисование фигур
        private void DrawFigure(Rectangle r, Graphics g)
        {
            switch (figureMode)
            {
                case 0:
                    if (!checkBox1.Checked)
                        g.FillRectangle(brush, r);
                    g.DrawRectangle(pen, r);
                    break;
                case 1:
                    if (!checkBox1.Checked)
                        g.FillEllipse(brush, r);
                    g.DrawEllipse(pen, r);
                    break;
            }
        }
        // метод рисования прямоугольника
        private Rectangle PtToRect(Point p1, Point p2)
        {
            if (equalSize)
            {
                int dx = p2.X - p1.X, dy = p2.Y - p1.Y;
                if (Math.Abs(dx) > Math.Abs(dy))
                    p2.X = p1.X + Math.Sign(dx) * Math.Abs(dy);
                else
                    p2.Y = p1.Y + Math.Sign(dy) * Math.Abs(dx);
            }
            int x = Math.Min(p1.X, p2.X),
                y = Math.Min(p1.Y, p2.Y),
                w = Math.Abs(p2.X - p1.X),
                h = Math.Abs(p2.Y - p1.Y);
            return new Rectangle(x, y, w, h);
        }
0
tarasalk
1225 / 734 / 292
Регистрация: 13.06.2013
Сообщений: 2,589
15.10.2014, 14:20 5
romanroman, храните вашу фигуру в массиве точек. Потом когда перемещаете мышку, вы запоминаете насколько ее перенесли. Например на 5 вправо, тогда все точки в массиве тоже надо перенести на 5 вправо. Ну и соответственно перерисовать.
Понятное дело, чтобы получилось что то вменяемое, нужно хорошенько продумать архитектуру. Вот у ViterAlex вроде как раз что то подобное.
0
romanroman
0 / 0 / 2
Регистрация: 24.04.2013
Сообщений: 135
15.10.2014, 14:27  [ТС] 6
tarasalk, в теории я понял как это сделать, только вот на практике это не получается реализовать, вот проект, может быть вы поможете решить данную проблему
0
Вложения
Тип файла: rar Paint1.rar (507.2 Кб, 38 просмотров)
romanroman
0 / 0 / 2
Регистрация: 24.04.2013
Сообщений: 135
15.10.2014, 17:50  [ТС] 7
Может кто нибудь помочь?
0
ViterAlex
6822 / 3797 / 1552
Регистрация: 11.02.2013
Сообщений: 8,343
Завершенные тесты: 3
15.10.2014, 18:16 8
Уже помогли. Я дополню свой класс методом добавления прямоугольника. Тебе останется:
  1. Создать экземпляр класса PaintedObject
  2. Добавить прямоугольник, который ты рисуешь
  3. Перемещать его как я показал в своём примере.
Класс PaintedObject
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
 
namespace PaintedObjectsMoving {
    class PaintedObject : ICloneable {
        private GraphicsPath path;
 
        public GraphicsPath Path {
            get { return path; }
            set { path = value; }
        }
        private Pen pen;
 
        public Pen @Pen {
            get { return pen; }
            set { pen = value; }
        }
        public PaintedObject() {
            this.path = new GraphicsPath();
            this.pen = Pens.Black;
        }
 
        public PaintedObject(Pen pen, GraphicsPath path) {
            this.path = path.Clone() as GraphicsPath;
            this.pen = pen.Clone() as Pen;
        }
 
        public void AddRectangle(Rectangle rect) {
            if (path == null)
                path = new GraphicsPath();
            path.AddRectangle(rect);
        }
 
        #region ICloneable Members
 
        public object Clone() {
            return new PaintedObject(this.Pen.Clone() as Pen, this.Path.Clone() as GraphicsPath);
        }
 
        #endregion
    }
}

Пример использования:
C#
1
2
PaintedObject po = new PaintedObject();
po.AddRectangle(твой прямоугольник);
1
romanroman
0 / 0 / 2
Регистрация: 24.04.2013
Сообщений: 135
15.10.2014, 21:33  [ТС] 9
ViterAlex, я все сделал, как ты писали,но фигуры не перетаскиваются
0
ViterAlex
6822 / 3797 / 1552
Регистрация: 11.02.2013
Сообщений: 8,343
Завершенные тесты: 3
15.10.2014, 22:30 10
Где то, что ты сделал?
0
romanroman
0 / 0 / 2
Регистрация: 24.04.2013
Сообщений: 135
16.10.2014, 00:22  [ТС] 11
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
using System;
using System.Drawing.Drawing2D;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Printing;
 
 
namespace Paint1
{
    public partial class Paint : Form
    {
        List<PaintedObject> list;//Список с объектами для прорисовки
        PaintedObject currObj;//Объект, который в данный момент перемещается
        Point oldPoint;
        Bitmap bmp;
        private New form2 = new New();
        private int mode;
        private Point movePt;
        private Point nullPt = new Point(int.MaxValue, 0);
        private Pen pen = new Pen(Color.Black);
        private Pen stir = new Pen(Color.White);
        private Point StartPt;
        private SolidBrush brush = new SolidBrush(Color.White);
        private int figureMode;
        private bool equalSize;
        private Bitmap oldImage;
        private Font font;// текст
 
        public Paint()
        {
            InitializeComponent();
            AddOwnedForm(form2);
            openFileDialog1.InitialDirectory = saveFileDialog1.InitialDirectory =
                Directory.GetCurrentDirectory();
            form2.numericUpDown1.Value = panel1.ClientSize.Width;
            form2.numericUpDown2.Value = panel1.ClientSize.Height;
            form2.button1_Click(this, null);// чистое поле при запуске 
            pen.StartCap = pen.EndCap = LineCap.Round;// сглаживание
            pen.Alignment = PenAlignment.Inset;//для правильного задания размера прямоугольников
            oldImage = new Bitmap(pictureBox1.Image);
            font = Font.Clone() as Font;
            comboBox1.SelectedIndex = 0;
            list = new List<PaintedObject>();
         //   bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
            bmp = new Bitmap(pictureBox1.Image);
            //Заполнение списка случайными объектами для прорисовки
            Init();
            //Обновление битмапа
            RefreshBitmap();
            this.DoubleBuffered = true;
            this.MouseDown += Form1_MouseDown;
            this.MouseUp += Form1_MouseUp;
            this.MouseMove += Form1_MouseMove;
            this.Paint += Form1_Paint;
         
        }
        void Form1_Paint(object sender, PaintEventArgs e) {
            if (bmp == null) return;
            RefreshBitmap();
            e.Graphics.DrawImage(bmp, 0, 0);
        }
 
        void Form1_MouseMove(object sender, MouseEventArgs e) {
            switch (e.Button) {
                case MouseButtons.Left:
                    //Считаем смещение курсора
                    int deltaX, deltaY;
                    deltaX = e.Location.X - oldPoint.X;
                    deltaY = e.Location.Y - oldPoint.Y;
                    //Смещаем нарисованный объект
                    currObj.Path.Transform(new Matrix(1, 0, 0, 1, deltaX, deltaY));
                    //Запоминаем новое положение курсора
                    oldPoint = e.Location;
                    break;
                default:
                    break;
            }
            //Обновляем форму
            this.Refresh();
        }
 
        void Form1_MouseUp(object sender, MouseEventArgs e) {
            currObj.Pen.Width -= 1;//Возвращаем ширину пера
            currObj = null;//Убираем ссылку на объект
        }
 
        void Form1_MouseDown(object sender, MouseEventArgs e) {
            //Запоминаем положение курсора
            oldPoint = e.Location;
            //Ищем объект, в который попала точка. Если таких несколько, то найден будет первый по списку
            foreach (PaintedObject po in list) {
                if (po.Path.GetBounds().Contains(e.Location)) {
                    currObj = po;//Запоминаем найденный объект
                    currObj.Pen.Width += 1;//Делаем перо жирнее
                    return;
                }
            }
        }
        void RefreshBitmap() {
            if (bmp != null) bmp.Dispose();
            bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
            //Прорисовка всех объектов из списка
            using (Graphics g = Graphics.FromImage(bmp)) {
                foreach (PaintedObject po in list) {
                    g.DrawPath(po.Pen, po.Path);
                }
            }
        }
 
        void Init() {
            PaintedObject po;
            Random rnd = new Random(DateTime.Now.Millisecond);
            int w = this.ClientSize.Width,
                w1 = this.ClientSize.Width / 2,
                h = this.ClientSize.Height,
                h1 = this.ClientSize.Height / 2;
            for (int i = 0; i < 5; i++) {
                po = new PaintedObject(new Pen(Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256))), new GraphicsPath());
                po.Path.AddEllipse(Rectangle.FromLTRB(rnd.Next(w1), rnd.Next(h1), rnd.Next(w1, w), rnd.Next(h1, h)));
                list.Add(po);
            }
        }
 
        private void MainForm_Load(object sender, EventArgs e)
        {
 
        }
    
       
 
        // Выбор и рисование фигур
        private void DrawFigure(Rectangle r, Graphics g)
        {
            PaintedObject po = new PaintedObject();
            po.AddRectangle(r);
            switch (figureMode)
            {
                case 0:
                    if (!checkBox1.Checked)
                        g.FillRectangle(brush, r);
                    g.DrawRectangle(pen, r);
                    break;
                case 1:
                    if (!checkBox1.Checked)
                        g.FillEllipse(brush, r);
                    g.DrawEllipse(pen, r);
                    break;
 
            }
        }
         
        // метод рисования прямоугольника
        private Rectangle PtToRect(Point p1, Point p2)
        {
            if (equalSize)
            {
                int dx = p2.X - p1.X, dy = p2.Y - p1.Y;
                if (Math.Abs(dx) > Math.Abs(dy))
                    p2.X = p1.X + Math.Sign(dx) * Math.Abs(dy);
                else
                    p2.Y = p1.Y + Math.Sign(dy) * Math.Abs(dx);
            }
            int x = Math.Min(p1.X, p2.X),
                y = Math.Min(p1.Y, p2.Y),
                w = Math.Abs(p2.X - p1.X),
                h = Math.Abs(p2.Y - p1.Y);
            return new Rectangle(x, y, w, h);
0
16.10.2014, 00:22
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.10.2014, 00:22

Передвижение объектов по форме мышкой
Хочу написать в Windows Forms игру Unblock King. На данном этапе реализовал...

Перемещение объектов OvalShape по форме мышкой
Подскажите как это реализовать, пожалуйста!

Graphics: перемещение нарисованных объектов
Добрый день , Как лучше удалить линию нарисованную с помощью Graphics.DrawLine...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru