![]() |
Desktop Development »
List Controls »
ListView controls
Intermediate
License: The BSD License
Scrolling to a group with a ListViewBy Lord ZoltarAdd the functionality to scroll to a group in a ListView |
C# (C# 1.0, C# 2.0, C# 3.0), Windows, .NET, WinForms, Dev
|
||||||||
|
Advanced Search |
|
|
|
||||||||||||||||
I had some data that I needed to display in a listview. The data was represented by images, and sorted into groups. Since there could be dozens (hundreds?) of images, I thought it would be useful to be able to jump to any group using buttons (1 button per group). Unfortunately, scrolling to a group is not something that the .NET ListView control supports out of the box.
Above is a screenshot of 4 buttons that scroll the listview to 4 groups.
The first time I tried to implement scroll-to-a-group, I used the EnsureVisible method on the first list item in a group. This works, but it's not great. The problem is that the control will scroll just enough to make the item visible, and that could mean making it visible at the top or bottom of the control. If you have many 16x16 icons, it takes several seconds to find the item that you just EnsureVisible'd. With EnsureVisible, nothing will happen if the item is already visible. Also, EnsureVisible can only be applied to ListViewItems, not to ListViewGroups (but Groups is what I wanted). The other method that was suggested to me was to use the TopItem method. This cannot be used if the ListView's view mode is LargeIcon or SmallIcon or Tile (I was using LargeIcon), so TopItem was out of the question.
Usage is simple: Add the AdvancedListView class to your project. When you want to scroll to a group, pass the group's name or index to AdvancedListView.ScrollToGroup() and you will see your ListView scroll so that the group header is right at the top of the control.
myListView.ScrollToGroup(myListViewItem.Group.Name);
The main trick to getting this to work was realizing that the .NET framework just couldn't scroll to a group. I needed to use the SendMessage function to send a LVM_SCROLL message to the ListView control. In discussion forums, it had often been suggested to use WM_VSCROLL, but this did NOT work. Using WM_VSCROLL, I was only able to move the scrollbar, but could not scroll the contents. The LVM_SCROLL message allows the listview contents to be scrolled as well.
This message takes two values, which are used to determine how much to scroll the listview by, relative to its CURRENT scroll position. The problem with this is that the position of the group is an absolute position, based on the position of the first item in the group:
myListViewGroup.Items[0].Position.Y - 30
to get the correct amount to scroll by, we need to first get the current scroll position, using the API function GetScrollInfo:
int prevScrollPos = 0;
SCROLLINFO currentInfo = new SCROLLINFO();
currentInfo.cbSize = Marshal.SizeOf(currentInfo);
currentInfo.fMask = (int)ScrollInfoMask.SIF_ALL;
GetScrollInfo(this.Handle, (int)ScrollBarDirection.SB_VERT, ref currentInfo)
prevScrollPos = currentInfo.nPos;
//The LVM_SCROLL message will take a delta-x and delta-y which tell the list view how
//much to scroll, relative to the current scroll positions. We are given the scroll
//position as an absolute position, so some adjustments are necessary:
scrollPos -= prevScrollPos;
As it turns out, there are MANY ListView messages. You can see all of them here:
http://msdn.microsoft.com/en-us/library/cc656508(VS.85).aspx
I used a very simple structure for the one message that I needed:
private enum ListViewMessages : int
{
LVM_FIRST = 0x1000,
LVM_SCROLL = (LVM_FIRST + 20)
}
SendMessage(listViewHandle, (uint)ListViewMessages.LVM_SCROLL, (IntPtr)scrollAmtX, (IntPtr)scrollAmtY);
July 5 2008: Added a screenshot, added a bit more explanation.
| You must Sign In to use this message board. | |||||||||||||||
|
|||||||||||||||
|
|||||||||||||||
|
|||||||||||||||
|
|||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 4 Jul 2008 Editor: |
Copyright 2008 by Lord Zoltar Everything else Copyright © CodeProject, 1999-2009 Web20 | Advertise on the Code Project |