Здравствуйте! Если кто знает, как можно улучшить, буду признателен. На данном этапе на панель можно добавлять элементы последовательно в цепь, передвигать их, как бы состыковывать, чтобы получить общий рисунок. но при добавлении на панель большого количества элементов при перерисовке все элементы начинают мерцать, и чем больше элементов, тем сильнее. Как можно от этого избавиться??? Описание отдельного класса Элемент: Code: 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 } } Описание действий на форме Code: 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 } }
Чувак я тебе же пример показывал как с помощью OnPaint рисовать. Зачем тебе public void Draw(Graphics g) если можно OnPaint'ом обойтись и мерцания небудет
foreach нагружает производительность больше чем for. по этому в designerPanel_Paint используй цикл for. в целом, использование array вместо коллекций может тоже выжать немного скорости. а вообще в критических случаях для работы с графикой лучше подходит directX.
google -> двойная буферизация c sharp и будет тебе счастье =) ---------------------- суть в том, что мы рисуем(когда необходимо отрисовать что-либо) на битмэп. А потом, подменяем изображение на контроле на уже готовое.
cheater_man Не совсем так. Не получается потому, что когда вызывается стандартная перерисовка то всё что вы отрисовали сбрасывается на дефолтное изображение. (А это можно обойти)
Дак блин нужно зафорить. Использовать ArrayList, для хранения местоположения каждой картинки: Code: protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); for(int i=0; i<Array.Leght;i++) { //paint } } Отрисововал так более 100 компонентов на Form. Без мерцания. Ну а конечно наилучший метод это ArrayList+IEnumerator+Container+Collection. Идиальный результат получается.