C# saját párbeszédablak

Fórumok

Sziasztok!

Adott egy főprogramban egy if utasítás, aminek a hasában a fájlkiválasztó párbeszédablak eredménye van:


OpenFileDialog fileSelector = new OpenFileDialog;
...
If(fileSelector.ShowDialog()==DialogResult.OK)
{
Do Something
}

Itt az a lényeg, hogy a ShowDialog metódus feldob egy ablakot egy "Ok" meg egy "Cancel" gombbal (hogy ez most éppen fájlkiválasztó, az mindegy), de visszatérési értéke csak akkor lesz a ShowDialog()-nak, és az if kiértékelése csak akkor történik meg, ha megnyomtam az OK vagy a Cancel gombot.

Én szeretnék egy saját hasonló párbeszédablakot írni, de a saját ShowDialog metódusomat nem tudom rávenni a fenti viselkedésre.

Úgy néz ki, hogy


public class myDialog : Form
{
...
public bool resultOK;
public myDialog() {
this.resultOK=false;
}

public bool ShowDialog() {
this.Show();
OKButton.Clicked+=new EventHandler(OKButton_Clicked);
return this.resultOK;
}
private void OKButton_Clicked(object sender,EventArgs e) {
this.resultOK=true;
}
}

Szóval a resultot, amivel a ShowDialog() metódusom visszatér, a konstruktorban falsra állítom, az OK gomb megnyomása esemény állítja truera. Ezzel csak az a baj, hogy példányosításkor fals lesz, és amikor a főprogramban az ifnek a hasában meghívom a ShowDialogot, már tér is vissza falssal, és ugorja át az ifemet. Ha a konstruktorban nem állítom be, akkor meg hiszti van, hogy nem inicializált értékkel akarok visszatérni. Hogy oldom meg, hogy a ShowDialog metódus addig ne akarjon visszatérni, amíg valami esemény (OK gomb megnyomása) be nem következik?

Köszi!

Hozzászólások

Esetleg a ShowDialog() hasában Show() helyett ShowDialog()-ot hivj, ami modalis dialoguskent jeleniti meg a formot..?

----------------------
"ONE OF THESE DAYS I'M GOING TO CUT YOU INTO LITTLE PIECES!!!$E$%#$#%^*^"
--> YouTube csatornám

már rég kellet ilyennel foglalkoznom de ha jól rémlik akkor az új ShowDialog metódust deffiniálsz akkor override-ni kell. Máskülönben a szülő Form-nak a ShowDialog metódusát hívod.
-------------------------------------------

Pár észrevétel és tanács:

Először is én nem definiálnék saját ShowDialog metódust, ugyanis a form-ból örököltetsz egyet. Hívd azt. Az eleve DialogResult Enum-ból fog neked értéket kiadni, mint ahogy az OpenFileDialog. Ahhoz, hogy az OK gombod OK értéket adjon a Designerben a gombon be tudod állítani a ModalResult vagy DialogResult tulajdonságban. (rég foglalkoztam WinForms-al, mostanában WPF megy, az meg másabb)

Ha mindenáron saját ShowDialog metódust csinálsz a példa szerint, akkor is ShowDialog() metódussal hívd meg a Form-ot a kívánt viselkedésért. Valahogy így lehetne módosítani:

public new bool ShowDialog() //a new azért kell, mert totál más értelmet adsz a függvénynek
{
OKButton.Clicked+=new EventHandler(OKButton_Clicked);
base.ShowDialog(); //base, mivel az ősosztály ShowDialog metódusát hívjuk, nem az átdefiniáltat
return this.resultOK;
}

Köszi, ezzel most elmozdultam a holtpontról, és már van egy megoldásom, nem a legszebb ugyan, de használható. Az van, hogy fogalmam sincs, hogy ez a beépített Form.ShowDialog() metódus hogy van megvalósítva, de úgy tűnik, hogy ha az OK gombomon beállítom a DialogResult tulajdonságot, akkor ráklikkeléskor előbb tér vissza a DialogResult.Ok értékkel, és csak utána kezdi el futtatni a klikkeléshez rendelt eseménykezelőt. Én meg abban az eseménykezelőben szerettem volna kiértékelni, hogy ha A feltétel teljesül, akkor térjen vissza DialogResult.OK-vel, egyébként viszont DialogResult.No-val.

Konkrétan egyébként egy jelentéskészítő GUI-n dolgozom. Ez a formom úgy néz ki, hogy van benne két textbox, ahova a user fájlneveket ír - az elsőbe egy template-et, a másodikba egy kimenetet. Cancel gomb megnyomására becsukódik, és nem történik semmi. OK gomb megnyomására az egyik textboxban megadott fájlról (template) megpróbál készíteni egy másolatot a másik textboxban lévő fájlnévvel (output, amit majd megnyit, és módosít a főprogramban). Ha a másolás sikeres, indítsa el a jelentéskészítést, azaz álljon neki az outputként megadott fájlban mókázni. Ha a másolás nem sikerült (mert mondjuk az outputként megadott fájl meg van nyitva egy szövegszerkesztőben), akkor viszont ne kezdje el a jelentést generálni.


if(myForm.ShowDialog==DialogResult.Ok) {
myReportGenerator.Start();
}
else {
MessageBox.Show("Nem jó valami");
}

Itt az a lényeg, hogy az else-ágba is akkor szeretnék kerülni, ha az OK-ra kattintottam, csak akkor nem DialogResult.OK-val tért vissza a formom.

Nem kell ennyire elbonyolítani: adott egy form, amit modálisan jelenítesz meg (nevezzük ModalForm-nak). Van rajta egy OK és egy Mégse gomb. A mégse gombnak fixen beállíthatod a DialogResult property-jét DialogResult.Cancel-re, az OK gomb esetén pedig a gomb Click eseménykezelőjében állítod be a form DialogResult-ját (this.DialogResult = ...; ) a feltételektől függően (amit a ShowDialog() metódusodban akartál megcsinálni). Nem kell felüldefiniálni a ShowDialog() metódust.

Ott, ahol a ModalForm-ot meg akarod jeleníteni, példányosítod, meghívod rajta a ShowDialog()-ot, és az eredmény alapján folytatod a futást.

Példa project két perc alatt:
ModalForm, rajta 1 checkbox (checkBox1), OK gomb (btnOK), Mégse gomb (btnCancel). OK gomb eseménykezelőjében egy sor:
this.DialogResult = checkBox1.Checked ? DialogResult.OK : DialogResult.Cancel;
A ModalForm tulajdonságaiban beállítod az AcceptButton és Cancel button értékeket a megfelelő gombokra, a btnCancel DialogResult tulajdonságát DialogResult.Cancel-re.

A hívó formra felteszel egy gombot, aminek az eseménykezelőjében ez van:
using (var modalForm = new ModelForm()) MessageBox.Show(modalForm.ShowDialog().ToString());

Azt hittem, hogy ezt csináltam már tegnap is, csak éppen ott ba...ltáztam el, hogy az OK gomb eseménykezelőjében a form DialogResult-ja helyett magát az OK gombét állítgattam... this.DialogResult helyett this.button_OK.DialogResult-ot...

Vajon arra van lehetőség, hogy az OK gomb megnyomása után ne csukja be a formot, attól, hogy visszatért a DialgResult.OK értékkel? Mert szeretnék még rátenni egy progress bart, ami a főprogramban az if(myModalForm.ShowDialog()==DialogResult.OK) ágban elindított szálból (ami Wordben csinálja a jelentést) rajzolgatnék.