windows - begrebet callbacks (c #)

Indlæg af Hanne Mølgaard Plasc

Problem



Hej jeg har en formular (Formular A), som har en knap 'Tilføj', der dukker op en tekstindtastningsformular (Formular B). Når du har indtastet teksten i Form B, skal du trykke på 'OK' (btnOK). På dette tidspunkt vil jeg have Form A for at få teksten og gøre noget med det.


Fra det jeg ser, har jeg to muligheder:


1) Formular A sender en funktion (delegeret) til Formular B, der udfører den i btnOK\_Click-funktionen.


2) Jeg registrerer på en eller anden måde en metode i Form A med btnOK.Click-arrangementet.


Er jeg på det rigtige spor og kan du tænke på løsninger på et lignende problem, som jeg kan læse, fordi jeg kommer i problemer med statiske metoder og begivenheder ...

Bedste reference


Hvis formular B er et modalt vindue, kan du tilføje en offentlig strengegenskab til formular B.


Når brugeren lukker Formular B, kan du indstille egenskaben til den tekst, der blev indtastet af brugeren. Derefter, tilbage i Form A kunne du læse den offentlige ejendom af Form B for at få den tekst, som brugeren indtastede.

Andre referencer 1


Tilføj en egenskab for at danne B, der er noget lignende


public class FormB { ...
   public string Text
   {
      get { return textBox.Text; }
   }
   ...
}


Hvis du viser formular b, følger du følgende:


FormB b = new FormB();
WPF: if (b.ShowDialog() != true) return;
Winforms: if (b.ShowDialog(this) != DialogResult.Ok) return;

string txt = b.Text;


Så dybest set, hvad sker der er, at du viser modalformularen b, hvor brugeren kan indtaste tekst. Når formularen er lukket, vil b.ShowDialog vende tilbage fra blokering. På det tidspunkt kan du bede om b 's tekstegenskab og hente strengen. Tekstegenskaben skal være bundet til b' s tekstboks ved hjælp af en metode.


Hvis du ikke vil vise b modalt, kan du gøre dette:


FormB b = new FormB();
b.Closed += new EventHandler(FormB\_Closed);

b.Show();

private void FormB\_Closed(object sender, EventArgs e)
{
    string text = ((FormB)sender).Text;

    ... do something
}

Andre referencer 2


En bedre løsning ville være at sætte en offentlig ejendom på Form B, der indeholder den tekst, du har brug for. Derefter skal du bare få adgang til den pågældende ejendom fra Formular A, når Form B er ophørt.

Andre referencer 3


Jeg foretrækker # 1 - at passere en delegat er ren og enkel


class BInputValues {
    public String Field1 { get; set; }
    //...
};

partial class FormB {
    readonly Action<BInputValues> callback;

    public FormB(Action<BInputValues> callback) {
        this.callback = callback;
    }

    protected override void btnOK\_Click(object sender, EventArgs e) {
        callback(new BInputValues {
            Field1 = Field1.Text, 
            //...
        });
    }
}





override void btnAdd\_click() {
    var formb = new FormB(args => {
        // do something with args
    });
    formb.ShowModal();
}

Andre referencer 4


Du kan også oprette en underklasse af formular ...


public class FormWithResult : Form
{
    protected object FormResult { get; set; }

    public DialogResult ShowDialog(out object result)
    {
        DialogResult dr = ShowDialog();
        result = FormResult;
        return dr;
    }

    public DialogResult ShowDialog(out object result, IWin32Window win)
    {
        DialogResult dr = ShowDialog(win);
        result = FormResult;
        return dr;
    }

    public void Return(object result)
    {
        FormResult = result;
        Close();
    }

}


Så kan du skrive dette til Call a modal form og hente et resultat


        popup p = new popup();
        object result;
        p.ShowDialog(out result);
        MessageBox.Show((string)result);


Og i din popup form kan du enten gøre:


        FormResult = textBox1.Text;
        Close();


ELLER


        Return(textBox1.Text);


For at lukke formularen og returnere værdien.


Subclassing Form har også ulemper selvfølgelig, men jeg vil smide det ud som en anden løsning.


Som en side ikke kunne en generisk version af dette, hvor du kunne skrive ret returværdi, være meget bedre, hvis det ikke var for denne begrænsning på designtiden: Visual Studio 2008 Winform designer fejler at indlæse Form, der arver fra generisk klasse


Hvis du ville have Asynkrone resultater selvfølgelig, ville det være nødvendigt at tweaked. Jeg går ud fra, at du bruger Modal popups.