Zdravím, mám pár problémů s ListViewem... Je toho docela dost tak se předem omlouvám, ale bude to hodně dlouhé :)
1) potřebuju modifikovat ListView tak, aby měl onScroll event.
Takže jsem si napsal třídu ListViewEx, která dědí původní Windows.Forms.ListView a má navíc event onScroll a má trochu poupravený WndProc. A zrovna tady mám problém...
Hledal jsem na internetu, jak detekovat scroll atd... a našel jsem, že musím detekovat zprávu WM_VSCROLL. Takže už bez problémů detekuju scrollování, ale potřebuju ještě detekovat dodatečné informace. Informace o tom, jak se scrolluje a o kolik by měla být uložená v parametru zprávy WParam. V klasickém WinApi bych si napsal switch ze kterého bych dostal vše co potřebuju
např.
GetScrollInfo (hwnd, SB_HORZ, &si);
xPos = si.nPos;
switch (LOWORD (wParam))
{
// user clicked left arrow
case SB_LINELEFT:
si.nPos -= 1;
break;
// user clicked right arrow
case SB_LINERIGHT:
si.nPos += 1;
break;
// user clicked the scroll bar shaft left of the scroll box
case SB_PAGELEFT:
si.nPos -= si.nPage;
break;
// user clicked the scroll bar shaft right of the scroll box
case SB_PAGERIGHT:
si.nPos += si.nPage;
break;
// user dragged the scroll box
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
default :
break;
}
( více viz http://msdn.microsoft.com/en-us/library/bb787531%28VS.85%29.aspx ) ale v C# bohužel není makro LOWORD() a tak nevím, jak dostat nižších 16 bitů ke kterým by se pak hodil podobný switch...
Zatím modifikovaný ListView vypadá takto:
public class ListViewEx : ListView
{
// from WinUser.h
private const int WM_PAINT = 0x000F;
private const int WM_VSCROLL = 0x0115;
public enum WM_VSCROLLINFO : short
{
SB_BOTTOM = 7,
SB_LINEDOWN = 1,
SB_LINEUP = 0,
SB_PAGEDOWN = 3,
SB_PAGEUP = 2,
SB_TOP = 6
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_VSCROLL)
{
onScroll(this, new EventArgs());
}
}
public event EventHandler onScroll;
}
umí tedy generovat onScroll event, ale zatím tam nejsou žádné informace o tom kam se scrolluje atd...
2) Nevím, jak posunout více položek na začátek nebo na konec ListViewu.
(tedy principiálně vím, ale když posunu jednu z vybraných položek tak se mi změní pořadí položek v ListView.SelectedItems a znovu posunu tu stejnou položku :( )
Ještě pro ukázku kód posunutí na začátek:
private void button1_Click(object sender, EventArgs e)
{
// Na začátek
if (1 == listView1.SelectedItems.Count)
{
ListViewItem item = listView1.SelectedItems[0];
int index;
index = item.Index;
index = 0;
if (index < listView1.Items.Count)
{
listView1.Items.Remove(item);
listView1.Items.Insert(index, item);
}
}
else
{
for (int x = listView1.SelectedItems.Count - 1; x >= 0; x--)
{
ListViewItem item = listView1.SelectedItems[x];
int index;
index = 0;
listView1.Items.Remove(item);
listView1.Items.Insert(index, item);
}
}
}
a teď co to dělá:
1. průchod cyklu:
------------
ListView1.SelectedItems[0] je 1. položka
ListView1.SelectedItems[1] je 2. položka
------------
2. průchod cyklu:
------------
ListView1.SelectedItems[0] je 2. položka
ListView1.SelectedItems[1] je 1. položka
tzn. že 1. průchod cyklu posune 2. položku na začátek ListViewu a druhý průchod cyklu znovu posune tu samou položku znovu na začátek. Tzn. dojde k posunutí pouze 1 položky.
3) Posunování prvků v ListView při použití Groups.
(Myslím že sem někde dokonce našel, že je v tom skutečně bug v zobrazování a byla tam i použita nějaká funkce na opravu, myslím že nějaké překreslení, ale nefungovalo mi to :( )
Při posunování prvků v ListView za použití Groups dojde skutečně k posunutí prvku v Items, ale zobrazí na konci ListViewu :(