Indicating an Empty ListView in C#
Introduction
Have you wondered how you couldshow text in ListView control if it's empty, just like Microsoft doesit in Outlook Express and in some other applications?
Background
OnPaint() won't work
If you're thinking about OnPaint() event,forget it. ListView control is just a wrapper around the control inComCtl and it doesn't fire this event.
UserControl: 100% pure C# solution but complicated
Another clean solution would be to makeyour own UserControl with one ListView and one label on the top whichcould be visible only if ListView would be empty, but there is onelittle problem with column resizing which draws a dark line on thecontrol which goes under the label control which doesn't look veryprofessional. We could possibly cover whole listview background, butthen we would find problems with not showing scrollbars… well, fixingone problem creates another one… and so on…
Using the code
Probably the best solution is tooverride WndProc method with something like this. If m.MSG == 20listview calls function to redraw background, so we just draw somestring on top of it if listView doesn't contain any items.
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == 20)
{
if (this.Items.Count == 0)
{
_b = true;
Graphics g = this.CreateGraphics();
int w = (this.Width – g.MeasureString(_msg, this.Font).ToSize().Width)/2;
g.DrawString(_msg, this.Font, SystemBrushes.ControlText, w, 30);
}
}
}

Well now it does what we need butsooner or later we will find out that this solution is not perfect. Ifyou will try to resize the whole control, or only one of the columns,or if you add a new item to the listView and part or whole of your textstring will be outside of the column's area, listView will becamepretty messy. Improved overrided WndProc method, which is fixing allthose problems, is here.
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == 20)
{
if (this.Items.Count == 0)
{
_b = true;
Graphics g = this.CreateGraphics();
int w = (this.Width – g.MeasureString(_msg, this.Font).ToSize().Width)/2;
g.DrawString(_msg, this.Font, SystemBrushes.ControlText, w, 30);
}
else
{
if (_b)
{
this.Invalidate();
_b = false;
}
}
}
if (m.Msg == 4127) this.Invalidate();
}
Yes, and we shouldn't forget to redraw the whole control on Resize event if listView is empty and showing our text string
private void ListView2_Resize(object sender, EventArgs e)
{
if (_b) Invalidate();
}
Download Source
That's it
Up-to-date version of this article can be found on http://www.hasko.com.au/blog/












No comments yet... Be the first to leave a reply!