C# - Form-ok közötti kapcsolat megvalósítása interfészen keresztül

forráskód letöltése
Abban az esetben, ha egy Windows-os alkalmazás egyik Form-ján végzett művelet hatással van egy másik Form-ra, akkor a két objektum között valamilyen módon kapcsolatot kell kialakítani. Cikkünkben elkészítünk egy példát arra, hogyan történhet ez meg a gyakorlatban. A példában az egyik objektumban indított ciklikus művelet állapotát jelenítjük meg a másik objektum felületén.
A mellékelt példában a Form1 űrlap felületén található gombbal elindíthatunk egy ciklust, mely 1-től 10-ig lépked egyesével, és a ciklusváltozó aktuális értékét megjelenítjük a Form2 űrlap felületén található Label kontrolon.
A megoldás lényege, hogy az IMyInterface.cs állományban található IMyInterface interfész metódusait implementáljuk a Form2 objektumban, és ezek meghívásakor tulajdonképpen a két szál együttműködését harmonizáljuk. A két szál egy ThreadPool objektumban kap helyet. Lássuk a megvalósítást.
IMyInterface interfész létrehozása
Az interfész három metódus definícióját tartalmazza. A Start metódust implementálva állíthatjuk be a Form2 objektum feliratának induló értékét.
public interface IMyInterface
{
  void Start(int i);
A SetLabelText metódussal állítjuk be a ciklusban a felirat aktuális szövegét.
  void SetLabelText(String t);
Majd az End metódusban végezzük el a szál leállítását és zárjuk be a Form2 űrlapot.
  void End();
}
Az IMyInterface interfész metódusainak implementációja
A Form2 űrlap kódjában létre kell hoznunk két delegáltat az eseményekhez:
public delegate void DSetLabelText(String t);
public delegate void DStart(int i);
Szükségünk van egy szálra, mely elvégzi a műveletet.
private Thread th = null;
Valamint egy objektumra, mely szemaforként jelzi a szálak számára, mikor egy esemény bekövetkezik.
private ManualResetEvent init = new ManualResetEvent(false);
A Start metódust implementálva futtatjuk a DStart delegáltat egy metódust átadva paraméterként. A metódus beállítja a Label kontrol Text property-jét a kezdeti nulla értékre.
public void Start(int i)
{
  ...
  Invoke(new DStart(StartProcess),new object[]{i});
}
A SetLabelText metódust implementálva futtatjuk a DSetLabelText delegáltat egy metódussal. A metódus akkor kerül meghívásra, amikor a ciklusban beállítjuk a címke feliratának értékét.
public void SetLabelText(String t)
{
  Invoke(new DSetLabelText(Process),new object[]{t});
}
Az End metódusban zárjuk a műveletet, és bezárjuk a Form2 objektumot.
public void End()
{
  Invoke(new MethodInvoker(EndProcess));
}
Form1 űrlap műveletei
A MŰVELET gombra kattintva példányosítjuk a Form2 osztályt, valamint egy metódust elhelyezünk a ThreadPool osztály függvényével a végrehajtási sorban, és megjelenítjük a dialógusablakot.
Form2 f = new Form2();
ThreadPool.QueueUserWorkItem(new WaitCallback(Process),f);
f.ShowDialog();
A Process metódusban futtatjuk a ciklust úgy, hogy az IMyInterface interfészen keresztül hívjuk meg a metódusokat.
IMyInterface cb = s as IMyInterface;
...
for(int i=1;i<11;++i)
{
  cb.SetLabelText(i.ToString());
  ...
}
...
A művelet végén az interfész End metódusát hívjuk meg.
cb.End();