Ręczne rozmieszczenie elementów kontrolki ListView.

0

Mam kilka pytań związanych z kontrolką ListView.

1.) Kontrolka standardowo posiada 5 widoków - LargeIcon, SmallIcon, Details, List,Tile. Dla każdego widoku ustawiane są standardowe wymiary elementu (Item). Problem z tym, że ja w swojej aplikacji potrzebuje ręcznie ustawić rozmiar elementu. Napisałem kod w WIN32API następujący :

 hwndList = GetDlgItem(hwndDlg, IDC_LIST);// Pobranie uchwytu do okna IDC_LIST.
ListView_SetImageList(hwndList, himlFilesSmall, LVSIL_NORMAL);// Dodaj do kontrolki IDC_LIST obrazki, LVSIL_NORMAL -> LargeIcon
ListView_SetView(hwndList, LV_VIEW_TILE);
LVITEM lvi;// Struktura zawierająca informacje o obrazkach w kontrolce LIST.
ZeroMemory(&lvi, sizeof(lvi));	// Wyczyść strukture.
lvi.mask = LVIF_PARAM | LVIF_IMAGE;
lvi.iImage = 0;
lvi.lParam = -1;
for(y=0; y<20; y++)
{
	for(x=0; x<20; x++)
	{
		lvi.iItem = 9999;
		lvi.iItem = ListView_InsertItem(hwndList, &lvi);// Wstaw nowy element. Zwraca kolejny indeks 1,2,3,4, ... etc.
		ListView_SetItemPosition(hwndList, lvi.iItem, x * TILE_WDH, y * TILE_HGH);
	}
}

i wszystko działa ładnie tworze sobie macierz elementów (20x20) gdzie każdy element ma wymiary (TILE_WDHxTILE_HGH).
Pytanie jest niby proste jak ustawić ręcznie pozycje elementów kontrolki ListView, kontrolka nie posiada metody SetItemPosition (w MFC jest). Zaznaczam, że oszukałem sie rozwiązania ale nic konkretnego nie znalazłem. Próbowałem też kombinować ze zdarzeniem DrawItem kontroli ListView co prawda można w niej pobrać wartości x ,y, szerokość, wysokość elemetnu listy, przykład :

 private void Form1_Load(object sender, EventArgs e)
        {          
            int i = 0;
            listView1.View = View.LargeIcon;            
            for (y = 0; y < 20; y++)
                for (x = 0; x < 20; x++)
                {
                    lvi = new ListViewItem();                         
                    lvi.Text = "IMG" + i.ToString();
                    lvi.Position = new Point(x * TILE_WDH, y * TILE_HGH); // ?????        
                    listView1.Items.Add(lvi);                   
                    i++;   
                }
        }
private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
      int iX = e.Item.Position.X;
      int iY = e.Item.Position.Y;
      int iWidth = e.Item.Bounds.Width;
      int iHeight = e.Item.Bounds.Height;
      e.Item.Position = new Point(x, y); // Zmiana parametrów X,Y elementu nic nie daje.
      Rectangle rect = new Rectangle(e.Item.Position.X, e.Item.Position.Y,e.Item.Bounds.Width, e.Item.Bounds.Height);
      e.Graphics.FillRectangle(new SolidBrush(Color.Yellow), rect);
      e.Graphics.DrawRectangle(Pens.Black, rect);   
      e.Graphics.DrawString(e.Item.Text, new Font("Arial", 9, FontStyle.Regular), Brushes.Black, e.Item.Position.X, e.Item.Position.Y);

}

można nawet niby ustawić konkretny element e.Item.Position = new Point(x, y); ale i tak przy rysowaniu wartości x,y są automatycznie pobierane na podstawie widoku (View -> LargeIcon, etc...)

2.) Jak do kontrolki ListView dodać VScroolBar ? HScroolBar pojawia automatycznie jak liczba elementów (a raczej ich rozmiar) przekracza wysokość okna ListView. Jak wyłączyć zawijanie elementów listy tak żeby przekraczały szerokość okna ListView, żeby nie były wyświetlane poziom niżej w momencie przekroczenia szerokości ListView.

3.) Jakiego zdarzenia użyć do odświeżania zawartości kontrolki w momencie przesuwania ScoolBar-a ? (w WIN32API -> jest to zdarzenie WM_HSCROLL )

Byłbym bardzo wdzięczny za pomoc bo bardzo potrzebuje rozwiązania. :-(

0
  1. tak sie sklada, ze .Net'owe ListView ma metode SetitemPosition, tylko ... niedostepna dla normalnych klientow (metoda ma dostep 'internal').. no, ale od czego reflection? jesli sadzisz, ze ta metoda by Ci pomogla, sprobuj pobawic sie z:
private void rfl_ListView_SetItemPosition(ListView listview, int index, int x, int y)
{   typeof(ListView).GetMethod("SetItemPosition", BindingFlags.Instance|BindingFlags.Nonpublic).Invoke(listview, new object[]{index, x, y});
}

a co do wielkosci ikonki... to czy to aby nie jest .net'owe property int ListView::TileSize ?!

  1. nie jestem pewien, ale wydaje mi sie, ze VScroll jest dostepny w 100% automatycznie jezeli tylko xy+wdthheight elementu/ikony wyjda poza jej clientarea. jestes pewien ze potrzebujesz recznie go wlaczac? imho, to ze nie widzisz vscrolla wynika wprost z punktu 1) i klopotow z ustawieniem xy elementu tak by wychodzil poza obszar roboczy.. jesli metoda z 1) zadziala - vscroll powinien sam sie pojawic

  2. nie sadze zebys potrzebowal w ogole oprogramowywac scrollbar. jak wypelnisz liste prawidlowo elementami, wszystko powinno samo ruszyc..

1 użytkowników online, w tym zalogowanych: 0, gości: 1