C# - Egyedien szerkeszthető csomópontokkal rendelkező TreeView kontrol

forráskód letöltése
Cikkünkben elkészítünk egy TreeView kontrolt, melyben a csomópontok felirata egyedi módon szerkeszthető. Igaz, hogy a TreeView osztály rendelkezik egy tulajdonsággal, melyet igazra állítva elérhető, hogy a feliratokat szerkeszthessük, azonban ekkor nincs lehetőség arra, hogy ezt egyedivé tegyük. Ekkor mindenképpen magunknak kell ezt megvalósítani.
A kontrol úgy működik, hogy a jobb egérgomb csomópont fölötti lenyomása után „előgördül” egy szerkesztőmező, melyben megadhatjuk a csomópont új szövegét, majd az új szöveget az ENTER billentyű lenyomásával fogadhatjuk el. Ha meggondoltuk magunkat, és nincs szükség a módosításra, akkor az ESC billentyűvel elvethetjük a módosítást.
A kontrolban a csomópontok szerkesztéséhez egy felbukkanó TextBox kontrolt használunk, melynek néhány tulajdonságát már induláskor beállítjuk.
private TextBox editor = new TextBox();
Nagyon fontos, hogy TextBox kontrol szülőobjektumaként a TreeView kontrolt jelöljük meg, hiszen csak ekkor tudjuk a szükséges koordinátákat felhasználni.
editor.Parent = this;
Induláskor a szövegmező nem látható.
editor.Visible = false;
Az ENTER és az ESC billentyűk értelmezéséhez a szövegmezőhöz deklaráltunk egy kezelőfüggvényt.
editor.KeyDown += new KeyEventHandler(editor_KeyDown);
A kontrolban történő kattintás feldolgozásához pedig egy másikat.
MouseUp += new MouseEventHandler(this_MouseUp);
A csomópontok szerkeszthetőségét engedélyező tulajdonságot elrejtettük, hogy a sajátunkat használhassuk.
[Browsable(false)]
public bool LabelEdit
{
  get
  {
    return false;
  }
}
A saját property-nk az EditableLabel nevet viseli. Amikor az egérgombot felengedjük a kontrol fölött, akkor megvizsgáljuk, hogy engedélyezett volt-e a szerkeszthetőség.
private void this_MouseUp(object sender, MouseEventArgs e)
{
  if (eLabel)
  {
Ha igen, akkor megvizsgáljuk, hogy a jobb egérgomb volt-e lenyomva.
    if (e.Button == MouseButtons.Right)
    {
Ezt követően a kezelőfüggvény paraméteréből kiolvassuk, hogy milyen koordinátában kattintottunk, és lekérdezzük, hogy van-e csomópont abban a koordinátában. Ha igen, vagyis a kapott objektum nem NULL, akkor lekérdezzük a csomópont adatait.
      if (e.Button == MouseButtons.Right)
      {
        node = GetNodeAt(e.X,e.Y);
        if (node != null)
        {
A csomópont eredeti szövegét és a szélességét eltároljuk egy-egy változóban, hogy később, a TextBox megjelenítésénél felhasználjuk.
          nodetext = node.Text;
          width = node.Bounds.Width;
A szövegmező pozíciója a csomópont pozíciójával egyezik meg, csakúgy mint a magassága.
          editor.Left = node.Bounds.Location.X;
          editor.Top = node.Bounds.Location.Y;
          editor.Height = node.Bounds.Height;
A szélessége kezdetben nulla. Láthatóvá is kell tennünk a kontrolt, majd elindítjuk az időzítőt, mely 1 századmásodperces periódusokban növel egy pixelt a szövegmező szélességén.
          editor.Width = 0;
          editor.Text = nodetext;
          editor.Visible = true;
          timer1.Enabled = true;
          timer1.Start();
        }
      }
Az egér bal gombjának lenyomását elfedjük a kontrolban, hogy az eredeti szerkesztő ne jelenhessen meg.
      if (e.Button == MouseButtons.Left)
      {
      }
    }
  }
Az időzítő művelete, melyet leállásig folytat, a következő:
private void timer1_Tick(object sender, EventArgs e)
{
  if (editor.Width == (width + 10))
  {
    timer1.Stop();
    timer1.Enabled = false;
    editor.Focus();
    editor.SelectAll();
    return;
  }
  editor.Width++;
}
Látható, hogy a szélesség elérése után megszakítjuk az időzítő működését.
Ha lenyomjuk az ENTER-t a szövegmező fölött, akkor a szövegmező szövege kerül a csomópontba.
switch(e.KeyCode)
{
  case Keys.Enter:
    node.Text = editor.Text;
    editor.Visible = false;
    Select();
    break;
ESC lenyomása után az eredeti szöveg.
  case Keys.Escape:
    node.Text = nodetext;
    editor.Visible = false;
    Select();
    break;
}
A hívó alkalmazásban egyszerűen feldobjuk a ToolBox palettán regisztrált kontrolt a felületre, és úgy használhatjuk, mint az ősét.