Discussion:
Problem with TListItem and TListColumn
(too old to reply)
Andre
2007-10-03 14:15:13 UTC
Permalink
Hello,

my program hast a item list, wich is much like Windows Explorer right
pane, in Detail mode.

But the automatic resizing of column widths is not working as I want. I
want it to accomodate the Column name (e.g. "Name", "Size", Type") and
the column item too. The width must be big enough everything is
completely show.

In TListColumn doc I find the property:

------------------------------------------------------------------------
TListColumn::WidthType

Indicates whether the column is sized automatically.

typedef int TWidth;
__property TWidth WidthType = {read=FWidth, nodefault};

Description

The read-only WidthType property indicates how the column width is
determined. WidthType is set to the same value as Width. WidthType,
however, retains its negative value when Width changes automatically.

If WidthType returns -1, the list column is automatically resized to
accommodate the text in the column. If WidthType returns -2, the list
column is automatically resized to accommodate the column header. If
WidthType returns a nonnegative value, the column is not resized
automatically; in this case, the value of Width and WidthType should be
the same.

To enable automatic column resizing, assign the value -1 or -2 directly
to Width.

------------------------------------------------------------------------

I want it to accomodate both the header and the column text. So I have
to do it by hand? How?

Thank you.

André
JD
2007-10-04 07:29:52 UTC
Permalink
[...] in Detail mode.
Do you mean that it's ViewStyle property is set to vsReport?
But the automatic resizing of column widths is not working
as I want. [...]
As you noted, that will only work for the header (which is
actually a seperate control).
I want it to accomodate both the header and the column text.
So I have to do it by hand?
Yes.
How?
Assuming that you're using the same font and font size for
both the header and the client area *and* that you're not
sizing the height of the Header to facilitate wordwrap ...

The first thing that you want to do is disable the control's
refresh. Many VCL controls have a BeginUpdate method that can
accomplish this but TListView does not so you have to use the
win32 API SendMessage to send the control a WM_SETREDRAW
message.

The reason for disabling refresh is that as you load the
TListView, you will need to measure the TextLength of the
item that you're adding and if it's length is larger than
the columns Width, you have to change the width and with
every change comes a repaint. That can *really* slow things
down and it looks like crap.

Of course, you could always just load the TListView and keep
the max-width for each column and then set all of the column
widths at the end but that too looks like crap because the
user sees the data load and then it repaints once for every
column. Besides, it's more complicated code because you need
to maintain a dynamic array of widths.

Disable refresh. Load the TListView (setting widths as you go).
Enable refresh and then Invalidate the control to paint it
once.

As you load the TListView, use it's TCanvas::TextWidth to get
the width of the current TListColumn::Caption or TListItem::Caption.
If the column width is less than that, change it.

If you are using a different font or font size in the header,
you can still accomplish what you want but it's more difficult
because the Header is a seperate control.

If you're sizing the Header's Height to accomidate wordwrap,
move that code to after you load the TListView but before you
enable refresh.

~ JD
Andre
2007-10-11 13:04:14 UTC
Permalink
Thank you. :)
Post by JD
[...] in Detail mode.
Do you mean that it's ViewStyle property is set to vsReport?
But the automatic resizing of column widths is not working
as I want. [...]
As you noted, that will only work for the header (which is
actually a seperate control).
I want it to accomodate both the header and the column text.
So I have to do it by hand?
Yes.
How?
Assuming that you're using the same font and font size for
both the header and the client area *and* that you're not
sizing the height of the Header to facilitate wordwrap ...
The first thing that you want to do is disable the control's
refresh. Many VCL controls have a BeginUpdate method that can
accomplish this but TListView does not so you have to use the
win32 API SendMessage to send the control a WM_SETREDRAW
message.
The reason for disabling refresh is that as you load the
TListView, you will need to measure the TextLength of the
item that you're adding and if it's length is larger than
the columns Width, you have to change the width and with
every change comes a repaint. That can *really* slow things
down and it looks like crap.
Of course, you could always just load the TListView and keep
the max-width for each column and then set all of the column
widths at the end but that too looks like crap because the
user sees the data load and then it repaints once for every
column. Besides, it's more complicated code because you need
to maintain a dynamic array of widths.
Disable refresh. Load the TListView (setting widths as you go).
Enable refresh and then Invalidate the control to paint it
once.
As you load the TListView, use it's TCanvas::TextWidth to get
the width of the current TListColumn::Caption or TListItem::Caption.
If the column width is less than that, change it.
If you are using a different font or font size in the header,
you can still accomplish what you want but it's more difficult
because the Header is a seperate control.
If you're sizing the Header's Height to accomidate wordwrap,
move that code to after you load the TListView but before you
enable refresh.
~ JD
Loading...