Synchonised ListViews

F

fanny.ricour

Hi,

I have 2 ListViews, one above the other, and I need to keep them
horizontally synchronised.
I managed to hide the bottom LV scrollbar (user is not supposed to
scroll it) and to scroll it when user clicks on the scollbar or
scrollbar arrows. However, the scrollbar does not move when the user
keep the scrollbar thingy (I don't know the right word) and move it
without releasing the mouse. And unfortunately, that's the easiest way
of scrolling !!!

Here is my code for the "chief listview" :

*************************************************************
public class ScrollerListView : System.Windows.Forms.ListView
{

#region DLL IMPORT
[DllImport("user32")]
static extern IntPtr SendMessage(IntPtr Handle, Int32 msg, IntPtr
wParam, IntPtr lParam);

[DllImport("user32.dll", SetLastError=true) ]
private static extern int GetScrollInfo(IntPtr hWnd, int n, ref
ScrollInfoStruct lpScrollInfo);

[DllImport("user32.dll")]
static extern int SetScrollInfo(IntPtr hwnd, int fnBar, ref
ScrollInfoStruct lpsi, bool fRedraw);

private struct ScrollInfoStruct
{
public int cbSize;
public int fMask;
public int nMin;
public int nMax;
public int nPage;
public int nPos;
public int nTrackPos;
}

const int SB_LINELEFT = 0;
const int SB_LINERIGHT = 1;
const int SB_PAGELEFT = 2; //same value as SB_PAGEUP
const int SB_PAGERIGHT = 3; //same value as SB_PAGEDOWN
const int SB_THUMBPOSITION = 4;
const int SB_THUMBTRACK = 5;
const int SB_LEFT = 6;
const int SB_RIGHT = 7;
const int SB_ENDSCROLL = 8;
const int WM_HSCROLL = 0x0114;

const int SBS_HORZ = 0;
const int SBS_VERT = 1;

private const int SIF_RANGE = 0x1;
private const int SIF_PAGE = 0x2;
private const int SIF_POS = 0x4;
private const int SIF_TRACKPOS = 0x10;
private const int SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS |
SIF_TRACKPOS;

#endregion

protected ListView _attachedLV;

public ScrollerListView(ListView attachedLV)
: base()
{
_attachedLV = attachedLV;
}

protected override void WndProc(ref Message m)
{
if(m.Msg == WM_HSCROLL)
{
// Scroll other listview
if (_attachedLV != null)
{
// Send scroll message to attached listview
SendMessage(_attachedLV.Handle, m.Msg, m.WParam, m.LParam);

Should move other scrollbar but does not work :(
if (m.WParam.ToInt32() == SB_THUMBTRACK
|| m.WParam.ToInt32() == SB_THUMBPOSITION)
{
ScrollInfoStruct si = new ScrollInfoStruct();
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.cbSize = Marshal.SizeOf(si);
GetScrollInfo(this.Handle, SBS_HORZ, ref si);

SetScrollInfo(_attachedLV.Handle, SBS_HORZ, ref si, true);
}
}
}
base.WndProc(ref m);
}
}

*************************************************************

I hope someone will be able to help me on this one :(
 
L

Lee Alexander

Sounds like your onto a loser here; you would also have to handle the user
changing ths size of a columns or even reorder them as well . Does your
design really have to do this? Is there a better way with the controls that
you have? If you describe the problem that needs this *solution* maybe
there's a better way?

Of the top of my head could you not use a grouped listview to acheive
something similar sort of thing but with one listview?

Regards
Lee
Hi,

I have 2 ListViews, one above the other, and I need to keep them
horizontally synchronised.
I managed to hide the bottom LV scrollbar (user is not supposed to
scroll it) and to scroll it when user clicks on the scollbar or
scrollbar arrows. However, the scrollbar does not move when the user
keep the scrollbar thingy (I don't know the right word) and move it
without releasing the mouse. And unfortunately, that's the easiest way
of scrolling !!!

Here is my code for the "chief listview" :

*************************************************************
public class ScrollerListView : System.Windows.Forms.ListView
{

#region DLL IMPORT
[DllImport("user32")]
static extern IntPtr SendMessage(IntPtr Handle, Int32 msg, IntPtr
wParam, IntPtr lParam);

[DllImport("user32.dll", SetLastError=true) ]
private static extern int GetScrollInfo(IntPtr hWnd, int n, ref
ScrollInfoStruct lpScrollInfo);

[DllImport("user32.dll")]
static extern int SetScrollInfo(IntPtr hwnd, int fnBar, ref
ScrollInfoStruct lpsi, bool fRedraw);

private struct ScrollInfoStruct
{
public int cbSize;
public int fMask;
public int nMin;
public int nMax;
public int nPage;
public int nPos;
public int nTrackPos;
}

const int SB_LINELEFT = 0;
const int SB_LINERIGHT = 1;
const int SB_PAGELEFT = 2; //same value as SB_PAGEUP
const int SB_PAGERIGHT = 3; //same value as SB_PAGEDOWN
const int SB_THUMBPOSITION = 4;
const int SB_THUMBTRACK = 5;
const int SB_LEFT = 6;
const int SB_RIGHT = 7;
const int SB_ENDSCROLL = 8;
const int WM_HSCROLL = 0x0114;

const int SBS_HORZ = 0;
const int SBS_VERT = 1;

private const int SIF_RANGE = 0x1;
private const int SIF_PAGE = 0x2;
private const int SIF_POS = 0x4;
private const int SIF_TRACKPOS = 0x10;
private const int SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS |
SIF_TRACKPOS;

#endregion

protected ListView _attachedLV;

public ScrollerListView(ListView attachedLV)
: base()
{
_attachedLV = attachedLV;
}

protected override void WndProc(ref Message m)
{
if(m.Msg == WM_HSCROLL)
{
// Scroll other listview
if (_attachedLV != null)
{
// Send scroll message to attached listview
SendMessage(_attachedLV.Handle, m.Msg, m.WParam, m.LParam);

Should move other scrollbar but does not work :(
if (m.WParam.ToInt32() == SB_THUMBTRACK
|| m.WParam.ToInt32() == SB_THUMBPOSITION)
{
ScrollInfoStruct si = new ScrollInfoStruct();
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.cbSize = Marshal.SizeOf(si);
GetScrollInfo(this.Handle, SBS_HORZ, ref si);

SetScrollInfo(_attachedLV.Handle, SBS_HORZ, ref si, true);
}
}
}
base.WndProc(ref m);
}
}

*************************************************************

I hope someone will be able to help me on this one :(
 
F

fanny.ricour

I need to have a line below my listview with information like the sum
of all the Listview lines for each column.
I don't have to do another listview, but I can't see how I can do
otherwise. The sums must be aligned with the corresponding listview
columns and when the user scrolls, it should scroll with it.
I wanted to put it in the last visible line of my listview and always
keep it there, but I don't know how to do it (knowing that it should
not be selectable and other things like that).
If you have an idea with or without the other listview, please give it
to me :)
 
L

Lee Alexander

Ah i see! Well if your using Framework 2 your in luck, there is a control
called the DataGridView that you can use to freeze either columns or rows,
i'd have a look at using that control.

If your stuck with < v2 framework then your options are:

1. Subclass the ListView control and grab a portion of the non-client area
and paint the totals in that. It's of course a bit of work with lots of
pinvoke (no guarantee that it will work).
2. Create a UserControl and plop your ListView in there and then align some
total controls at the bottom of it as you scroll around you would move them.
Not ideal as the ListView horizontal scrollbar would be between the totals
and their column siblings when it was visible.
3.Buy in a control that supports what you want (There's tons of Grids).


HTH
Regards
Lee
 

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