|
I've tried it but the form is still freezing and I've no control over it.
Here is the code I have in my OnPaint method.
protected override void OnPaint(PaintEventArgs e)
{
if (session == 0)
{
Graphics dc = e.Graphics;
Pen CyanPen = new Pen(Color.Cyan, 1);
Pen MagentaPen = new Pen(Color.Magenta, 1);
Pen YellowPen = new Pen(Color.Yellow, 1);
Pen BlackPen = new Pen(Color.Black, 1);
Random rnd = new Random();
int buff = 0;
for (int y = 0; y < 300; y++)
{
for (int x = 0; x < 300; x++)
{
buff = rnd.Next(0, 4);
if (buff == 0)
dc.DrawRectangle(CyanPen, x, y, 1, 1);
if (buff == 1)
dc.DrawRectangle(MagentaPen, x, y, 1, 1);
if (buff == 2)
dc.DrawRectangle(YellowPen, x, y, 1, 1);
if (buff == 3)
dc.DrawRectangle(BlackPen, x, y, 1, 1);
}
}
session++;
}
}
|
|
|
|
|
That's a lot of drawing 300 by 300 => 90000 rectagles in one session
Try putting a a this.Invalidate inside the first for and out of the second/inner for.
|
|
|
|
|
I tried your advise and still, I can't do anything on the form until the drawing is over.
|
|
|
|
|
I just realized that my first reply or message is a total ...
My bad.
All of the drawing is inside the OnPaint()!!!!
Use the fors outside the OnPaint() or better said call the paint or invalidate method
FROM the fors.
|
|
|
|
|
I see. But there is some thing that I don't understand. If I use OnPaint method, only for the painting process while randomizing in another method; how am I going to transfer my variables like color and position to the OnPaint method? I can use global variables but is it a good solution? There should be an easier and neater solution.
|
|
|
|
|
Yep. Create a method that draws.
Something like:
private void Draw(params here){
Grphics g = this.CreateGraphics();
}
And inside a for:
for(..){
Draw(params here);
this.Invalidate();
}
|
|
|
|
|
SimpleData wrote: use global variables
use class members to do so, and make sure your Paint handler executes fast.
I suggest you read this[^] little article of mine.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that. All Toronto weekends should be extremely wet until we get it automated in regular forums, not just QA.
modified on Friday, February 26, 2010 12:58 PM
|
|
|
|
|
Of course it keep freezing. In orther to respond, you need to make sure it only redraws once. And use timer.Tick event and forcfully call OnPaint by calling Invalidate(). Do not call OnPaint() directly. Invalidate works like a message pump (Or at least i think so). If it is called 3 times and redraw hasn't occourt, it will only redraw once, and clear quee.
other option is to put onto another thread. But i do not recomend. I would recomend a timer.
ps: Make sure to call dispose on a PEN, to clear unmanaged resources.
I would recomend you use only this code inside OnPaint. And make another Thread like a timer to Invalidate(), or OnPaint (Forcfully) as long as it doesn't call too frequent.
if (buff == 0)
dc.DrawRectangle(CyanPen, x, y, 1, 1);
if (buff == 1)
dc.DrawRectangle(MagentaPen, x, y, 1, 1);
if (buff == 2)
dc.DrawRectangle(YellowPen, x, y, 1, 1);
if (buff == 3)
dc.DrawRectangle(BlackPen, x, y, 1, 1);
|
|
|
|
|
This is my current code and I still have the freezing issue but I think we are getting there.
private void SetPixel(Point xy, Color clr)
{
Graphics dc = this.CreateGraphics();
Pen _pen = new Pen(clr, 1);
dc.DrawRectangle(_pen, new Rectangle( xy, new Size(1,1) ) );
_pen.Dispose(); dc.Dispose();
}
private void button1_Click_1(object sender, EventArgs e)
{
Random rnd = new Random();
int buff = 0;
for (int y = 0; y < 300; y++)
{
this.Invalidate();
for (int x = 0; x < 300; x++)
{
this.Invalidate();
buff = rnd.Next(0, 4);
if (buff == 0)
SetPixel(new Point(x,y),Color.Cyan);
else if (buff == 1)
SetPixel(new Point(x,y),Color.Magenta);
else if (buff == 2)
SetPixel(new Point(x,y),Color.Yellow);
else if (buff == 3)
SetPixel(new Point(x,y),Color.Black);
}
}
}
|
|
|
|
|
i would suggest what you have in button method you move to other thread. and it is incorect usage. you must let all drawing into OnPaint for perforamce. Invalidate prepares a message into a quee, when message pump has avaible slot, it will call OnPaint. Your Invalidate() is meanigless.
|
|
|
|
|
I now got it working. It is the incorrect usage but whatever, it seems to be working. The only problem I've left is the issue when the windows gets out of sight, the drawings I did are gone. How can I solve this?
private void SetPixel(Point xy, Color clr)
{
Graphics dc = this.CreateGraphics();
Pen _pen = new Pen(clr, 1);
dc.DrawRectangle(_pen, new Rectangle( xy, new Size(1,1) ) );
_pen.Dispose(); dc.Dispose();
}
private void button1_Click_1(object sender, EventArgs e)
{
Thread th = new Thread( new ThreadStart(Dummy) );
th.Name = "Drawer";
th.Start();
}
private void Dummy()
{
Random rnd = new Random();
int buff = 0;
for (int y = 0; y < 300; y++)
{
for (int x = 0; x < 300; x++)
{
buff = rnd.Next(0, 4);
if (buff == 0)
SetPixel(new Point(x,y),Color.Cyan);
else if (buff == 1)
SetPixel(new Point(x,y),Color.Magenta);
else if (buff == 2)
SetPixel(new Point(x,y),Color.Yellow);
else if (buff == 3)
SetPixel(new Point(x,y),Color.Black);
}
}
}
|
|
|
|
|
 I have done it:
private Bitmap bit;
private Graphics dc;
private delegate void Suspend(bool b);
private Suspend mySuspend;
private void SuspendLayoutDel(bool b)
{
if (b)
this.SuspendLayout();
else
{
this.ResumeLayout();
Invalidate(true);
}
}
private void SetPixel(Point xy, Color clr, Graphics dc)
{
Pen _pen = new Pen(clr, 1);
lock(dc)
{
dc.DrawRectangle(_pen, new Rectangle(xy, new Size(1, 1)));
}
_pen.Dispose();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (bit == null)
{
bit = new Bitmap(300, 300);
dc = Graphics.FromImage(bit);
}
e.Graphics.DrawImage(bit,0,0);
}
private void button1_Click(object sender, EventArgs e)
{
mySuspend = new Suspend(SuspendLayoutDel);
Thread th = new Thread(new ThreadStart(Dummy));
th.Name = "Drawer";
th.Start();
}
private void Dummy()
{
this.Invoke(mySuspend, new Object[]{true});
Random rnd = new Random();
int buff = 0;
for (int y = 0; y < 300; y++)
{
for (int x = 0; x < 300; x++)
{
buff = rnd.Next(0, 4);
if (buff == 0)
SetPixel(new Point(x, y), Color.Cyan,dc);
else if (buff == 1)
SetPixel(new Point(x, y), Color.Magenta, dc);
else if (buff == 2)
SetPixel(new Point(x, y), Color.Yellow, dc);
else if (buff == 3)
SetPixel(new Point(x, y), Color.Black, dc);
}
}
this.Invoke(mySuspend, new Object[] { false });
}
I used graphic to draw to bitmap. Aka to memory. After all is displayed, it draws on screen. This aproach is olmost instantly compared to draw directly to screen.
|
|
|
|
|
CreateGraphics() is an expensive method (expect everything with Create in its name to be expensive and slow); you should really do without it.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that. All Toronto weekends should be extremely wet until we get it automated in regular forums, not just QA.
|
|
|
|
|
Hi,
i want an application quadtree with images like google map
for example,
i enter one name that name must be search in image using quad tree concept
using c#.net
please help me
|
|
|
|
|
What colour would you like it in?
|
|
|
|
|
Mauve. It has the most RAM."WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
ROTFL! Dalek Dave: There are many words that some find offensive, Homosexuality, Alcoholism, Religion, Visual Basic, Manchester United, Butter.
|
|
|
|
|
Using DotNet 3.5...
I found the following code on the net (I don't remember exactly where, but I do know it's conglomeration of a couple of different examples). It's a ListView extension method that's responsible for putting a sort direction arrow in the column header. The problem is that it places the arrow above the column header text and centers the arrow in the column. I've made a couple of attempts to try to get the arrow to be laced on the right side of the column, but nothing has worked.
My last attempt was to add the line after the switch(order) statement that adds the HDF_BITMAP_ON_RIGHT flag. Can anyone help?
[EditorBrowsable(EditorBrowsableState.Never)]
public static class ListViewExtensions
{
[StructLayout(LayoutKind.Sequential)]
protected struct LVCOLUMN
{
public Int32 mask;
public Int32 cx;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszText;
public IntPtr hbm;
public Int32 cchTextMax;
public Int32 fmt;
public Int32 iSubItem;
public Int32 iImage;
public Int32 iOrder;
}
const Int32 HDI_WIDTH = 0x0001;
const Int32 HDI_HEIGHT = HDI_WIDTH;
const Int32 HDI_TEXT = 0x0002;
const Int32 HDI_FORMAT = 0x0004;
const Int32 HDI_LPARAM = 0x0008;
const Int32 HDI_BITMAP = 0x0010;
const Int32 HDI_IMAGE = 0x0020;
const Int32 HDI_DI_SETITEM = 0x0040;
const Int32 HDI_ORDER = 0x0080;
const Int32 HDI_FILTER = 0x0100;
const Int32 HDF_LEFT = 0x0000;
const Int32 HDF_RIGHT = 0x0001;
const Int32 HDF_CENTER = 0x0002;
const Int32 HDF_JUSTIFYMASK = 0x0003;
const Int32 HDF_RTLREADING = 0x0004;
const Int32 HDF_OWNERDRAW = 0x8000;
const Int32 HDF_STRING = 0x4000;
const Int32 HDF_BITMAP = 0x2000;
const Int32 HDF_BITMAP_ON_RIGHT = 0x1000;
const Int32 HDF_IMAGE = 0x0800;
const Int32 HDF_SORTUP = 0x0400;
const Int32 HDF_SORTDOWN = 0x0200;
const Int32 LVM_FIRST = 0x1000;
const Int32 LVM_GETHEADER = LVM_FIRST + 31;
const Int32 HDM_FIRST = 0x1200;
const Int32 HDM_SETIMAGELIST = HDM_FIRST + 8;
const Int32 HDM_GETIMAGELIST = HDM_FIRST + 9;
const Int32 HDM_GETITEM = HDM_FIRST + 11;
const Int32 HDM_SETITEM = HDM_FIRST + 12;
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", EntryPoint = "SendMessage")]
private static extern IntPtr SendMessageLVCOLUMN(IntPtr hWnd, Int32 Msg, IntPtr wParam, ref LVCOLUMN lPLVCOLUMN);
public static void SetSortIcon(this ListView listView, int columnIndex, SortOrder order)
{
IntPtr columnHeader = SendMessage(listView.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
for (int columnNumber = 0; columnNumber <= listView.Columns.Count - 1; columnNumber++)
{
IntPtr columnPtr = new IntPtr(columnNumber);
LVCOLUMN lvColumn = new LVCOLUMN();
lvColumn.mask = HDI_FORMAT;
SendMessageLVCOLUMN(columnHeader, HDM_GETITEM, columnPtr, ref lvColumn);
if (!(order == SortOrder.None) && columnNumber == columnIndex)
{
switch (order)
{
case SortOrder.Ascending:
lvColumn.fmt &= ~HDF_SORTDOWN;
lvColumn.fmt |= HDF_SORTUP;
break;
case SortOrder.Descending:
lvColumn.fmt &= ~HDF_SORTUP;
lvColumn.fmt |= HDF_SORTDOWN;
break;
}
lvColumn.fmt |= (HDF_LEFT | HDF_BITMAP_ON_RIGHT);
}
else
{
lvColumn.fmt &= ~HDF_SORTDOWN & ~HDF_SORTUP & ~HDF_BITMAP_ON_RIGHT;
}
SendMessageLVCOLUMN(columnHeader, HDM_SETITEM, columnPtr, ref lvColumn);
}
}
} .45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
namespace JSOPTest
{
[EditorBrowsable(EditorBrowsableState.Never)]
public static class ExListView
{
[StructLayout(LayoutKind.Sequential)]
private struct LVCOLUMN
{
public Int32 mask;
public Int32 cx;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszText;
public IntPtr hbm;
public Int32 cchTextMax;
public Int32 fmt;
public Int32 iSubItem;
public Int32 iImage;
public Int32 iOrder;
}
private const Int32 HDI_FORMAT = 0x4;
private const Int32 HDF_SORTUP = 0x400;
private const Int32 HDF_SORTDOWN = 0x200;
private const Int32 LVM_GETHEADER = 0x101f;
private const Int32 HDM_GETITEM = 0x120b;
private const Int32 HDM_SETITEM = 0x120c;
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(
IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", EntryPoint = "SendMessage")]
private static extern IntPtr SendMessageLVCOLUMN(IntPtr hWnd,
Int32 Msg,
IntPtr wParam,
ref LVCOLUMN lPLVCOLUMN);
public static void SetSortIcon(ListView ListViewControl,
int ColumnIndex,
SortOrder Order)
{
IntPtr ColumnHeader = SendMessage(ListViewControl.Handle,
LVM_GETHEADER,
IntPtr.Zero, IntPtr.Zero);
for (int ColumnNumber = 0;
ColumnNumber <= ListViewControl.Columns.Count - 1;
ColumnNumber++)
{
IntPtr ColumnPtr = new IntPtr(ColumnNumber);
LVCOLUMN lvColumn = new LVCOLUMN();
lvColumn.mask = HDI_FORMAT;
SendMessageLVCOLUMN(ColumnHeader, HDM_GETITEM, ColumnPtr, ref lvColumn);
if (!(Order == SortOrder.None) && ColumnNumber == ColumnIndex)
{
switch (Order)
{
case SortOrder.Ascending:
lvColumn.fmt &= ~HDF_SORTDOWN;
lvColumn.fmt |= HDF_SORTUP;
break;
case SortOrder.Descending:
lvColumn.fmt &= ~HDF_SORTUP;
lvColumn.fmt |= HDF_SORTDOWN;
break;
}
}
else
{
lvColumn.fmt &= ~HDF_SORTDOWN & ~HDF_SORTUP;
}
SendMessageLVCOLUMN(ColumnHeader, HDM_SETITEM, ColumnPtr, ref lvColumn);
}
}
}
} "WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
That's what I started out with. It gives me the sort arrow, but it's positioned above the text, and centered horizontally in the column header.
Mine is different only with respect the extra const members, the renaming of some of the variables using in the extension method, and the attempted use of the extra flag after the switch statement.
On a side note, I don't understand why Microsoft would omit this feature (and others) from the list control in the first place. Programmers have always need to add extra code to implement stuff that should - by now - be part of the control itself..45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
That's kind of odd because this is code I ripped out of an old winforms project that I have, and it gave the arrow where you'd expect it. Granted it was a .NET 2 project, but I don't see that as having an effect."WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
I even thought it might have something to do with the orientation of the header text, so I made them all Left, but that didn't have any effect either..45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
I created a new project with an unmolested listview control, dropped the code into it, and it still does it. Could it be a Windows 7 thing?.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
Possibly. I'll try it out later on."WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
It's a Windows 7 thing. The icon in Windows 7 appears centred above the text."WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|