owner drawn ListBox repaint issues

G

Guest

I am using variable height owner-drawn ListBox using new Visual Studio 2005
Beta.
It appears to not repaint items in ListBox until I actually select them.
In the constructor of my ListBox I call the following code:

<code>
this.DrawMode = DrawMode.OwnerDrawVariable;
this.DrawItem += new DrawItemEventHandler(HandleDrawItem);
this.MeasureItem += new MeasureItemEventHandler(HandleMeasureItem);
this.HorizontalScrollbar = true;
this.MouseDown += new MouseEventHandler(HandleMouseDown);
this.MouseUp += new MouseEventHandler(HandleMouseUp);
this.SetStyle(ControlStyles.ResizeRedraw |
ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint, true);
this.UpdateStyles();
</code>

Then in the DrawItem and MeasureItem code I do the following:
<code>
public void HandleDrawItem(Object sender,DrawItemEventArgs e)
{
if (e.Index < 0) return;
e.DrawBackground();


//Draw control onto bitmap
Control ctrl = (Control)this.Items[e.Index];
//using (Image tmpImg = new Bitmap(ctrl.Bounds.Width,
ctrl.Bounds.Height))
//{
// using (Graphics g = Graphics.FromImage(tmpImg))
// {
// Utils.ControlPainter.PaintControl(g, ctrl);
// }

// ////map ctrl location to viewport coordinates
// //Point loc = ctrl.Location;
// ////top left of viewport corresponds to
// ////location of topCtrl
// //Control topCtrl = (Control)this.Items[this.TopIndex];
// //loc.Offset(-topCtrl.Location.X, -topCtrl.Location.Y);


// //g.TranslateTransform(loc.X, loc.Y);

// e.Graphics.DrawImage(tmpImg, e.Bounds);
//}
e.Graphics.DrawString("item: " + e.Index, this.Font,
Brushes.Blue, e.Bounds);

e.DrawFocusRectangle();

}

public void HandleMeasureItem(Object sender,MeasureItemEventArgs e)
{
if (e.Index >= this.Items.Count)
{
return;
}
Control ctrl = (Control)this.Items[e.Index];
ctrl.Location = nextLocation;
e.ItemHeight = ctrl.Height;
nextLocation.Y += e.ItemHeight;
e.ItemWidth = ctrl.Width;
HorizontalExtent = Math.Max(e.ItemWidth, HorizontalExtent);
}
</code>

However, the painting doesn't appear to be done until I actually select the
item.
Do I need to invalidate the whole listbox initially and then every time I
scroll?
 
G

Guest

I tried creating a new class called
OwnerDrawnListBoxPanel that contains a ListBox and
as the parent of that ListBox provides DrawItem and MeasureItem callbacks.
The repaint issue then went away. Perhaps this is due to the underlying win32
stuff -- if I remember correctly in win32 you have to have parent window
implement the draw item code unless you have message reflection.

So in short it's probably not recommended to subclass a given control and
attach event callbacks inside the constructor. I.e. don't call

this.DrawItem += ...

from within a ListBox derived class,
instead create a ListBox lb and call

lb.DrawItem += ...


dlyle said:
I am using variable height owner-drawn ListBox using new Visual Studio 2005
Beta.
It appears to not repaint items in ListBox until I actually select them.
In the constructor of my ListBox I call the following code:

<code>
this.DrawMode = DrawMode.OwnerDrawVariable;
this.DrawItem += new DrawItemEventHandler(HandleDrawItem);
this.MeasureItem += new MeasureItemEventHandler(HandleMeasureItem);
this.HorizontalScrollbar = true;
this.MouseDown += new MouseEventHandler(HandleMouseDown);
this.MouseUp += new MouseEventHandler(HandleMouseUp);
this.SetStyle(ControlStyles.ResizeRedraw |
ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint, true);
this.UpdateStyles();
</code>

Then in the DrawItem and MeasureItem code I do the following:
<code>
public void HandleDrawItem(Object sender,DrawItemEventArgs e)
{
if (e.Index < 0) return;
e.DrawBackground();


//Draw control onto bitmap
Control ctrl = (Control)this.Items[e.Index];
//using (Image tmpImg = new Bitmap(ctrl.Bounds.Width,
ctrl.Bounds.Height))
//{
// using (Graphics g = Graphics.FromImage(tmpImg))
// {
// Utils.ControlPainter.PaintControl(g, ctrl);
// }

// ////map ctrl location to viewport coordinates
// //Point loc = ctrl.Location;
// ////top left of viewport corresponds to
// ////location of topCtrl
// //Control topCtrl = (Control)this.Items[this.TopIndex];
// //loc.Offset(-topCtrl.Location.X, -topCtrl.Location.Y);


// //g.TranslateTransform(loc.X, loc.Y);

// e.Graphics.DrawImage(tmpImg, e.Bounds);
//}
e.Graphics.DrawString("item: " + e.Index, this.Font,
Brushes.Blue, e.Bounds);

e.DrawFocusRectangle();

}

public void HandleMeasureItem(Object sender,MeasureItemEventArgs e)
{
if (e.Index >= this.Items.Count)
{
return;
}
Control ctrl = (Control)this.Items[e.Index];
ctrl.Location = nextLocation;
e.ItemHeight = ctrl.Height;
nextLocation.Y += e.ItemHeight;
e.ItemWidth = ctrl.Width;
HorizontalExtent = Math.Max(e.ItemWidth, HorizontalExtent);
}
</code>

However, the painting doesn't appear to be done until I actually select the
item.
Do I need to invalidate the whole listbox initially and then every time I
scroll?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top