Laden...

[Tutorial] InputBox selbermachen - Grundgerüst

Erstellt von nic4x4 vor 17 Jahren Letzter Beitrag vor 17 Jahren 61.293 Views
nic4x4 Themenstarter:in
191 Beiträge seit 2006
vor 17 Jahren
[Tutorial] InputBox selbermachen - Grundgerüst

In diesem kleinen Tutorial geht es darum eine eigene InputBox zu entwerfen und funktionsfähig zu machen.
Wenn Fehler drinne sein sollten, bitte auf jeden Fall Bescheid geben.
Das soll ein Grundgerüst darstellen und überhaupt das Prinzip der Kommunikation zwischen 2 Formen veranschaulichen (besonders bei ShowDialog()).

Designen:
Zunächst mal erstellt man eine neue Form, die einen eindeutigen Namen, wie z. Bs. „frmInputBox.cs“ bekommt.

Folgende Eigenschaften müssen passend eingestellt werden:

  • FormBorderStyle = FixedSingle (oder FixedToolBox)
  • KeyPreview = true (damit man mit der Eingabetaste die InputBox bestätigen kann)
  • MinBox = false
  • MaxBox = false
  • ShowIcon = false
  • ShowInTaskbar = false
  • StartPosition = CenterParent (damit die Form zentriert über dem Aufrufer erscheint)

Danach plaziert man 1 Label, 1 Textfeld und 2 Buttons, die zu lblDescription, txtInput und bttOK bzw. bttCancel umgetauft werden.

Etwa so kann man die Steuerelemente dann anordnen:

Jetzt muss man noch die DialogResult – Eigenschaften der beiden Buttons richtig setzen. OK bzw. Cancel.
Bei der Form selbst, ordnet man der AcceptButton Eigenschaft den bttOK Button zu und bei CancelButton den bttCancel Button.

Code:
Man muss jetzt also 3 Eigenschaften kapseln: den Fenstertext (Bezeichnung des Formulars), die Beschreibung (die lblDescription zugewiesen wird) und die Benutzereingabe.
Das geschiet folgendermaßen:


/// <summary>
/// Legt den Fenstertext fest oder gibt diesen zurück.
/// </summary>
public string WindowTitle
{
    get { return this.Text; }
    set { this.Text = value; }
}

/// <summary>
/// Legt die Beschreibung, die über dem Eingabefeld erscheint, fest oder gibt diese zurück.
/// </summary>
public string Description
{
    get { return lblDescription.Text; }
    set { lblDescription.Text = value; }
}

/// <summary>
/// Legt die Benutzereingabe fest oder gibt diese zurück
/// </summary>
public string Default
{
    get { return txtInput.Text; }
    set { txtInput.Text = value; }
}

Wenn man die “frmInputBox” jetzt instanzieren würde, hätte das Objekt also drei neue Eigenschaften (WindowTitle, Description und Default) hinzubekommen, die man frei setzen und abrufen kann:

frmInputBox InputBox = new frmInputBox();
InputBox.WindowTitle = “Eingabe erwartet”;
InputBox.Description = “Geben Sie irgendwas ein:”;

Es ist aber auch ganz praktisch, wenn man die die Eigenschaften direkt beim Instanzieren setzen kann. Dafür muss der Konstruktor überladen werden:


/// <summary>
/// Initialisiert die InputBox mit den übergebenen Werten
/// </summary>
/// <param name="Description">Beschreibung, die über dem Eingabefeld steht</param>
/// <param name="Fenstertext"></param>
/// <param name="Default">Vorgegebene Benutzereingabe</param>
public frmInputBox(string Description, string Fenstertext, string Default)
    : this()
{
    this.Description = Description;
    this.WindowTitle = Fenstertext;
    txtInput.Text = Default;
}

Man kann sich also entscheiden, ob man nichts übergibt oder gleich alle drei Werte. Wenn ein Wert nicht bekannt sein sollte, kann man schließlich auch „“ schreiben.

Zum Schluss noch das Click – Ereignis des bttCancel – Buttons anpassen:


// Wird aufgerufen, wenn auf "Abbrechen" geklickt wird
private void bttCancel_Click(object sender, EventArgs e)
{
    // Text zurücksetzen
    txtInput.Text = "";
}

Somit ist gewährleistet, dass die Benutzereingabe gelöscht wird, falls der Benutzer auf „Abbrechen“ klickt.

So. Nun ist die ganze Sache eigentlich auch schon fertig.
Man kann jetzt die InputBox folgendermaßen auswerten:
(das kommt in eine andere Form!)

private void button1_Click(object sender, EventArgs e)
{
    frmInputBox InputBox = new frmInputBox("Geben Sie einen Suchbegriff ein:", "Suchen", "");

    if (InputBox.ShowDialog() == DialogResult.OK)
    {
        MessageBox.Show("Sie haben " + InputBox.Default + " eingegeben.");
    }
    else
    {
        MessageBox.Show("Abgebrochen!");
    }
}

Wegen diesem Thread erstellt: Link

Hinweis von herbivore vor 11 Jahren

Für eine nicht-modale Alternative zur InputBox siehe [Snippet] Nicht-modale Abfrage als Alternative für MessageBoxen (inbesondere folgenden Beitrag in [Snippet] Nicht-modale Abfrage als Alternative für MessageBoxen).

2.082 Beiträge seit 2005
vor 17 Jahren

Hallo nic4x4,

wie lange machst du schon c#? Für mich sehen da nämlich manche Programmstellen so aus, als könnten sie besonders Anfänger verwirren, wo doch ein Tutorial eigentlich dazu da ist, einen Anfänger langsam an das eigentliche Ziel heranführen sollte.

Ganz besonders ist mir hier

public frmInputBox(string Description, string Fenstertext, string Default)
    : this()
{
    this.Description = Description;
    this.WindowTitle = Fenstertext;
    txtInput.Text = Default;
} 

aufgefallen. Die Parameter sollten auf jedenfall ausschlagkräftiger benannt werden und imho wäre es besser, wenn CamelCase verwendet wird. So würde z. B. folgendes einem Anfänger besser verdeutlichen, was eigentlich was ist:

public frmInputBox(string paramBeschreibung, string paramFenstertitel, string paramStandartText)
    : this()
{
    this.Description = paramBeschreibung;
    this.WindowTitle = paramFenstertitel;
    txtInput.Text = paramStandartText;
} 

Aber bleib am Ball, man lernt ja aus Fehlern 😁

Es ist toll jemand zu sein, der nichts von der persönlichen Meinung Anderer hält. - frisch-live.de

W
558 Beiträge seit 2006
vor 17 Jahren

👍
webstarg

nic4x4 Themenstarter:in
191 Beiträge seit 2006
vor 17 Jahren

@frisch
seit nem Monat mach ich das ungefähr.
Naja, ich wollte es eigentlich für GNewMan schreiben, der ein Problem hatte.
Und ich wollte auch natürlich erfahren wie man das besser machen kann (steht ja oben).

Thx

2.082 Beiträge seit 2005
vor 17 Jahren

Und ich wollte auch natürlich erfahren wie man das besser machen kann (steht ja oben). Na schonmal Anfängerfreundlicher gestalten 😁

Ansonsten würde ich das Tutorial eher als Tutorial für ein simples UserControl oder Properties sehen als für eine Kommunikation zwischen 2 Forms.

Es ist toll jemand zu sein, der nichts von der persönlichen Meinung Anderer hält. - frisch-live.de

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo zusammen,

ich finde das Tutorial gar nicht schlecht. Sicher sollte camelCase für alle variablenNamen verwendet werden (oder wenn der Name nur aus einem Wort besteht, eben kleinschreibung) und PascalCase für den KlassenNamen. Wäre nett, wenn du, nic4x4, das noch anpassen würdest. Und auch InputBox.WindowTitle braucht man nicht wirklich, weil man ja InputBox.Text benutzen kann, um den Fenstertitel zu setzen. Aber ist sonst noch was? Ich habe beim schnellen Drübergucken nichts gefunden. Na gut, nett wäre noch, den gesamten (gecamelCasten 🙂 Quelltext der InputBox als Dateianhang zur Verfügung zu stellen.

Ich habe das Tutorial (in der Hoffnung, dass diese Überarbeitungen erfolgen) mal ins Artikelforum gestellt.

herbivore

3.728 Beiträge seit 2005
vor 17 Jahren

Original von frisch

public frmInputBox(string paramBeschreibung, string paramFenstertitel, string paramStandartText)  
    : this()  
{  
    this.Description = paramBeschreibung;  
    this.WindowTitle = paramFenstertitel;  
    txtInput.Text = paramStandartText;  
}   

Ich setze kein "param" vor meine Parameternamen. Hast Du das irgendwo im .NET Framework schon mal gesehen? Ich nämlich nicht.

4.506 Beiträge seit 2004
vor 17 Jahren

Hallo frisch und Rainbird,

Ich setze kein "param" vor meine Parameternamen. Hast Du das irgendwo im .NET Framework schon mal gesehen? Ich nämlich nicht.

wir in unserer Firma haben uns nun darauf geeinigt, dass wir "p_" vor unseren Parametern setzen, das hat zum einen damit zu tun, dass wir C++ Code und C# Code gleichzeitig programmieren. Für C++ hat sich hier die ungarische Notation festgesetzt, und das wird aus lesbarkeitsgründen nun auch in C# so eingehalten.

Es hat teilweise den Vorteil, membervariablen von lokalen Variablen und Parametern zu unterscheiden, und das finde ich prinzipiell nicht verkehrt.

Genauso reagiert das Intellisense natürlich. Wenn ich schon "p_" eingebe erhalte ich alle Parameter...

Deshalb finde ich eine solche Kennzeichnung überhaupt nicht verwerflich. Allerdings würde ich definitiv nicht das Wort "param" verwenden, denn das verwirrt aufgrunddessen, dass das ein Schlüsselwort in C# ist, und bei der Eingabe dementsprechend gehighlighted (<- Ich liebe Denglisch 🙂 wird.

Gruß
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

X
2.051 Beiträge seit 2004
vor 17 Jahren

@nic4x4

ich würde deine InputBox noch um ein paar statische Methoden erweitern. dan würde es etwa so aussehen:

public partial class InputBox : Form
{
        private InputBox(string caption, string description, string defaultValue)
        {
            InitializeComponent();

            this.Text = caption;
            this.lblDescription.Text = description;
            this.txtInput.Text = defaultValue;
        }

        public static DialogResult ShowDialog(ref string inputValue)
        {
            return ShowDialog("Geben Sie hier einen Wert ein:", ref inputValue);
        }

        public static DialogResult ShowDialog(string description, ref string inputValue)
        {
            return ShowDialog(Application.ProductName, description, ref inputValue);
        }

        public static DialogResult ShowDialog(string caption, string description, ref string inputValue)
        {
            DialogResult res;

            using (InputBox frm = new InputBox(caption, description, inputValue))
            {
                res = frm.ShowDialog();
                if (res == DialogResult.OK)
                    inputValue = frm.txtInput.Text;
            }

            return res;
        }
}

und aufgerufen kann es dan z.b. so:

private void button1_Click(object sender, EventArgs e)
{
            string value = "Ein Wert";
            if (InputBox.ShowDialog(ref value) == DialogResult.OK) 
                MessageBox.Show(value);
}

so ähnlich wird es in Delphi oder auch VB gemacht. und ich finde es ist besser so für so eine einfache aufgabe.

X
2.051 Beiträge seit 2004
vor 17 Jahren

ah ja...warum man KeyPreview = true braucht habe ich auch nicht ganz verstanden? geht auch ohne.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Xqgene,

stimmt, die Verwendung von AcceptButton und CancelButton sollten reichen.

herbivore

2.082 Beiträge seit 2005
vor 17 Jahren

Original von Rainbird

Original von frisch

public frmInputBox(string paramBeschreibung, string paramFenstertitel, string paramStandartText)  
    : this()  
{  
    this.Description = paramBeschreibung;  
    this.WindowTitle = paramFenstertitel;  
    txtInput.Text = paramStandartText;  
}   

Ich setze kein "param" vor meine Parameternamen. Hast Du das irgendwo im .NET Framework schon mal gesehen? Ich nämlich nicht. Ich selbst benutze auch kein param. Meistens mache ich ein 'a' vor meinem Parameter. Ich habe jetzt lediglich param verwendet damit man leicht erkennen kann, was hier Parameter sind und was nicht.

Es ist toll jemand zu sein, der nichts von der persönlichen Meinung Anderer hält. - frisch-live.de

nic4x4 Themenstarter:in
191 Beiträge seit 2006
vor 17 Jahren

Original von Xqgene
ah ja...warum man KeyPreview = true braucht habe ich auch nicht ganz verstanden? geht auch ohne.

Bei mir ging das komischerweiße nicht immer.
Wenn ich der AcceptButton Eigenschaft einen Button zuweise, bekommt seine DialogResult Eigenschaft keinen Wert ?(

Das Tutorial werd ich noch überarbeiten.
Schaue mir die Beispiele an und erweiter/verbessere den Code.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo zusammen,

==> InputBox

herbivore

3.825 Beiträge seit 2006
vor 17 Jahren

Ohne KeyPreview hängt es davon ab, welches Control den Focus hat.

Also besser einschalten.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3