С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/37: Рейтинг темы: голосов - 37, средняя оценка - 4.92
4 / 4 / 0
Регистрация: 21.04.2012
Сообщений: 132

Мигает текст в панели. Как задействовать DoubleBuffered

02.10.2012, 19:06. Показов 7422. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
День добрый.
я работаю с биржевыми данными. подключаюсь к серверу. сервер выдает цену акции в заданном диапазоне, от и до. для этого я создал панель в мастере, далее программно поместил на нее еще одну (вторую) панель, на которой я собственно и пытаюсь вывести весь список цен акции. цены вывожу столбиком, с заданным шагом, при помощи DrawString. сам вывод столбиком засунул в OnPaint формы. Цена акции, выдаваемая сервером - меняется с огромной скоростью, десятки раз в секунду. так что все должно быть быстро.

проблема 1:
если не очищать элементы, то цифры цены начинают накладывать друг на друга, при каждой новой перерисовке.

проблема 2: если вставить очистку gg.Clear(Color.Pink); то весь столбик начинает рябить (моргать).

покопался в гугле - сказано, что нужно использовать двойной буфер и еще несколько свойств, что бы этого избежать. вставил в код:
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
- не работает. не понятно, нужно эти свойства задавать у каждого контрола или у всей формы?
хотя, я может намудрил с самим кодом конечно. подскажите, кто в теме разбирается, плиз.

прошу прощения за мусор в коде - я не особо пока монстр программирования.
вот код:

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
namespace graphic_stakan
{
    public partial class Form1 : Form
    {
        public StServer smartcom; // объявляем переменную смарткома
        string bumaga_1 = "RTS-12.12_FT";
        string ip = "*******"; // порт 8090
        string login = "********";
        string password = "********";
        string portfolio = "***********"; // реал
 
 
        public Form1()
        {
            InitializeComponent();
            
        }
 
        int x = 10;
        int y = 10;
        int width = 200;
        int height = 200;
 
 
        Thread t; // создадим поток под именем t
        private Panel panel_2 = new Panel(); // вторая панель
 
 
 
        public void Form1_Load(object sender, EventArgs e)
        {
 
            // smartcom
            smartcom = new StServer(); // создаем новый объект смарткома.
            smartcom.Connected +=new _IStClient_ConnectedEventHandler(smartcom_Connected);
            smartcom.Disconnected +=new _IStClient_DisconnectedEventHandler(smartcom_disconnected);
            smartcom.UpdateBidAsk +=new _IStClient_UpdateBidAskEventHandler(smartcom_UpdateBidAsk);
            smartcom.UpdateQuote +=new _IStClient_UpdateQuoteEventHandler(smartcom_UpdateQuote);
 
            panel1.BorderStyle = BorderStyle.FixedSingle; // стиль первой панели
            this.Text = "анимация он_паинт";
            t = new Thread(new ThreadStart(start)); // укажим стартовый код потока
 
            panel1.Controls.Add(panel_2); // добавим панель 2 на панель 1
                        
            
            t.Start(); // запустим поток
        }
 
        
        
 
 
        int price_start;// планки цены
        int price_end;
        int price_step = 10; // шаг цены
 
       
        protected override void OnPaint(PaintEventArgs e)
        {
 
            // что бы не моргало
            //SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true); // другой вариант
            SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true); // работает
 
                 
            
 
            textBox5.Text = ((price_end - price_start) / price_step * 15 + 18).ToString();
 
            // стиль второй панели
            panel_2.BorderStyle = BorderStyle.FixedSingle;
            panel_2.BackColor = Color.Pink;
            panel_2.Size = new Size(150, (price_end - price_start) / price_step * 15 + 18 ); // диапазон цены / шаг цены * шаг в пунктах + некое значение для красоты
            panel_2.Location = new Point(20, Convert.ToInt32(trackBar1.Value)); // положение
            
            /*
            // рисование элипса (круга) - работает
            Graphics g = e.Graphics;
            Pen green = new Pen(Color.Red, 3);
            //Brush red = new SolidBrush(Color.Blue);
            //g.DrawEllipse(green, x, y, width, height);
            g.DrawEllipse(green, x, y, width, Convert.ToSingle(numericUpDown1.Value));
             */
 
            // добавление строки на панель - работает
            //String drawString = "146 520"; // создадим строку 
            Font drawFont = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular); // определим шрифт
            SolidBrush drawBrush = new SolidBrush(Color.Black); // определим кисть
            PointF drawPoint = new PointF(0F, 0F); // определим координаты
 
            Graphics gg = Graphics.FromHwnd(panel_2.Handle); // создадим графический элемент на панели 2
            //gg.DrawString(drawString, drawFont, drawBrush, drawPoint); // отрисуем его
            //gg.DrawString(drawString, drawFont, drawBrush, new PointF(0F, 20F));
 
            //panel1.Controls.Clear(); // очистим панель 1
            //panel1.Controls.Add(panel_2); // добавим панель 2 на панель 1
 
            //gg.Clear(Color.Pink);
                        
            for (int i = 0, j = price_end; j >= (price_start); i += 15, j -= price_step) // с шагом 15. i - шаг в пунктах. по 5 пуктов расстояние между строчками, размер шрифта - 10
            {
 
                String drawString = j.ToString() + " " + i ; // создадим строку 
                gg.DrawString(drawString, drawFont, drawBrush, new PointF(0F, i));
                
            }
            
            
 
            textBox1.Text = numericUpDown1.Value.ToString();
            textBox2.Text = trackBar1.Value.ToString();
 
            base.OnPaint(e);
 
        }
 
        
 
        public void start()
        {
            while (true)
            {
                Invalidate();
                Thread.Sleep(10);
            }
        }
 
 
        private void Form1_FormClosing(object sender, FormClosingEventArgs e) // при закрытии формы - удить поток
        {
            smartcom.disconnect(); // отключимся от сервера
            t.Abort(); // остановим поток
        }
Борис
Изображения
 
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.10.2012, 19:06
Ответы с готовыми решениями:

Как рисовать на Doublebuffered panel?
Как рисовать фигуры на панели, когда DoubleBuffered у неё стоит на true. У меня фигуры рисуются и тут же пропадают, и видно их только на...

Холодильник Simens KG30E01/02 не включается, индикация на панели прерывисто мигает
Холодильник не включается,индикация на панели прерывисто мигает.При вкл.плати отдельно на столе индикация светит нормально толь...

Как вставить текст из буфера туда где мигает курсор? В хром например или другую программу?
Помогите все перерыл нигде нету инфы как вставить текст на место курсора в винде.

18
4 / 4 / 0
Регистрация: 21.04.2012
Сообщений: 132
04.10.2012, 01:40  [ТС]
Что, по данной теме никто ничего сказать и подсказать не может?
0
Заблокирован
04.10.2012, 01:48
хз может не стоит OnPaint использовать?
0
4 / 4 / 0
Регистрация: 21.04.2012
Сообщений: 132
04.10.2012, 10:12  [ТС]
может и не стоит, а что тогда использовать?
0
Українець
424 / 318 / 16
Регистрация: 26.09.2009
Сообщений: 844
04.10.2012, 11:40
я не уверен, что SetStyle присваивает значение panel_2
попробуйте при загрузке установить стиль
C#
1
panel_2.SetStyle(..)
1
Темная сторона .Net
 Аватар для Noob.net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
04.10.2012, 12:47
пробовал после каждого изменения текста refresh'ать элемент управления?
//мне когда то в делфэ помогло..
а проще будет изменить,например на текстбокс
1
4 / 4 / 0
Регистрация: 21.04.2012
Сообщений: 132
04.10.2012, 12:55  [ТС]
1. у panel_2 нет метода SetStyle()
2. рефрешить это как? invalidate(), который отвечает за обновление вроде бы стоит.
0
Українець
424 / 318 / 16
Регистрация: 26.09.2009
Сообщений: 844
04.10.2012, 13:23
Попробуйте сначала нарисовать в Bitmap, а потом отразить на экране
0
Темная сторона .Net
 Аватар для Noob.net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
04.10.2012, 15:42
slinger, panel2.refresh(); Invalidate - вызывается внутри рефреша.
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8725 / 3677 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
04.10.2012, 15:49
Где ж вас учат то таких... Смотрите проект в аттаче.

з.ы. В принципе, в коде можно даже Sleep убрать, у меня он не на что не влияет - мерцания нет.
Вложения
Тип файла: rar drawing.rar (10.5 Кб, 19146 просмотров)
1
4 / 4 / 0
Регистрация: 21.04.2012
Сообщений: 132
04.10.2012, 18:41  [ТС]
2SSTREGG

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

борис
0
Українець
424 / 318 / 16
Регистрация: 26.09.2009
Сообщений: 844
04.10.2012, 22:08
SSTREGG, не заметил я у Вас двойной буферизации. Наверное плохо учусь.
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8725 / 3677 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
04.10.2012, 22:11
freest, конструктор формы посмотрите, 25-28 строчки.
1
Українець
424 / 318 / 16
Регистрация: 26.09.2009
Сообщений: 844
04.10.2012, 22:14
SSTREGG, ага спасибо.
0
4 / 4 / 0
Регистрация: 21.04.2012
Сообщений: 132
05.10.2012, 12:45  [ТС]
вопрос по коду:
в коде запускается поток
C#
1
new Thread( ThreadToDo ).Start();
- а, как его остановить, при закрытии формы?
в событие закрытия формы я поместил:
C#
1
Thread.CurrentThread.Abort(); // остановили поток
но, поток по прежнему продолжает работать при закрытии.

Добавлено через 38 минут
поколдовал. сделал вот так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
     Thread panel_potok; // поток
 
        private void btnStart_Click ( object sender, EventArgs e ) // кнопка старт + запуск процесса
        {
            if ( running )
                return;
 
            running = true;
            //new Thread( ThreadToDo ).Start(); // назначение потока + передача в него параметра из нумерик ап даун я ее прибил
 
            panel_potok = new Thread(new ThreadStart(ThreadToDo)); // мой вариант
            panel_potok.Start();
            
            pnlPink.Height = 5 * 2 /* 0ffset from top & bottom */ + ((int)pnlPink.Font.GetHeight() + 3) * ((price_end - price_start) / price_step + 1);
            
        }
 
 
        private void Form1_FormClosing(object sender, FormClosingEventArgs e) // форма закрывается
        {
            panel_potok.Abort();
                                  
        }
вроде после закрытия форму - процесс останавливается. подскажите, на сколько это правильно и можно ли так оставить?
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8725 / 3677 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
05.10.2012, 16:04
Цитата Сообщение от slinger Посмотреть сообщение
подскажите, на сколько это правильно и можно ли так оставить
Неправильно, вы не даете потоку корректно завершится, а обрываете его "на полуслове".
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
using System;
using System.Drawing;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
 
namespace drawing
{
    public partial class Form1 : Form
    {
        volatile bool running;
        Thread        thWorker;
 
        string[] strArray;
        object   objLocker;
 
        public Form1 ( )
        {
            objLocker = new object();
 
            InitializeComponent();
            this.FormClosed += Form1_FormClosed;
 
            typeof( Control ).GetProperty(
                "DoubleBuffered",
                BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty
                ).SetValue( pnlPink, true, null );
            pnlPink.Paint += pnlPink_Paint;
 
            numCount.Value = 50M;
        }
 
        void Form1_FormClosed ( object sender, FormClosedEventArgs e )
        {
            running = false;
            if ( thWorker != null && thWorker.IsAlive )
                thWorker.Join();
        }
 
        void pnlPink_Paint ( object sender, PaintEventArgs e )
        {
            if ( strArray == null )
                return;
 
            var g = e.Graphics;
 
            lock ( objLocker )
            {
                var pt = new Point( 5, 5 );
                for ( int i = 0; i < strArray.Length; ++i )
                {
                    g.DrawString( strArray[i], pnlPink.Font, Brushes.Black, pt );
                    pt.Y += (int)pnlPink.Font.GetHeight() + 3;
                }
            }
        }
 
        private void numCount_ValueChanged ( object sender, EventArgs e )
        {
            pnlPink.Height = 5 * 2 /* 0ffset from top & bottom */ +
                             ((int)pnlPink.Font.GetHeight() + 3) * (int)numCount.Value;
        }
 
        private void btnStart_Click ( object sender, EventArgs e )
        {
            if ( running )
                return;
 
            running = true;
            thWorker = new Thread( ThreadToDo );
            thWorker.Start( (int)numCount.Value );
 
            btnStart.Enabled = numCount.Enabled = false;
            btnStop.Enabled = true;
        }
 
        void ThreadToDo ( object obj )
        {
            int count = (int)obj;
            var buff  = new byte[count];
            var rng   = new System.Security.Cryptography.RNGCryptoServiceProvider();
 
            strArray = new string[count];
 
            while ( running )
            {
                rng.GetNonZeroBytes( buff );
 
                lock ( objLocker )
                {
                    for ( int i = 0; i < count; ++i )
                        strArray[i] = "element" + i + ", v: " + buff[i];
                }
 
                // Не вызывает синхронную перерисовку
                // поэтому Invoke не треуется
                pnlPink.Invalidate();
            }
        }
 
        private void btnStop_Click ( object sender, EventArgs e )
        {
            if ( !running )
                return;
 
            running = false;
            if ( thWorker != null && thWorker.IsAlive )
                thWorker.Join();
            thWorker = null;
 
            btnStart.Enabled = numCount.Enabled = true;
            btnStop.Enabled = false;
        }
    }
}
0
4 / 4 / 0
Регистрация: 21.04.2012
Сообщений: 132
05.10.2012, 18:34  [ТС]
все сделал, как вы написали.
доделал второй вариант - такая же панель, но в виде класса.
проблемы: все вроде работает, но если скролить левую панель, то видно, что она тормозит по сравнению со второй. пробовал прибавлять/убавлять
C#
1
Thread.Sleep(10);
, но если его вообще убрать, то левая панель вообще зависает.
это как то связано с тем, что обе они работают в одном потоке?
если поставить значение 100, то вроде работает нормально. непонятная чувствительность к данному значению.
завершать поток при помощи Join не получается - при закрытии формы, все виснет.
оставил
C#
1
panel_potok.Abort()
высылаю проект, на проверку
Вложения
Тип файла: zip drawing_s_foruma_MY.zip (73.0 Кб, 17 просмотров)
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8725 / 3677 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
05.10.2012, 20:39
Цитата Сообщение от slinger Посмотреть сообщение
это как то связано с тем, что обе они работают в одном потоке?
Да, и еще то что Invalidate не обновляет область, а всего-лишь добавляет её в регион обновления
Цитата Сообщение от MSDN
When this method is called with no parameters, the entire client area is added to the update region.
в итоге приоритет отдается тому кто успел первым.
Цитата Сообщение от slinger Посмотреть сообщение
завершать поток при помощи Join не получается - при закрытии формы, все виснет.
Это из-за Invoke. В текущем варианте не будет виснуть.
Вложения
Тип файла: rar drawing.rar (11.5 Кб, 49 просмотров)
1
4 / 4 / 0
Регистрация: 21.04.2012
Сообщений: 132
15.10.2012, 18:22  [ТС]
основываясь на проделанной работе - сочинил пост:
Ссылка: http://bfin.pro/2012/10/zagotovka-dom-stakana-2-kod-c-postroenie-grafika/
и записал видео:
Кликните здесь для просмотра всего текста


всем еще раз спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.10.2012, 18:22
Помогаю со студенческими работами здесь

Загрузка системы до рабочего стола доходит, появляются иконки в панели задач, а сам экран черный и курсор мигает
а что хоть, решилась проблема-то? а то у меня то же самое.. :cry: во время игры зависло все, потом появился синий экран, вот ни...

DoubleBuffered = true
DoubleBuffered = true - включен как решить проблему с миганием картинок? exe файл в приложение (ошибка выходит из-за музыки)

DoubleBuffered и frame
Всем привет Столкнулся с проблемой Делаю перерисовку битмапа на PaintBox1 на форме, DoubleBuffered:=true и мерцания нет делаю тоже...

Windows 8 черный экран после старта, мигает и курсор мигает
Помогите товарищи!!! На компе пропал add- файл для запуска некоторых игр, после советов пере установил все microsoft visual c++...

Как задействовать мышь
Мне необходимо разобраться с использованием мыши в qb. Я сначала думал над библеотекой int33h, но она на ассэмблере и я от этого отказался....


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru