Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.63/19: Рейтинг темы: голосов - 19, средняя оценка - 4.63
3 / 3 / 2
Регистрация: 27.06.2013
Сообщений: 91
1

Двигать фигуру мышью, есть ли более быстрая альтернатива методу pictureBox.Refresh?

01.08.2013, 07:27. Показов 3932. Ответов 7
Метки нет (Все метки)

На форме есть pictureBox, в который вставлен рисунок (Image) из файла. С использованием метода MouseMove поверх рисунка с помощью курсора мыши горизонтально двигается фигура, которая рисуется с использованием метода MouseMove.

Объявляются следующие объекты:

C#
1
2
3
SolidBrush myBrush1 = new SolidBrush(Color.DeepSkyBlue);
Point[] points4 = new Point[5];
Graphics Графика;
В методе MyForm_Activated(object sender, EventArgs e), который вызывается при активации формы, есть строчка:

C#
1
Графика = pictureBox2.CreateGraphics();
Метод MouseMove:

C#
1
2
3
4
5
6
7
8
9
10
private void pictureBox2_MouseMove(object sender, MouseEventArgs e)
{
this.pictureBox2.Refresh();
points4[0] = new Point(e.X, 7 + 14);
points4[1] = new Point(e.X + 7, 14);
points4[2] = new Point(e.X + 14, 7 + 14);
points4[3] = new Point(e.X + 14, 14 + 14);
points4[4] = new Point(e.X, 14 + 14);
Графика.FillPolygon(myBrush1, points4);
}
this.pictureBox2.Refresh(); используется, чтобы уже нарисованная фигура стиралась при движении мыши, когда рисуется новая, и двигалась, а не рисовала линию. Проблема в том, что в Windows 7, когда включен интерфейс Aero, прорисовка экрана при движении фигуры происходит довольно медленно, и эта фигура мигает при движении. Если Aero отключен, или в Windows XP, и почему-то в Windows Vista на более старом и медленном компьютере с включенным Aero прорисовка фигуры при ее движении происходит быстро. Пробовал другой вариант - создавать еще один pictureBox, в который вставляется прозрачный рисунок в формате png с использованием следующей конструкции:

C#
1
2
3
pictureBox7.Location = new Point(0, 14);
pictureBox7.Parent = this.pictureBox2;
pictureBox7.BackColor = Color.Transparent;
и дальше менять Location с помощью метода MouseMove. Скорость прорисовки экрана в Windows 7 с Aero такая же не слишком быстрая.

Пробовал еще один способ - вместо this.pictureBox2.Refresh(); использовать метод
C#
1
Графика.Clear(Color.FromArgb(0,255,255,255));
Но при этом вместо прозрачного фона, под которым виден рисунок, под фигурой, которая движется, появляется черный фон. Кроме того, скорость этого варианта такая же низкая.

Есть ли более быстрые альтернативы методу Refresh, которые позволяют двигать фигуру поверх рисунка с помощью курсора мыши, а не рисовать ей линию. То есть стирать ранее нарисованную фигуру при ее перемещении. На что следует обратить внимание, чтобы увеличить скорость, может быть, поменять какие дефолтные настройки, свойства и т. д.
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.08.2013, 07:27
Ответы с готовыми решениями:

Как нарисовать фигуру и двигать ее мышью?
Как нарисовать геометрическую фигуру (треугольник, квадрат, многоугольник) в окне? И как сделать...

Более быстрая альтернатива циклической вставке в таблицу
Задача звучит так: При помощи простого SELECT вставить миллион записей в таблицу базы в цикле....

Есть ли в WinForms альтернатива методу перемещения окна DragMove() в WPF
Здравствуйте! Подскажите, есть в WinForms какая-то альтернатива методу перемещения окна DragMove()...

Есть ли более достойная альтернатива WebBrowser
Всем привет! Мне в приложении на vb.net надо использовать другой, отличный от ie браузер (который и...

7
39 / 37 / 8
Регистрация: 01.08.2013
Сообщений: 106
01.08.2013, 14:25 2
Создать собственный класс например. И изменять его контрол, как душе угодно.
0
2 / 2 / 0
Регистрация: 31.07.2013
Сообщений: 29
01.08.2013, 15:51 3
добавь DoubleBuffered
http://msdn.microsoft.com/en-u... htc9c.aspx
0
3 / 3 / 2
Регистрация: 27.06.2013
Сообщений: 91
09.08.2013, 15:36  [ТС] 4
В общем, не получается убрать мерцание под Windows 7 Aero ни одним из способов. Такое на всех компьютерах, причем в Vista Aero такого нет. DoubleBuffered тоже не помогает, делал его для pictureBox, как написано в Интернете. Даже простое рисование по форме (привожу код) приводит к мерцанию при движении фигуры. Код не совсем корректный, нарисованная фигура при движении мыши закрашивается цветом формы. Поверх рисунка двигать фигуру не получается, рисует шлейф, а если сделать цвет прозрачным, он не закрашивает движущуюся фигуру, и происходит рисование ее цветом. Кроме того, по краям могут оставаться следы в виде частей фигуры. Так как он тоже не решает проблемы мерцания, не работал над ним дальше. Привожу его как пример. Что можно изменить в файлах программы, чтобы ускорить перерисовку окна под Windows 7 Aero? Или этот интерфейс сам по себе медленный?

Файл Program.cs

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
using System.Windows.Forms;
 
namespace MyProgram
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}
Файл Form1.cs

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
using System;
using System.Drawing;
using System.Windows.Forms;
 
 
namespace MyProgram
{
    public partial class Form1 : Form
    {   
 
        int exold;
        Point[] points = new Point[5];
        SolidBrush myBrush = new SolidBrush(Color.Magenta);
        SolidBrush myBrush1 = new SolidBrush(Color.Silver);        
        Graphics Графика;
        
        public Form1()
        {
            Activated += new EventHandler(MyForm_Activated);
            InitializeComponent();
            points[0] = new Point(0, 7 + 14);
            points[1] = new Point(0 + 7, 14);
            points[2] = new Point(0 + 14, 7 + 14);
            points[3] = new Point(0 + 14, 14 + 14);
            points[4] = new Point(0, 14 + 14);
        }
     
        public void MyForm_Activated(object sender, EventArgs e)
        {
         Графика = this.CreateGraphics();
        }
 
            private void pictureBox2_MouseMove(object sender, MouseEventArgs e)
        { 
                points[0] = new Point(exold, 7 + 14);
                points[1] = new Point(exold + 7, 14);
                points[2] = new Point(exold + 14, 7 + 14);
                points[3] = new Point(exold + 14, 14 + 14);
                points[4] = new Point(exold, 14 + 14);
 
                Графика.FillPolygon(myBrush1, points);
 
                if (e.X < 10)
                {
                    points[0] = new Point(10, 7 + 14);
                    points[1] = new Point(10 + 7, 14);
                    points[2] = new Point(10 + 14, 7 + 14);
                    points[3] = new Point(10 + 14, 14 + 14);
                    points[4] = new Point(10, 14 + 14);
                }
 
                else if (e.X > 400)
                {
                    points[0] = new Point(400, 7 + 14);
                    points[1] = new Point(400 + 7, 14);
                    points[2] = new Point(400 + 14, 7 + 14);
                    points[3] = new Point(400 + 14, 14 + 14);
                    points[4] = new Point(400, 14 + 14);
                }
 
                else
                {
                    points[0] = new Point(e.X, 7 + 14);
                    points[1] = new Point(e.X + 7, 14);
                    points[2] = new Point(e.X + 14, 7 + 14);
                    points[3] = new Point(e.X + 14, 14 + 14);
                    points[4] = new Point(e.X, 14 + 14);
                }
 
                Графика.FillPolygon(myBrush, points);
                exold = e.X;
       }
    }
}
Файл Form1.Designer.cs

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
namespace MyProgram
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
 
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
 
        #region Windows Form Designer generated code
 
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.BackColor = System.Drawing.Color.Silver;
            this.ClientSize = new System.Drawing.Size(424, 36);
            this.DoubleBuffered = true;
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
            this.KeyPreview = true;
            this.Name = "Form1";
            this.Text = "Form1";           
            this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox2_MouseMove);
            this.ResumeLayout(false);
        }
        #endregion
    }
}
0
39 / 37 / 8
Регистрация: 01.08.2013
Сообщений: 106
09.08.2013, 15:54 5
Посмотрите в моих исходниках тут, еще проще можно сделать, например писать на Control-ах. Никакого мерцания нет.
0
3 / 3 / 2
Регистрация: 27.06.2013
Сообщений: 91
10.08.2013, 21:54  [ТС] 6
Помогло использование класса BufferedGraphics
https://www.cyberforum.ru/csha... 40684.html
Так как метод Clear затирает рисунок, после него каждый раз использовал DrawImage. Refresh в этом случае не нужен. Свойство pictureBox DoubleBuffered вроде бы ускоряет прорисовку при использовании BufferedGraphics еще больше.
0
1466 / 1174 / 551
Регистрация: 08.01.2012
Сообщений: 4,524
11.08.2013, 09:06 7
Цитата Сообщение от Max_t Посмотреть сообщение
Свойство pictureBox DoubleBuffered
это где такое?
0
3 / 3 / 2
Регистрация: 27.06.2013
Сообщений: 91
11.08.2013, 11:00  [ТС] 8
Цитата Сообщение от MansMI Посмотреть сообщение
это где такое?
C#
1
2
3
4
5
6
7
8
              public Form1()
              {
                // ... код
            typeof(Control).GetProperty(
            "DoubleBuffered",
            BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty
            ).SetValue(pictureBox2, true, null);
             }
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.08.2013, 11:00

Есть ли более 'легковесная' альтернатива текстбоксу? (freeware)
Предвидя ответ Мессира 'напиши такой контрол сам' :)), всё же спрошу: слышал, что при размещении...

Есть ли альтернатива MessageDialog из FireMonkey с более чем одной кнопкой
Добрый день друзья! TDialogServiceSync.MessageDialog('Are you sure you want to terminate the...

Двигать кнопку на слайдере за мышью
Нужно как-то сделать так, чтобы при нажатии на кнопку мышь двигалась за курсором мыши, но не...

Программа: клавишами управления курсором двигать фигуру по экрану
Задать цвет фона розовый, цвет фигуры - серый, фигура в виде буквы Z. Клавишами управления курсором...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru