C# - ListBox kontrol gyorstippel

forráskód letöltése
A fájlkezelő alkalmazásokban gyakori, hogy a hosszú állománynevekre fókuszálva gyorstippszerűen megjelenik a név teljes hosszában. Alkalmazásainkban is találkozhatunk olyan problémával, hogy egy lista túl hosszú karakterláncokat tartalmaz, azonban a listát tároló kontrol méretét nem akarjuk a leghosszabb karakterlánchoz igazítani, mert ezzel hasznos területet foglalunk el fölöslegesen. Ennek érdekében hasznos, ha az adott kontrol szükség esetén képes a szöveget megfelelő hosszában megjeleníteni. Cikkünkben elkészítünk egy ilyen képességekkel rendelkező ListBox kontrolt.
A megvalósítást most a legegyszerűbben végezzük el, vagyis egy ToolTip objektumot használunk arra, hogy szükség esetén a lista adott listaelemének teljes nevét megjelenítse.
private System.Windows.Forms.ToolTip toolTip1;
Az objektumot a kontrol konstruktorában inicializáljuk, Active property-jét TRUE értékre állítjuk be.
public TTControl()
{
  this.toolTip1 = new System.Windows.Forms.ToolTip();
  toolTip1.Active = true;
}
Szükségünk lesz három API metódusra is, hogy a megjelenítéshez kapcsolódó műveleteket elvégezzük. Ezek közül a GetTextExtentPoint32 a GDI32.DLL-ben található, és a következőképpen deklaráljuk.
[DllImport("gdi32.dll")]
public static extern int GetTextExtentPoint32(IntPtr hdc, String str, int len, ref SIZE size);
Ennek meghívásával határozzuk meg a lista adott elemének hosszát. A másik két metódus a USER32.DLL-ben található, ezek a következők:
[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern int ReleaseDC(IntPtr hWnd,IntPtr hdc);
Ezek segítenek abban, hogy az adott ablak kezelőjét megkaphassuk, majd a mutatót a művelet végén felszabadíthassuk.
A gyorstipp megjelenítése a kontrol OnMouseMove eseménykezelőjében valósul meg. Minden egyes egérmozgatáskor, mely a kontrol kliens-területére korlátozódik, meghatározzuk, hogy a mutató alatt található-e eleme a listának. Amennyiben igen, akkor elkezdhetjük a műveletet.
int index = IndexFromPoint(e.X,e.Y);
if (index != ListBox.NoMatches)
{
Meghatározzuk a mutató alatt található elem karakterláncát, majd lekérdezzük az ablak kezelőjét.
string s = Items[index].ToString();  
IntPtr hdc = GetDC(this.Handle);
A GetTextExtentPoint32 metódussal egy struktúrába kérdezzük le a szöveg méreteit, majd felszabadítjuk a kezelőt.
GetTextExtentPoint32(hdc,s,s.Length,ref size);
ReleaseDC(this.Handle,hdc);
Ha az adott karakterlánc-hossz meghaladja a kontrol kliens-területének szélességét, vagyis túllóg, akkor a ToolTip objektum SetToolTip metódusával megjelenítjük a gyorstippet.
if (Width < size.cx)
{
  toolTip1.SetToolTip(this,s);
}
Ellenkező esetben kiürítjük a ToolTip objektum beállított szövegeket tartalmazó listáját, hogy ne jelenhessen meg semmilyen szöveg.
else
{
  toolTip1.RemoveAll();
}