Pererisovka Graphika
Problema: kogda graph vihodit za predeli razmera formi i pojavlaetsa polosa prokrutki(scrollbar) vo vrema prokrutki ves graph (narisovannaja chast: pictures i lines) trusitsa, vigladit ochen nekrasivo. Chto delat? :(
Pishu programmy kotoraja stroit graph i sostojazii iz: lines, pictures and labels.
Problema: kogda graph vihodit za predeli razmera formi i pojavlaetsa polosa prokrutki(scrollbar) vo vrema prokrutki ves graph (narisovannaja chast: pictures i lines) trusitsa, vigladit ochen nekrasivo. Chto delat? :(
Уважаемая OlgaKr, если есть такая возможность, изложите всё тоже самое, но на английском (если честно, то я просто не понял)
Уважаемая OlgaKr, если есть такая возможность, изложите всё тоже самое, но на английском (если честно, то я просто не понял)
______________________________________________
Извиняюсь, у меня проблемы с русской клавиатурой.
Mоя программа чертит графики которые состоят из линий, картинок и labels. Когда граф выходит за границы окна и надо ползоваться ScrollBar чтобы просмотреть весь граф нарисованные обекты графа дрожат и если прокрутка HorizontalScrollBar и VerticalScrollBar одновременно тогда график частично не востанавливается.
Обрати внимание что перерисовку я делаю, у меня есть функция которая обрабатывает событие Paint:
{
this.DrawGraph();
}
private void DrawGraph()
{
Graphics g = this.pnlShowGraph.CreateGraphics();
g.Clear(Color.FloralWhite);
g.SmoothingMode = SmoothingMode.HighQuality;
this.DrawArrows(g);
this.DrawPictures(g);
}
private void DrawPictures(Graphics graphics)
{
for(int i = 0; i < this.entgraph.ArrPictures.Count; i++)
{
entPicture p = ((entPicture)this.entgraph.ArrPictures);
graphics.DrawImage(p.Bitmap,p.Control_X,p.Control_Y,p.Bitmap.Width,p.Bitmap.Height);
}
}
private void DrawArrows(Graphics graphics)
{
for(int i = 0; i < this.entgraph.ArrArrows.Count; i++)
{
graphics.DrawLine(new Pen(((entArrow)this.entgraph.ArrArrows).Color,((entArrow)this.entgraph.ArrArrows).Width),((entArrow)this.entgraph.ArrArrows).Point1,((entArrow)this.entgraph.ArrArrows).Point2);
}
}
private PictureBox pictureBox1 = new PictureBox();
private void Form1_Load(object sender, System.EventArgs e)
{
// Стыкуем PictureBox на форму и устанавливаем цвет фона
pictureBox1.Dock = DockStyle.Fill;
pictureBox1.BackColor = Color.White;
// Назначаем процедуру перерисовки
pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
//Добавляем PictureBox на форму
this.Controls.Add(pictureBox1);
}
private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
// Создаём локальную версию графического объекта
Graphics g = e.Graphics; //<-Обращаем внимание
// Рисуем текст
g.DrawString("Какой-то текст",
new Font("Arial",10), System.Drawing.Brushes.Blue, new Point(30,30));
// Рисуем линию
g.DrawLine(System.Drawing.Pens.Red, pictureBox1.Left, pictureBox1.Top,
pictureBox1.Right, pictureBox1.Bottom);
}
Дрожания можно избежать, если выполнять прорисовку графика после окончания прокрутки, а не во время (перехватывать обработку события на MouseUp и выполнять прорисовку)
Дрожание происходит из-за того, что в процедурах перерисовки есть циклы. Я из исходного текста понял, что рисование происходит в контрол pnlShowGraph так. Если так, то почему перерисовка назначена на форму а не на этот контрол? Вот этот пример демонстрирует, как рисовать в контрол:
private PictureBox pictureBox1 = new PictureBox();
private void Form1_Load(object sender, System.EventArgs e)
{
// Стыкуем PictureBox на форму и устанавливаем цвет фона
pictureBox1.Dock = DockStyle.Fill;
pictureBox1.BackColor = Color.White;
// Назначаем процедуру перерисовки
pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
//Добавляем PictureBox на форму
this.Controls.Add(pictureBox1);
}
private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
// Создаём локальную версию графического объекта
Graphics g = e.Graphics; //<-Обращаем внимание
// Рисуем текст
g.DrawString("Какой-то текст",
new Font("Arial",10), System.Drawing.Brushes.Blue, new Point(30,30));
// Рисуем линию
g.DrawLine(System.Drawing.Pens.Red, pictureBox1.Left, pictureBox1.Top,
pictureBox1.Right, pictureBox1.Bottom);
}
Дрожания можно избежать, если выполнять прорисовку графика после окончания прокрутки, а не во время (перехватывать обработку события на MouseUp и выполнять прорисовку)
Спасибо большоё, я попробую изменить код.
Только я рисую не на PictureBox а на Panel.
Дрожание происходит из-за того, что в процедурах перерисовки есть циклы. ...Дрожания можно избежать, если выполнять прорисовку графика после окончания прокрутки, а не во время (перехватывать обработку события на MouseUp и выполнять прорисовку)
_________________________________________________
Изменила функцию Paint, назначила её на контрол на котором рисую. Но как обработать правильно событие MouseUp не знаю. Прокрутка у меня автоматическая на форме (AutoScroll == true), рисую на Panel, обработчик события MouseUп нужно написать для AutoScrollBar формы и честно говоря как это сделать я не знаю. Если можешь помоги пожалуйста.
_______________________
Кстати есть ли разница между определением Craphics что ты написал в своём примере( Graphics g = e.Graphics; //<-Обращаем внимание), и межды тем как это делаю я: Graphics g = this.pnlShowGraph.CreateGraphics(); ?
Или разница только в синтаксисе написания?
_______________________
P.S. После того как поменяла обработчик события Paint график трусится но востанавливается полностью. Уже веселей.
:)
Кстати есть ли разница между определением Craphics что ты написал в своём примере( Graphics g = e.Graphics; //<-Обращаем внимание), и межды тем как это делаю я: Graphics g = this.pnlShowGraph.CreateGraphics(); ?
Или разница только в синтаксисе написания?
______________________
Разница в перехвате графического объекта для обработки. В моём случае это происходит на уровне соответствующего события, а у тебя объект создаётся заново. А насчёт обработчика MouseUp: попробуй два варианта:
1) В обработчике MouseDown стирай график, а в обработчике MouseUp перерисовывай.
2) Только в MouseUp делай перерисовку, а MouseDown не трогай
Разница в перехвате графического объекта для обработки. В моём случае это происходит на уровне соответствующего события, а у тебя объект создаётся заново. А насчёт обработчика MouseUp: попробуй два варианта:
1) В обработчике MouseDown стирай график, а в обработчике MouseUp перерисовывай.
2) Только в MouseUp делай перерисовку, а MouseDown не трогай
[COLOR=indigo]1) Спасибо за помощь, ты меня очень выручаешь.[/COLOR]
2) Я наверно неправильно сформулировала вопрос. Проблема не в том когда перерисовавать а в том как написать обработчук события MouseUp/Down для АutoScroll, прокрутка появлается только если график выходит за пределы окна, до этого момента ScrollBar не существует как объект. Вопрос как написать обработчик события для диномически появляющегося объета в процессе выполнения программы???
Пробавала делать обработку события для формы (AutoScroll определен для формы) но это неработает |=> надо делать обработку события для ScrollBar.
2) Попробуй при помощи свойства Controls обнаружить, есль ли у панели скролы. Controls - это экземпляр класса ControlCollection, т.е. является коллекцией. Это свойство содержит все контролы, находящиеся на панели. Также помогутв поиске скролов методы FindControl и свойство HasControls
3) Есть так же идея в быстрой перерисовке графика при прокрутке, но для этого необходимо, чтобы каждый элемент графика (ветви, labels) был дочерним контролом относительно панели. В этом случае при перерисовке панели в обработчике нужно будет перебрать всего лишь дочерние контролы и вызвать их перерисовку. Делается это так:
void Repaint(object sender, PaintEventArgs e)
{
foreach(Control c in MyPanel.Controls)
c.OnPaint(e);
}