ANTICHAT — форум по информационной безопасности, OSINT и технологиям
ANTICHAT — русскоязычное сообщество по безопасности, OSINT и программированию.
Форум ранее работал на доменах antichat.ru, antichat.com и antichat.club,
и теперь снова доступен на новом адресе —
forum.antichat.xyz.
Форум восстановлен и продолжает развитие: доступны архивные темы, добавляются новые обсуждения и материалы.
⚠️ Старые аккаунты восстановить невозможно — необходимо зарегистрироваться заново.
 |
Мерцание при перерисовке картинок C# |

17.04.2010, 10:10
|
|
Новичок
Регистрация: 29.03.2010
Сообщений: 8
Провел на форуме: 12954
Репутация:
0
|
|
Мерцание при перерисовке картинок C#
Здравствуйте!
Если кто знает, как можно улучшить, буду признателен.
На данном этапе на панель можно добавлять элементы последовательно в цепь, передвигать их, как бы состыковывать, чтобы получить общий рисунок.
но при добавлении на панель большого количества элементов при перерисовке все элементы начинают мерцать, и чем больше элементов, тем сильнее.
Как можно от этого избавиться???
Описание отдельного класса Элемент:
Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Reflection;
namespace CircuitBuilder
{
class Element
{
const int DEFAULT_WIDTH = 100;
const int DEFAULT_HEIGHT = 26;
Image ElementImage = CircuitBuilder.Properties.Resources.Elem;
public Element(string name, int x, int y)
{
this.Name = name;
this.X = x;
this.Y = y;
this.Width = DEFAULT_WIDTH;
this.Height = DEFAULT_HEIGHT;
}
#region Свойства
public string Name { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public Size Size
{
get { return new Size(Width, Height); }
}
public Point Location
{
get { return new Point(X, Y); }
}
#endregion
#region Открытые Методы
public void Draw(Graphics g)
{
g.DrawImage(ElementImage, X, Y, Width, Height);
g.DrawString(Name, SystemFonts.DefaultFont, SystemBrushes.WindowText, new Point(X, Y + Height));
}
#endregion
}
}
Описание действий на форме
Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace CircuitBuilder
{
public partial class Form1 : Form
{
List<Element> elements = new List<Element>();
Element SelectedElement = null;
Boolean dragging;
Point startDragPoint;
public Form1()
{
InitializeComponent();
}
#region Методы
Element GetItemAt(int x, int y)
{
foreach (Element currElement in elements)
{
if (
currElement.X < x &&
currElement.X + currElement.Width > x &&
currElement.Y < y &&
currElement.Y + currElement.Height > y
)
return currElement;
}
return null;
}
#endregion
#region События меню
private void выходToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void новыйToolStripMenuItem_Click(object sender, EventArgs e)
{
elements.Clear();
designerPanel.Invalidate();
}
private void добавитьЭлементToolStripMenuItem_Click(object sender, EventArgs e)
{
Element element = new Element(" Элемент " + elements.Count.ToString(), 0, 0);
elements.Add(element);
designerPanel.Invalidate();
}
private void designerPanel_Paint(object sender, PaintEventArgs e)
{
foreach (Element element in elements)
element.Draw(e.Graphics);
}
private void designerPanel_MouseDown(object sender, MouseEventArgs e)
{
Element element = GetItemAt(e.X, e.Y);
if (element != null)
{
SelectedElement = element;
dragging = true;
startDragPoint = e.Location;
}
}
private void designerPanel_MouseUp(object sender, MouseEventArgs e)
{
if (dragging)
{
dragging = false;
designerPanel.Invalidate();
}
}
private void designerPanel_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
{
SelectedElement.X = SelectedElement.Location.X + (e.Location.X - startDragPoint.X);
SelectedElement.Y = SelectedElement.Location.Y + (e.Location.Y - startDragPoint.Y);
designerPanel.Invalidate();
startDragPoint = e.Location;
}
}
#endregion
}
}
|
|
|

17.04.2010, 10:42
|
|
Постоянный
Регистрация: 13.11.2009
Сообщений: 437
Провел на форуме: 709575
Репутация:
17
|
|
Чувак я тебе же пример показывал как с помощью OnPaint рисовать. Зачем тебе public void Draw(Graphics g) если можно OnPaint'ом обойтись и мерцания небудет 
|
|
|

17.04.2010, 10:49
|
|
Постоянный
Регистрация: 09.06.2005
Сообщений: 531
Провел на форуме: 3516666
Репутация:
439
|
|
foreach нагружает производительность больше чем for. по этому в designerPanel_Paint используй цикл for. в целом, использование array вместо коллекций может тоже выжать немного скорости. а вообще в критических случаях для работы с графикой лучше подходит directX.
|
|
|

17.04.2010, 11:49
|
|
Участник форума
Регистрация: 06.02.2006
Сообщений: 177
Провел на форуме: 1576821
Репутация:
88
|
|
google -> двойная буферизация c sharp
и будет тебе счастье =)
----------------------
суть в том, что мы рисуем(когда необходимо отрисовать что-либо) на битмэп. А потом, подменяем изображение на контроле на уже готовое.
Последний раз редактировалось Irdis; 17.04.2010 в 11:55..
|
|
|

17.04.2010, 11:50
|
|
Участник форума
Регистрация: 06.02.2006
Сообщений: 177
Провел на форуме: 1576821
Репутация:
88
|
|
BrainDeaD
Будет мерцать чуть побыстрее XD
|
|
|

17.04.2010, 11:55
|
|
Постоянный
Регистрация: 13.11.2009
Сообщений: 437
Провел на форуме: 709575
Репутация:
17
|
|
Сообщение от Irdis
BrainDeaD
Будет мерцать чуть побыстрее XD
Двойная буферизация и onPaint, а если чисто двойная буферизация то толку нет. Личный опыт.
|
|
|

17.04.2010, 11:58
|
|
Участник форума
Регистрация: 06.02.2006
Сообщений: 177
Провел на форуме: 1576821
Репутация:
88
|
|
cheater_man
Не совсем так. Не получается потому, что когда вызывается стандартная перерисовка то всё что вы отрисовали сбрасывается на дефолтное изображение. (А это можно обойти)
|
|
|

17.04.2010, 12:22
|
|
Постоянный
Регистрация: 13.11.2009
Сообщений: 437
Провел на форуме: 709575
Репутация:
17
|
|
Сообщение от Irdis
cheater_man
Не совсем так. Не получается потому, что когда вызывается стандартная перерисовка то всё что вы отрисовали сбрасывается на дефолтное изображение. (А это можно обойти)
Дак блин нужно зафорить.
Использовать ArrayList, для хранения местоположения каждой картинки:
Код:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
for(int i=0; i<Array.Leght;i++)
{
//paint
}
}
Отрисововал так более 100 компонентов на Form.
Без мерцания.
Ну а конечно наилучший метод это ArrayList+IEnumerator+Container+Collection. Идиальный результат получается.
|
|
|

20.04.2010, 14:11
|
|
Новичок
Регистрация: 29.03.2010
Сообщений: 8
Провел на форуме: 12954
Репутация:
0
|
|
а как отрисовывать элементы с помощью OnPaint, но только не ан форме, а на панели??
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|