ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2

ANTICHAT — форум по информационной безопасности, OSINT и технологиям

ANTICHAT — русскоязычное сообщество по безопасности, OSINT и программированию. Форум ранее работал на доменах antichat.ru, antichat.com и antichat.club, и теперь снова доступен на новом адресе — forum.antichat.xyz.
Форум восстановлен и продолжает развитие: доступны архивные темы, добавляются новые обсуждения и материалы.
⚠️ Старые аккаунты восстановить невозможно — необходимо зарегистрироваться заново.
Вернуться   Форум АНТИЧАТ > Программирование > С/С++, C#, Delphi, .NET, Asm
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

Мерцание при перерисовке картинок C#
  #1  
Старый 17.04.2010, 10:10
madwort
Новичок
Регистрация: 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
    }
}
 
Ответить с цитированием

  #2  
Старый 17.04.2010, 10:42
cheater_man
Постоянный
Регистрация: 13.11.2009
Сообщений: 437
Провел на форуме:
709575

Репутация: 17
По умолчанию

Чувак я тебе же пример показывал как с помощью OnPaint рисовать. Зачем тебе public void Draw(Graphics g) если можно OnPaint'ом обойтись и мерцания небудет
 
Ответить с цитированием

  #3  
Старый 17.04.2010, 10:49
BrainDeaD
Постоянный
Регистрация: 09.06.2005
Сообщений: 531
Провел на форуме:
3516666

Репутация: 439


По умолчанию

foreach нагружает производительность больше чем for. по этому в designerPanel_Paint используй цикл for. в целом, использование array вместо коллекций может тоже выжать немного скорости. а вообще в критических случаях для работы с графикой лучше подходит directX.
 
Ответить с цитированием

  #4  
Старый 17.04.2010, 11:49
Irdis
Участник форума
Регистрация: 06.02.2006
Сообщений: 177
Провел на форуме:
1576821

Репутация: 88
Отправить сообщение для Irdis с помощью ICQ
По умолчанию

google -> двойная буферизация c sharp
и будет тебе счастье =)
----------------------
суть в том, что мы рисуем(когда необходимо отрисовать что-либо) на битмэп. А потом, подменяем изображение на контроле на уже готовое.

Последний раз редактировалось Irdis; 17.04.2010 в 11:55..
 
Ответить с цитированием

  #5  
Старый 17.04.2010, 11:50
Irdis
Участник форума
Регистрация: 06.02.2006
Сообщений: 177
Провел на форуме:
1576821

Репутация: 88
Отправить сообщение для Irdis с помощью ICQ
По умолчанию

BrainDeaD
Будет мерцать чуть побыстрее XD
 
Ответить с цитированием

  #6  
Старый 17.04.2010, 11:55
cheater_man
Постоянный
Регистрация: 13.11.2009
Сообщений: 437
Провел на форуме:
709575

Репутация: 17
По умолчанию

Цитата:
Сообщение от Irdis  
BrainDeaD
Будет мерцать чуть побыстрее XD
Двойная буферизация и onPaint, а если чисто двойная буферизация то толку нет. Личный опыт.
 
Ответить с цитированием

  #7  
Старый 17.04.2010, 11:58
Irdis
Участник форума
Регистрация: 06.02.2006
Сообщений: 177
Провел на форуме:
1576821

Репутация: 88
Отправить сообщение для Irdis с помощью ICQ
По умолчанию

cheater_man
Не совсем так. Не получается потому, что когда вызывается стандартная перерисовка то всё что вы отрисовали сбрасывается на дефолтное изображение. (А это можно обойти)
 
Ответить с цитированием

  #8  
Старый 17.04.2010, 12:22
cheater_man
Постоянный
Регистрация: 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. Идиальный результат получается.
 
Ответить с цитированием

  #9  
Старый 20.04.2010, 14:11
madwort
Новичок
Регистрация: 29.03.2010
Сообщений: 8
Провел на форуме:
12954

Репутация: 0
По умолчанию

а как отрисовывать элементы с помощью OnPaint, но только не ан форме, а на панели??
 
Ответить с цитированием
Ответ



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
мерцание при установке винды на ноут Дикс Windows 7 27.10.2009 20:59
Jc, показ картинок (подмена при нажатии) rcc0023 PHP, PERL, MySQL, JavaScript 4 20.08.2009 23:30
Тест скорости мультиядерных процессоров на Windows 7, XP и VISTA NetSter Аппаратное обеспечение 1 08.02.2009 15:36



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ