Kontrol elkészítése
A kontrolt úgy készítjük el, hogy használata megegyezzen az ősosztály használatával, vagyis elegendő legyen elemeket megadni az Items kollekcióban. A kontrolban egy-egy elem többsoros szöveg is lehet.
A módosítandó elem fölött kattintanunk kell az egér jobb gombjával, és a szöveg máris szerkeszthetővé válik. Amikor a szerkesztést befejeztük, vagyis megadtuk az új szöveget az elem számára, akkor az ENTER gombra kell kattintanunk, és a módosítás életbe lép. Amennyiben meggondoltuk magunkat, az ESC billentyű leütésével elvethetjük a módosítást.
Most vizsgáljuk meg, hogy milyen metódusokat kell deklarálnunk a fentiek megvalósítása érdekében.
A módosítás eseményének kezeléséhez egy saját osztályú objektumot adunk át a kezelőfüggvénynek, melynek property-jei tartalmazzák az éppen módosítandó elem indexét, a módosított szöveget, és az új szöveget.
...
public ChangedTextEventArgs(int i,string at,string bt)
{
index = i;
prevtext = bt;
aftertext = at;
}
A kezelődelegált és az esemény deklarációja a következő:
public delegate bool ChangedTextEventHandler(ChangedTextEventArgs e);
public event ChangedTextEventHandler ChangedText;
Jól látható, hogy a szokásostól eltérő módon a kezelőmetódus visszatérési logikai (nem void), így az eseménykezelőben is van módunk jelezni, hogy lépjen-e életbe a változtatás, vagy sem.
Az adott elem szerkesztésekor egy többsoros TextBox kontrol jelenik meg az elem szövege helyén, melyben megjelenítjük az elem értékét. A megjelenő kontrol MyTextBox típusú, melyet mi deklaráltunk. Induláskor a kontrol rejtett.
MyTextBox textBox1 = new MyTextBox();
...
textBox1.Parent = this;
textBox1.Hide();
Annak érdekében, hogy a módosítás eseményét elkaphassuk, a szövegmező osztályában meghívott metódusok egyikében kell elsütni az eseményt, majd továbbgyűrűzve azt, eljuttatni annak hatásait a hívó objektumba, jelen esetben a ListBox kontrolba.
textBox1.CText += new MyTextBox.CTEventHandler(textBox1_CText);
Controls.Add(textBox1);
A kontrol egyedivé akkor válik, ha a DrawMode property értékét megváltoztatjuk.
this.DrawMode = DrawMode.OwnerDrawVariable;
Az esemény bekövetkeztekor (példányosodásakor) meghívódik az OnChangedText metódus, mely megkapja a szükséges értékeket.
protected virtual bool OnChangedText(object sender,ChangedTextEventArgs e)
{
bool ret = false;
if (ChangedText != null)
{
ret = ChangedText(e);
}
return ret;
}
A meghívás a szövegmező objektum eseménykezelőjében történik meg.
private bool textBox1_CText(object sender,ChangedTextEventArgs e)
{
return OnChangedText(textBox1,e);
}
Ebben a helyzetben az összes kapcsolódó eseménykezelő logikai visszatérési értékű.
Az OnMeasureItem metódusban gondoskodunk arról, hogy az elemek egyedi magassági és szélességi értékekkel rajzolódjanak ki. Itt lekérdezzük az adott elem szövegmagasságát, majd ezt tízzel megtoldva kapjuk a megfelelő magasságot.
string s = Items[e.Index].ToString();
SizeF sf = e.Graphics.MeasureString(s,Font,Width);
int plus = 10;
e.ItemHeight = (int)sf.Height + plus;
e.ItemWidth = Width;
A kezelőmetódusban minden egyes elemet egyedileg rajzolunk ki, vagyis ha az kijelölt, akkor SystemColors.Info háttérszínt kap az elem, egyébként fehéret.
if((e.State & DrawItemState.Focus)==0)
{
e.Graphics.FillRectangle(new SolidBrush(SystemColors.Window),e.Bounds);
e.Graphics.DrawString(s,Font,new SolidBrush(SystemColors.WindowText),e.Bounds);
}
else
{
e.Graphics.FillRectangle(new SolidBrush(SystemColors.Info),e.Bounds);
e.Graphics.DrawString(s,Font,new SolidBrush(SystemColors.InfoText),e.Bounds);
}
Az OnMousUp metódusban kezeljük le az eseményt, amikor az egérgombbal egy elem fölött kattintunk. Ekkor megjelenítjük a szövegmezőt, benne a kijelölt eredeti szöveggel.
A szövegmező osztályában a legfontosabb metódus az OnKeyPress, itt kezeljük le a változtatás elfogadásának eseményét. Itt kiváltjuk az eseményt, majd annak visszatérési értékétől függően helyezzük el az adott elem szövegeként a megadott karakterláncot. Ha ez FALSE, akkor nem történik meg a módosítás.
...
if (OnCText(this,new ChangedTextEventArgs(index,Text,((ListBox)Parent).Items[index].ToString())))
{
((ListBox)Parent).Items[index] = Text;
}
Hide();
A hívó alkalmazás
A hívó alkalmazásban csupán egy kezelőmetódust adunk meg a kontrol ChangedText eseményéhez.
elbControl1.ChangedText += new ELBLibrary.ELBControl.ChangedTextEventHandler(elbControl1_ChangedText);
Ebben megvizsgáljuk, hogy a megadott új érték azonos-e a szövegmezőben megadott kontrolértékkel. Amennyiben igen, a kezelő TRUE értékkel tér vissza, ellenkező esetben FALSE-sal. Utóbbi esetben a kontrol kódjában nem adjuk értékül az új szöveget az adott elemnek.
private bool elbControl1_ChangedText(ELBLibrary.ChangedTextEventArgs e)
{
if (e.TextAfter != textBox1.Text)
{
return false;
}
else
{
return true;
}
}