|
I got this working quite well on my Windows 10 project in 2021. Had to make a few adjustments but perfect for my needs. Arrow doesn't work, but double click does so it doesn't really matter to me. Seems solid. Thank you Charles for sharing it - 12 years ago (:
What I cannot figure out though, is the font for the Group headers. Mine is coming out Blue and maybe 10 pixel. I can adjust all the other fonts, but can't see where the Header font is coming from in this project.
Based on my reading, you can't change the group font or it's hard to change the font for the group. But, in this project - it's a different size from my lIstView Items. Anyone know where that group header font comes from in this project and if I can change it.
|
|
|
|
|
Calling the method SetGroupCollapse(GroupState state) on Windows 10 instantly causes the program to crash without exception. LVGROUP 's struct size should be Marshal.SizeOf(typeof(LVGROUP)) not Marshal.SizeOf(group) .
|
|
|
|
|
Thank you very much for sharing.
Do you see any chance to align the collapse/expand icon on the left side of the group header?
|
|
|
|
|
Once you used a Form and a MDI form try to put your Codes to the Form and Then call it to the MDI FORM..
at first the collapsed procedure is working but try to create another form and try to show it while the form with the ListviewGroup is showed. then call the New Form.. then try to open the Form with the listviewgroup.. the collapsed icon will gone.. 
|
|
|
|
|
Here are two fixes to make this awesome hack work flawlessy:
Fix the x86 error:
In the SetGroupCollapse method, replace
Marshal.StructureToPtr(group, ip, true);
with
Marshal.StructureToPtr(group, ip, false);
To get the arrows working, override WndProc like this:
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case NativeMethods.WM_LBUTTONUP:
base.DefWndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
|
|
|
|
|
thx for this solution..
but i get confused. where i have to put override WndProc?
and how to use it?
|
|
|
|
|
You just have to put it into the class which is inheriting from ListView (it's a normal method).
|
|
|
|
|
To make the sample work, add a class inheriting from ListView to the MainForm class in MainForm.cs. Then replace the two references to System.Windows.Forms.ListView in MainForm.Designer.cs with your extended class. For example, add the following as a nested class within MainForm
public class ExtListView : ListView
{
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0x202:
base.DefWndProc(ref m);
base.WndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
}
and then change
this.aoc = new System.Windows.Forms.ListView(); to
this.aoc = new ExtListView(); and
private System.Windows.Forms.ListView aoc; to
private ExtListView aoc; in the designer code.
|
|
|
|
|
It seems that it would be better to change WM_LBUTTONUP handler to the following one:
case WM_LBUTTONUP:
base.DefWndProc(ref m);
base.WndProc(ref m);
break;
Both DefWndProc and WndProc should be called. Otherwise either DoubleClick event may not be fired or collapse group arrow will not work... I have just run into this problem on Windows 8.
|
|
|
|
|
Thanks! Just had the exact same issue.
|
|
|
|
|
Hi sir! Good code, but why when I click the button from the group bar on each group bar, doesn't work? The button I mean, is located in the right of each ListViewGroup. Thanks!
|
|
|
|
|
Hello,
I am opening the MainForm of this Project from another Form called Form1 in the button click event.
For the first button click in Form1 i am able to collapse/expand Listview Groups, but for the next button clicks i'm unable to collapse/expand Listview Groups.
Please help me..
|
|
|
|
|
i encountered that too, but still now i dont have any idea how to fix it.. gush...
|
|
|
|
|
I downloaded the source code, Win 7, executed the project without changing anything and it throws an exception at the Marshl.StructureToPtr()
|
|
|
|
|
Sorry, I am running a 64-bit machine, just forced 32 bit and it worked.
|
|
|
|
|
 Use this class for x86 and x64
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode), Description("LVGROUP StructureUsed to set and retrieve groups.")]
internal class LVGROUP
{
[Description("Size of this structure, in bytes.")]
public int CbSize = Marshal.SizeOf(typeof(LVGROUP));
[Description("Mask that specifies which members of the structure are valid input. One or more of the following values:LVGF_NONE No other items are valid.")]
public int Mask;
[Description("Pointer to a null-terminated string that contains the header text when item information is being set. If group information is being retrieved, this member specifies the address of the buffer that receives the header text.")]
[MarshalAs(UnmanagedType.LPWStr)]
public string PszHeader;
[Description("Size in TCHARs of the buffer pointed to by the pszHeader member. If the structure is not receiving information about a group, this member is ignored.")]
public int CchHeader;
[Description("Pointer to a null-terminated string that contains the footer text when item information is being set. If group information is being retrieved, this member specifies the address of the buffer that receives the footer text.")]
[MarshalAs(UnmanagedType.LPWStr)]
public string PszFooter;
[Description("Size in TCHARs of the buffer pointed to by the pszFooter member. If the structure is not receiving information about a group, this member is ignored.")]
public int CchFooter;
[Description("ID of the group.")]
public int IGroupId;
[Description("Mask used with LVM_GETGROUPINFO (Microsoft Windows XP and Windows Vista) and LVM_SETGROUPINFO (Windows Vista only) to specify which flags in the state value are being retrieved or set.")]
public int StateMask;
[Description("Flag that can have one of the following values:LVGS_NORMAL Groups are expanded, the group name is displayed, and all items in the group are displayed.")]
public int State;
[Description("Indicates the alignment of the header or footer text for the group. It can have one or more of the following values. Use one of the header flags. Footer flags are optional. Windows XP: Footer flags are reserved.LVGA_FOOTER_CENTERReserved.")]
public uint UAlign;
[Description("Windows Vista. Pointer to a null-terminated string that contains the subtitle text when item information is being set. If group information is being retrieved, this member specifies the address of the buffer that receives the subtitle text. This element is drawn under the header text.")]
public IntPtr PszSubtitle;
[Description("Windows Vista. Size, in TCHARs, of the buffer pointed to by the pszSubtitle member. If the structure is not receiving information about a group, this member is ignored.")]
public uint CchSubtitle;
[Description("Windows Vista. Pointer to a null-terminated string that contains the text for a task link when item information is being set. If group information is being retrieved, this member specifies the address of the buffer that receives the task text. This item is drawn right-aligned opposite the header text. When clicked by the user, the task link generates an LVN_LINKCLICK notification.")]
[MarshalAs(UnmanagedType.LPWStr)]
public string PszTask;
[Description("Windows Vista. Size in TCHARs of the buffer pointed to by the pszTask member. If the structure is not receiving information about a group, this member is ignored.")]
public uint CchTask;
[Description("Windows Vista. Pointer to a null-terminated string that contains the top description text when item information is being set. If group information is being retrieved, this member specifies the address of the buffer that receives the top description text. This item is drawn opposite the title image when there is a title image, no extended image, and uAlign==LVGA_HEADER_CENTER.")]
[MarshalAs(UnmanagedType.LPWStr)]
public string PszDescriptionTop;
[Description("Windows Vista. Size in TCHARs of the buffer pointed to by the pszDescriptionTop member. If the structure is not receiving information about a group, this member is ignored.")]
public uint CchDescriptionTop;
[Description("Windows Vista. Pointer to a null-terminated string that contains the bottom description text when item information is being set. If group information is being retrieved, this member specifies the address of the buffer that receives the bottom description text. This item is drawn under the top description text when there is a title image, no extended image, and uAlign==LVGA_HEADER_CENTER.")]
[MarshalAs(UnmanagedType.LPWStr)]
public string PszDescriptionBottom;
[Description("Windows Vista. Size in TCHARs of the buffer pointed to by the pszDescriptionBottom member. If the structure is not receiving information about a group, this member is ignored.")]
public uint CchDescriptionBottom;
[Description("Windows Vista. Index of the title image in the control imagelist.")]
public int ITitleImage;
[Description("Windows Vista. Index of the extended image in the control imagelist.")]
public int IExtendedImage;
[Description("Windows Vista. Read-only.")]
public int IFirstItem;
[Description("Windows Vista. Read-only in non-owner data mode.")]
public IntPtr CItems;
[Description("Windows Vista. NULL if group is not a subset. Pointer to a null-terminated string that contains the subset title text when item information is being set. If group information is being retrieved, this member specifies the address of the buffer that receives the subset title text.")]
public IntPtr PszSubsetTitle;
[Description("Windows Vista. Size in TCHARs of the buffer pointed to by the pszSubsetTitle member. If the structure is not receiving information about a group, this member is ignored.")]
public IntPtr CchSubsetTitle;
public override string ToString()
{
return ("LVGROUP: header = " + this.PszHeader.ToString() + ", iGroupId = " + this.IGroupId.ToString(System.Globalization.CultureInfo.InvariantCulture));
}
}
|
|
|
|
|
|
Listview may get repaint issue when groups are collapsing or expanding with scrollbar presenting or disappearing. Tested on Win7.
A picture means everything.
http://hi.csdn.net/attachment/201105/27/1705918_1306468648h8Tc.jpg[^]
Follow up on 26/7/2011: API call SendMessage to force a redraw:
Public Property Let AllowRedraw(bRedraw As Boolean)
If m_hListView Then
Call SendMessage(m_hListView, WM_SETREDRAW, Abs(CLng(bRedraw)), 0&)
m_AllowRedraw = bRedraw
End If
End Property
modified on Tuesday, July 26, 2011 5:43 AM
|
|
|
|
|
I'd tried to do this exact same thing before, but never quite managed it. Your code showed me where I was going wrong. Cheers!
|
|
|
|
|
|
- The strings in LVGROUP should be LPWStr, not LPTStr. Check the windows headers.
- Why write your own marshaling code when you can just declare LVGROUP as ref param.
- Group id: someone else already mentioned it.
- Design: collapsible/collapsed should be properties of the group, as in win32 api. Yes, the group and group collection can't be inherited, but there're ways around it, and they can be added to work with the designer as if the properties come from the groups.
- Other misc stuffs like the use of const literals, exception handling...
All these are rather trivial, and that's why the article level is beginner.
|
|
|
|
|
In your "Design" issue you mention ways to add the functionality to the class and/or designer, could you point me in the direction of some information or examples on how this might be accomplished. Thanks.
|
|
|
|
|
Trivial stuff for Vista only...
|
|
|
|
|
I wouldn't say this is trivial. Not many people understand how to use interop code or even that you can use interop code to change the behavior of the standard .NET winforms controls.
List view grouping is also supported on Windows XP and later, including Vista and Win7. Being able to collapse the groups is Vista and later.
Scott Dorman Microsoft® MVP - Visual C# | MCPD
President - Tampa Bay IASA
[ Blog][ Articles][ Forum Guidelines] Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
|
|
|
|
|