Eingabeaufforderungsdialog in Windows Forms

115

Ich benutze, System.Windows.Formsaber seltsamerweise habe ich nicht die Fähigkeit, sie zu erstellen.

Wie kann ich so etwas wie einen Javascript-Eingabeaufforderungsdialog ohne Javascript erhalten?

MessageBox ist nett, aber es gibt keine Möglichkeit für den Benutzer, eine Eingabe einzugeben.

Ich möchte, dass der Benutzer jede mögliche Texteingabe eingibt.

user420667
quelle
Können Sie ein Codebeispiel für das veröffentlichen, was Sie versuchen?
Andrew Cooper
Welche Art von Eingabe suchen Sie, geben Sie wenig mehr Details. CommonDialog Schauen Sie sich die Klassen an, die es erben. Sieht eine von ihnen für Sie richtig aus?
Sanjeevakumar Hiremath
20
Es ist lustig, wie drei Leute das OP bitten, mehr Details und Codebeispiele anzugeben, aber es ist ziemlich klar, was er unter "wie ein Javascript-Eingabeaufforderungsdialog" versteht .
Camilo Martin
2
Hier sind zwei Beispiele, eines Basic und eines mit Eingabevalidierung: 1. Basic - csharp-examples.net/inputbox 2. Validierung - csharp-examples.net/inputbox-class
JasonM1

Antworten:

274

Sie müssen einen eigenen Eingabeaufforderungsdialog erstellen. Sie könnten vielleicht eine Klasse dafür erstellen.

public static class Prompt
{
    public static string ShowDialog(string text, string caption)
    {
        Form prompt = new Form()
        {
            Width = 500,
            Height = 150,
            FormBorderStyle = FormBorderStyle.FixedDialog,
            Text = caption,
            StartPosition = FormStartPosition.CenterScreen
        };
        Label textLabel = new Label() { Left = 50, Top=20, Text=text };
        TextBox textBox = new TextBox() { Left = 50, Top=50, Width=400 };
        Button confirmation = new Button() { Text = "Ok", Left=350, Width=100, Top=70, DialogResult = DialogResult.OK };
        confirmation.Click += (sender, e) => { prompt.Close(); };
        prompt.Controls.Add(textBox);
        prompt.Controls.Add(confirmation);
        prompt.Controls.Add(textLabel);
        prompt.AcceptButton = confirmation;

        return prompt.ShowDialog() == DialogResult.OK ? textBox.Text : "";
    }
}

Und nenne es:

string promptValue = Prompt.ShowDialog("Test", "123");

Update :

Standardschaltfläche ( Eingabetaste ) und anfänglicher Fokus basierend auf Kommentaren und einer anderen Frage hinzugefügt .

Bas
quelle
1
Wie würde man dies erweitern, um A) eine Schaltfläche zum Abbrechen zu haben und B) den Text im Textfeld auf irgendeine Weise zu validieren, bevor man zurückkehrt?
Ewok
@ewok Erstellen Sie einfach ein Formular. Der Formular-Designer hilft Ihnen dabei, es so zu gestalten, wie Sie es möchten.
Camilo Martin
1
@ SeanWorle Ich sehe nicht, wo das erwähnt wird.
Bas
1
Was ich erreicht habe, indem ich Folgendes hinzugefügt habe: prompt.AcceptButton = Bestätigung;
B. Clay Shannon
1
Es wurde Code hinzugefügt, mit dem Benutzer die Eingabeaufforderung mit der Schaltfläche "Schließen" abbrechen und eine leere Zeichenfolge zurückgeben können
Matthew Lock
53

Fügen Sie einen Verweis auf Microsoft.VisualBasicIhren C # -Code hinzu und verwenden Sie diesen:

string input = Microsoft.VisualBasic.Interaction.InputBox("Prompt", 
                       "Title", 
                       "Default", 
                       0, 
                       0);

So fügen Sie die Referenz hinzu: Klicken Sie mit der rechten Maustaste auf die Verweise in Ihrem Projekt-Explorer-Fenster und dann auf Verweis hinzufügen, und aktivieren Sie VisualBasic in dieser Liste.

KurvaBG
quelle
4
Dies sagt, Interactionexistiert nicht im NamespaceMicrosoft.VisualBasic
Khalil Khalaf
1
Dies ist etwas besser als die benutzerdefinierte Klassenlösung, da sie
hochauflösende
Ich weiß, dass die Verwendung der benutzerdefinierten Lösung wahrscheinlich besser wäre, aber ich suche nach einer schnellen und einfachen Lösung, und dies war die beste. Vielen Dank an alle.
Juano
14

In Windows Forms gibt es so etwas nicht.

Sie müssen dafür Ihr eigenes Formular erstellen oder:

Verwenden Sie die Microsoft.VisualBasicReferenz.

Inputbox ist ein Legacy-Code, der aus Gründen der VB6-Kompatibilität in .Net integriert wurde. Ich rate daher, dies nicht zu tun.

Marino Šimić
quelle
2
Dies gilt für den Microsoft.VisualBasic.CompatibilityNamespace. Microsoft.VisualBasicist eher eine Reihe von Hilfsbibliotheken über .Net und überhaupt nicht wirklich VB-spezifisch.
Jim Wooley
-1 wegen der ungenauen Aussage über die VB-Referenz. Kein Grund, Menschen davon abzuhalten, diese sehr nützliche integrierte Funktion zu verwenden.
UuDdLrLrSs
6

Es ist im Allgemeinen keine gute Idee, die VisualBasic-Bibliotheken in C # -Programme zu importieren (nicht, weil sie nicht funktionieren, sondern nur aus Gründen der Kompatibilität, des Stils und der Aktualisierungsfähigkeit), aber Sie können Microsoft.VisualBasic.Interaction.InputBox () aufrufen. um die Art der Box anzuzeigen, nach der Sie suchen.

Wenn Sie ein Windows.Forms-Objekt erstellen können, ist dies am besten, aber Sie sagen, dass Sie dies nicht tun können.

Sean Worle
quelle
26
Warum ist das keine gute Idee? Was sind die möglichen Probleme mit "Kompatibilität" und "Upgrade-Fähigkeit"? Ich stimme zu, dass "stilistisch" die meisten C # -Programmierer es vorziehen würden, keine Klassen aus einem Namespace namens zu verwenden VisualBasic, aber das ist nur in ihrem Kopf. Dieses Gefühl hat keine Realität. Es würde genauso gut als Microsoft.MakeMyLifeEasierWithAlreadyImplementedMethodsNamespace bezeichnet werden.
Cody Gray
3
Im Allgemeinen soll das Microsoft.VisualBasic-Paket das Aktualisieren von Code nur von VB 6 vereinfachen. Microsoft droht weiterhin mit einem dauerhaften Sonnenuntergang von VB (obwohl dies wahrscheinlich nie tatsächlich passieren wird), sodass die zukünftige Unterstützung für diesen Namespace nicht garantiert werden kann. Einer der Vorteile von .Net soll außerdem die Portabilität sein - derselbe Code wird auf jeder Plattform ausgeführt, auf der das .Net-Framework installiert ist. Es ist jedoch nicht garantiert, dass Microsoft.VisualBasic auf einer anderen Plattform verfügbar ist (einschließlich .Net Mobile, wo es überhaupt nicht verfügbar ist).
Sean Worle
22
Falsch. Das ist der Microsoft.VisualBasic.CompatibilitySub-Namespace, nicht die ganze Sache. Der Microsoft.VisualBasicNamespace enthält viele "Kern" -Funktionen . es geht nirgendwo hin. Microsoft hat VB 6, nicht VB.NET, mit "Sonnenuntergang" gedroht. Sie haben wiederholt versprochen, dass es nirgendwo hingehen wird. Einige Leute scheinen den Unterschied immer noch nicht herausgefunden zu haben ...
Cody Gray
4

Andere Vorgehensweise: Angenommen, Sie haben einen TextBox-Eingabetyp, erstellen Sie ein Formular und haben den Textfeldwert als öffentliche Eigenschaft.

public partial class TextPrompt : Form
{
    public string Value
    {
        get { return tbText.Text.Trim(); }
    }

    public TextPrompt(string promptInstructions)
    {
        InitializeComponent();

        lblPromptText.Text = promptInstructions;
    }

    private void BtnSubmitText_Click(object sender, EventArgs e)
    {
        Close();
    }

    private void TextPrompt_Load(object sender, EventArgs e)
    {
        CenterToParent();
    }
}

In der Hauptform ist dies der Code:

var t = new TextPrompt(this, "Type the name of the settings file:");
t.ShowDialog()

;;

Auf diese Weise sieht der Code sauberer aus:

  1. Wenn Validierungslogik hinzugefügt wird.
  2. Wenn verschiedene andere Eingabetypen hinzugefügt werden.
user2347528
quelle
4

Die Antwort von Bas kann Sie theoretisch in Speicherprobleme bringen, da ShowDialog nicht entsorgt wird. Ich denke, das ist ein richtigerer Weg. Erwähnen Sie auch, dass das textLabel mit längerem Text lesbar ist.

public class Prompt : IDisposable
{
    private Form prompt { get; set; }
    public string Result { get; }

    public Prompt(string text, string caption)
    {
        Result = ShowDialog(text, caption);
    }
    //use a using statement
    private string ShowDialog(string text, string caption)
    {
        prompt = new Form()
        {
            Width = 500,
            Height = 150,
            FormBorderStyle = FormBorderStyle.FixedDialog,
            Text = caption,
            StartPosition = FormStartPosition.CenterScreen,
            TopMost = true
        };
        Label textLabel = new Label() { Left = 50, Top = 20, Text = text, Dock = DockStyle.Top, TextAlign = ContentAlignment.MiddleCenter };
        TextBox textBox = new TextBox() { Left = 50, Top = 50, Width = 400 };
        Button confirmation = new Button() { Text = "Ok", Left = 350, Width = 100, Top = 70, DialogResult = DialogResult.OK };
        confirmation.Click += (sender, e) => { prompt.Close(); };
        prompt.Controls.Add(textBox);
        prompt.Controls.Add(confirmation);
        prompt.Controls.Add(textLabel);
        prompt.AcceptButton = confirmation;

        return prompt.ShowDialog() == DialogResult.OK ? textBox.Text : "";
    }

    public void Dispose()
    {
        //See Marcus comment
        if (prompt != null) { 
            prompt.Dispose(); 
        }
    }
}

Implementierung:

using(Prompt prompt = new Prompt("text", "caption")){
    string result = prompt.Result;
}
Gideon Mulder
quelle
2
Gute Nutzung der Speicherverwaltung. Dies schlägt jedoch fehl, wenn Sie eine Abbrechen-Schaltfläche hinzufügen, da die promptzu diesem Zeitpunkt null ist. Eine einfache Lösung zu ermöglichen , der die schnelle Aufhebung ersetzen prompt.Dispose();Innenseite public void Dispose()mitif (prompt != null) { prompt.Dispose(); }
Marcus Parsons
3

Basierend auf der Arbeit von Bas Brekelmans oben habe ich auch zwei Ableitungen erstellt -> "Eingabedialoge", mit denen Sie vom Benutzer sowohl einen Textwert als auch einen Booleschen Wert (TextBox und CheckBox) erhalten können:

public static class PromptForTextAndBoolean
{
    public static string ShowDialog(string caption, string text, string boolStr)
    {
        Form prompt = new Form();
        prompt.Width = 280;
        prompt.Height = 160;
        prompt.Text = caption;
        Label textLabel = new Label() { Left = 16, Top = 20, Width = 240, Text = text };
        TextBox textBox = new TextBox() { Left = 16, Top = 40, Width = 240, TabIndex = 0, TabStop = true };
        CheckBox ckbx = new CheckBox() { Left = 16, Top = 60, Width = 240, Text = boolStr };
        Button confirmation = new Button() { Text = "Okay!", Left = 16, Width = 80, Top = 88, TabIndex = 1, TabStop = true };
        confirmation.Click += (sender, e) => { prompt.Close(); };
        prompt.Controls.Add(textLabel);
        prompt.Controls.Add(textBox);
        prompt.Controls.Add(ckbx);
        prompt.Controls.Add(confirmation);
        prompt.AcceptButton = confirmation;
        prompt.StartPosition = FormStartPosition.CenterScreen;
        prompt.ShowDialog();
        return string.Format("{0};{1}", textBox.Text, ckbx.Checked.ToString());
    }
}

... und Text zusammen mit einer Auswahl einer von mehreren Optionen (TextBox und ComboBox):

public static class PromptForTextAndSelection
{
    public static string ShowDialog(string caption, string text, string selStr)
    {
        Form prompt = new Form();
        prompt.Width = 280;
        prompt.Height = 160;
        prompt.Text = caption;
        Label textLabel = new Label() { Left = 16, Top = 20, Width = 240, Text = text };
        TextBox textBox = new TextBox() { Left = 16, Top = 40, Width = 240, TabIndex = 0, TabStop = true };
        Label selLabel = new Label() { Left = 16, Top = 66, Width = 88, Text = selStr };
        ComboBox cmbx = new ComboBox() { Left = 112, Top = 64, Width = 144 };
        cmbx.Items.Add("Dark Grey");
        cmbx.Items.Add("Orange");
        cmbx.Items.Add("None");
        Button confirmation = new Button() { Text = "In Ordnung!", Left = 16, Width = 80, Top = 88, TabIndex = 1, TabStop = true };
        confirmation.Click += (sender, e) => { prompt.Close(); };
        prompt.Controls.Add(textLabel);
        prompt.Controls.Add(textBox);
        prompt.Controls.Add(selLabel);
        prompt.Controls.Add(cmbx);
        prompt.Controls.Add(confirmation);
        prompt.AcceptButton = confirmation;
        prompt.StartPosition = FormStartPosition.CenterScreen;
        prompt.ShowDialog();
        return string.Format("{0};{1}", textBox.Text, cmbx.SelectedItem.ToString());
    }
}

Beide erfordern die gleiche Verwendung:

using System;
using System.Windows.Forms;

Nennen Sie sie so:

Nennen Sie sie so:

PromptForTextAndBoolean.ShowDialog("Jazz", "What text should accompany the checkbox?", "Allow Scat Singing"); 

PromptForTextAndSelection.ShowDialog("Rock", "What should the name of the band be?", "Beret color to wear");
B. Clay Shannon
quelle
2

Die Antwort von Bas Brekelmans ist in ihrer Einfachheit sehr elegant. Ich habe jedoch festgestellt, dass für eine tatsächliche Anwendung etwas mehr erforderlich ist, z.

  • Erweitern Sie das Formular entsprechend, wenn der Nachrichtentext zu lang ist.
  • Wird nicht automatisch in der Mitte des Bildschirms angezeigt.
  • Bietet keine Validierung der Benutzereingaben.

Die Klasse hier behandelt diese Einschränkungen: http://www.codeproject.com/Articles/31315/Getting-User-Input-With-Dialogs-Part-1

Ich habe gerade die Quelle heruntergeladen und InputBox.cs in mein Projekt kopiert.

Überrascht, dass es nichts Besseres gibt ... Meine einzige echte Beschwerde ist, dass der Untertiteltext keine Zeilenumbrüche unterstützt, da er ein Beschriftungssteuerelement verwendet.

blak3r
quelle
Schöne Antwort, aber außerhalb des Rahmens der gestellten Frage
Munim Munna
1

Leider bietet C # diese Funktion in den integrierten Bibliotheken immer noch nicht an. Die derzeit beste Lösung besteht darin, eine benutzerdefinierte Klasse mit einer Methode zu erstellen, mit der ein kleines Formular angezeigt wird. Wenn Sie in Visual Studio arbeiten, können Sie dies tun, indem Sie auf Projekt> Klasse hinzufügen klicken

Klasse hinzufügen

Visual C # -Elemente> Code> Klasse Klasse 2 hinzufügen

Benennen Sie die Klasse PopUpBox (Sie können sie später umbenennen, wenn Sie möchten ) und fügen Sie den folgenden Code ein:

using System.Drawing;
using System.Windows.Forms;

namespace yourNameSpaceHere
{
    public class PopUpBox
    {
        private static Form prompt { get; set; }

        public static string GetUserInput(string instructions, string caption)
        {
            string sUserInput = "";
            prompt = new Form() //create a new form at run time
            {
                Width = 500, Height = 150, FormBorderStyle = FormBorderStyle.FixedDialog, Text = caption,
                StartPosition = FormStartPosition.CenterScreen, TopMost = true
            };
            //create a label for the form which will have instructions for user input
            Label lblTitle = new Label() { Left = 50, Top = 20, Text = instructions, Dock = DockStyle.Top, TextAlign = ContentAlignment.TopCenter };
            TextBox txtTextInput = new TextBox() { Left = 50, Top = 50, Width = 400 };

            ////////////////////////////OK button
            Button btnOK = new Button() { Text = "OK", Left = 250, Width = 100, Top = 70, DialogResult = DialogResult.OK };
            btnOK.Click += (sender, e) => 
            {
                sUserInput = txtTextInput.Text;
                prompt.Close();
            };
            prompt.Controls.Add(txtTextInput);
            prompt.Controls.Add(btnOK);
            prompt.Controls.Add(lblTitle);
            prompt.AcceptButton = btnOK;
            ///////////////////////////////////////

            //////////////////////////Cancel button
            Button btnCancel = new Button() { Text = "Cancel", Left = 350, Width = 100, Top = 70, DialogResult = DialogResult.Cancel };
            btnCancel.Click += (sender, e) => 
            {
                sUserInput = "cancel";
                prompt.Close();
            };
            prompt.Controls.Add(btnCancel);
            prompt.CancelButton = btnCancel;
            ///////////////////////////////////////

            prompt.ShowDialog();
            return sUserInput;
        }

        public void Dispose()
        {prompt.Dispose();}
    }
}

Sie müssen den Namespace auf das ändern, was Sie verwenden. Die Methode gibt eine Zeichenfolge zurück. Hier ist ein Beispiel für die Implementierung in Ihrer aufrufenden Methode:

bool boolTryAgain = false;

do
{
    string sTextFromUser = PopUpBox.GetUserInput("Enter your text below:", "Dialog box title");
    if (sTextFromUser == "")
    {
        DialogResult dialogResult = MessageBox.Show("You did not enter anything. Try again?", "Error", MessageBoxButtons.YesNo);
        if (dialogResult == DialogResult.Yes)
        {
            boolTryAgain = true; //will reopen the dialog for user to input text again
        }
        else if (dialogResult == DialogResult.No)
        {
            //exit/cancel
            MessageBox.Show("operation cancelled");
            boolTryAgain = false;
        }//end if
    }
    else
    {
        if (sTextFromUser == "cancel")
        {
            MessageBox.Show("operation cancelled");
        }
        else
        {
            MessageBox.Show("Here is the text you entered: '" + sTextFromUser + "'");
            //do something here with the user input
        }

    }
} while (boolTryAgain == true);

Diese Methode überprüft die zurückgegebene Zeichenfolge auf einen Textwert, eine leere Zeichenfolge oder "Abbrechen" (die Methode getUserInput gibt "Abbrechen" zurück, wenn auf die Schaltfläche Abbrechen geklickt wird) und handelt entsprechend. Wenn der Benutzer nichts eingegeben und auf OK geklickt hat, wird der Benutzer darüber informiert und gefragt, ob er seinen Text abbrechen oder erneut eingeben möchte.

Post Notes: In meiner eigenen Implementierung stellte ich fest, dass allen anderen Antworten mindestens eine der folgenden fehlte:

  • Eine Abbrechen-Schaltfläche
  • Die Fähigkeit, Symbole in der an die Methode gesendeten Zeichenfolge zu enthalten
  • Zugriff auf die Methode und Behandlung des zurückgegebenen Werts.

Daher habe ich meine eigene Lösung veröffentlicht. Ich hoffe, jemand findet es nützlich. Dank an Bas und Gideon + Kommentatoren für Ihre Beiträge, Sie haben mir geholfen, eine praktikable Lösung zu finden!

technoman23
quelle
0

Hier ist meine überarbeitete Version, die Multiline / Single als Option akzeptiert

   public string ShowDialog(string text, string caption, bool isMultiline = false, int formWidth = 300, int formHeight = 200)
        {
            var prompt = new Form
            {
                Width = formWidth,
                Height = isMultiline ? formHeight : formHeight - 70,
                FormBorderStyle = isMultiline ? FormBorderStyle.Sizable : FormBorderStyle.FixedSingle,
                Text = caption,
                StartPosition = FormStartPosition.CenterScreen,
                MaximizeBox = isMultiline
            };

            var textLabel = new Label
            {
                Left = 10,
                Padding = new Padding(0, 3, 0, 0),
                Text = text,
                Dock = DockStyle.Top
            };

            var textBox = new TextBox
            {
                Left = isMultiline ? 50 : 4,
                Top = isMultiline ? 50 : textLabel.Height + 4,
                Multiline = isMultiline,
                Dock = isMultiline ? DockStyle.Fill : DockStyle.None,
                Width = prompt.Width - 24,
                Anchor = isMultiline ? AnchorStyles.Left | AnchorStyles.Top : AnchorStyles.Left | AnchorStyles.Right
            };

            var confirmationButton = new Button
            {
                Text = @"OK",
                Cursor = Cursors.Hand,
                DialogResult = DialogResult.OK,
                Dock = DockStyle.Bottom,
            };

            confirmationButton.Click += (sender, e) =>
            {
                prompt.Close();
            };

            prompt.Controls.Add(textBox);
            prompt.Controls.Add(confirmationButton);
            prompt.Controls.Add(textLabel);

            return prompt.ShowDialog() == DialogResult.OK ? textBox.Text : string.Empty;
        }
Alper Ebicoglu
quelle
-2

Hier ist ein Beispiel in VB.NET

Public Function ShowtheDialog(caption As String, text As String, selStr As String) As String
    Dim prompt As New Form()
    prompt.Width = 280
    prompt.Height = 160
    prompt.Text = caption
    Dim textLabel As New Label() With { _
         .Left = 16, _
         .Top = 20, _
         .Width = 240, _
         .Text = text _
    }
    Dim textBox As New TextBox() With { _
         .Left = 16, _
         .Top = 40, _
         .Width = 240, _
         .TabIndex = 0, _
         .TabStop = True _
    }
    Dim selLabel As New Label() With { _
         .Left = 16, _
         .Top = 66, _
         .Width = 88, _
         .Text = selStr _
    }
    Dim cmbx As New ComboBox() With { _
         .Left = 112, _
         .Top = 64, _
         .Width = 144 _
    }
    cmbx.Items.Add("Dark Grey")
    cmbx.Items.Add("Orange")
    cmbx.Items.Add("None")
    cmbx.SelectedIndex = 0
    Dim confirmation As New Button() With { _
         .Text = "In Ordnung!", _
         .Left = 16, _
         .Width = 80, _
         .Top = 88, _
         .TabIndex = 1, _
         .TabStop = True _
    }
    AddHandler confirmation.Click, Sub(sender, e) prompt.Close()
    prompt.Controls.Add(textLabel)
    prompt.Controls.Add(textBox)
    prompt.Controls.Add(selLabel)
    prompt.Controls.Add(cmbx)
    prompt.Controls.Add(confirmation)
    prompt.AcceptButton = confirmation
    prompt.StartPosition = FormStartPosition.CenterScreen
    prompt.ShowDialog()
    Return String.Format("{0};{1}", textBox.Text, cmbx.SelectedItem.ToString())
End Function
user890332
quelle