Finestra di dialogo Prompt in Windows Form


115

Sto usando System.Windows.Formsma stranamente non ho la capacità di crearli.

Come posso ottenere qualcosa come una finestra di dialogo del prompt di javascript, senza javascript?

MessageBox è carino, ma non c'è modo per l'utente di inserire un input.

Voglio che l'utente inserisca qualsiasi input di testo possibile.


Puoi pubblicare un esempio di codice di ciò che stai cercando di fare?
Andrew Cooper

Che tipo di input stai cercando, dai qualche dettaglio in più. CommonDialog guarda le classi che lo ereditano, qualcuna di loro sembra giusta per te?
Sanjeevakumar Hiremath

21
È divertente come tre persone chiedano all'OP di fornire maggiori dettagli ed esempi di codice, ma è abbastanza chiaro cosa intende con "come una finestra di dialogo di prompt javascript" .
Camilo Martin

2
Di seguito sono riportati due esempi, uno di base e un altro con la convalida dell'input: 1. basic - csharp-examples.net/inputbox 2. validation - csharp-examples.net/inputbox-class
JasonM1

Risposte:


274

È necessario creare la propria finestra di dialogo Prompt. Potresti forse creare una classe per questo.

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 : "";
    }
}

E chiamandolo:

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

Aggiornamento :

Aggiunto pulsante predefinito (tasto invio ) e focus iniziale basato sui commenti e un'altra domanda .


1
Come estenderlo ad A) avere un pulsante di annullamento e B) convalidare il testo nel campo di testo in qualche modo prima di tornare?
ewok

@ewok Crea semplicemente un modulo, il Forms Designer ti aiuterà a disporlo nel modo che preferisci.
Camilo Martin

1
@SeanWorle non vedo dove sia menzionato.
Bas

1
Cosa che ho ottenuto aggiungendo questo: prompt.AcceptButton = confirm;
B. Clay Shannon,

1
Aggiunto codice per gestire la cancellazione da parte dell'utente del prompt con il pulsante di chiusura e la restituzione di una stringa vuota
Matthew Lock

53

Aggiungi riferimento Microsoft.VisualBasice usalo nel tuo codice C #:

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

Per aggiungere il riferimento: fare clic con il pulsante destro del mouse su Riferimenti nella finestra Esplora progetti, quindi su Aggiungi riferimento e selezionare VisualBasic da tale elenco.


4
Questo dice Interactionche non esiste nello spazio dei nomiMicrosoft.VisualBasic
Khalil Khalaf

1
questo è leggermente migliore della soluzione di classe personalizzata in quanto supporta schermi ad alta dpi
segna gamache

So che probabilmente sarebbe meglio usare la soluzione personalizzata, ma sto cercando una soluzione semplice e veloce, e questa è stata la migliore. Grazie, davvero, a tutti.
Juano

14

Non esiste nulla di simile in modo nativo in Windows Form.

Devi creare il tuo modulo per quello o:

utilizzare il Microsoft.VisualBasicriferimento.

Inputbox è un codice legacy importato in .Net per la compatibilità VB6, quindi consiglio di non farlo.


2
Questo è vero per lo Microsoft.VisualBasic.Compatibilityspazio dei nomi. Microsoft.VisualBasicè più un insieme di librerie di supporto su .Net e non è affatto specifico per VB.
Jim Wooley,

-1 a causa dell'istruzione inacurrate sul riferimento VB. Non c'è motivo di spaventare le persone dall'usare questa utilissima funzione integrata.
UuDdLrLrSs

6

In genere non è una buona idea importare le librerie VisualBasic in programmi C # (non perché non funzioneranno, ma solo per compatibilità, stile e capacità di aggiornamento), ma puoi chiamare Microsoft.VisualBasic.Interaction.InputBox () per visualizzare il tipo di scatola che stai cercando.

Se puoi creare un oggetto Windows.Forms, sarebbe meglio, ma dici che non puoi farlo.


26
Perché questa non è una buona idea? Quali sono i possibili problemi di "compatibilità" e "capacità di aggiornamento"? Concordo sul fatto che "stilisticamente" parlando, la maggior parte dei programmatori C # preferirebbe non utilizzare classi da uno spazio dei nomi chiamato VisualBasic, ma è solo nella loro testa. Non c'è realtà in quella sensazione. Sarebbe altrettanto bene essere chiamato Microsoft.MakeMyLifeEasierWithAlreadyImplementedMethodsspazio dei nomi.
Cody Grey

3
In generale, il pacchetto Microsoft.VisualBasic ha lo scopo di semplificare l'aggiornamento del codice solo da VB 6. Microsoft continua a minacciare di chiudere definitivamente VB (anche se probabilmente questo non accadrà mai), quindi il supporto futuro per questo spazio dei nomi non è garantito. Inoltre, uno dei vantaggi di .Net dovrebbe essere la portabilità: lo stesso codice verrà eseguito su qualsiasi piattaforma in cui è installato il framework .Net. Microsoft.VisualBasic, tuttavia, non è garantito per essere disponibile su qualsiasi altra piattaforma (incluso, per quel che vale, .Net mobile, dove non è affatto disponibile).
Sean Worle

22
Non corretto. Questo è il Microsoft.VisualBasic.Compatibilitysotto-spazio dei nomi, non l'intera cosa. Molte funzionalità "principali" sono incluse nello Microsoft.VisualBasicspazio dei nomi; non sta andando da nessuna parte. Microsoft ha minacciato di "abbandonare" VB 6, non VB.NET. Hanno promesso ripetutamente che non andrà da nessuna parte. Alcune persone sembrano ancora non aver capito la differenza ...
Cody Grey

4

Altro modo per farlo: supponendo che tu abbia un tipo di input TextBox, Crea un modulo e hai il valore della casella di testo come proprietà pubblica.

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();
    }
}

Nella forma principale, questo sarà il codice:

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

;

In questo modo, il codice sembra più pulito:

  1. Se viene aggiunta la logica di convalida.
  2. Se vengono aggiunti vari altri tipi di input.

4

La risposta di Bas può farti entrare in problemi di memoria teoricamente, poiché ShowDialog non verrà smaltito. Penso che questo sia un modo più corretto. Indica anche che textLabel è leggibile con testo più lungo.

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(); 
        }
    }
}

Implementazione:

using(Prompt prompt = new Prompt("text", "caption")){
    string result = prompt.Result;
}

2
Buon uso della gestione della memoria. Ma questo non riesce quando si aggiunge un pulsante Annulla perché prompta quel punto è nullo. Una semplice soluzione per consentire l'annullamento del prompt è sostituire l' prompt.Dispose();interno di public void Dispose()conif (prompt != null) { prompt.Dispose(); }
Marcus Parsons

3

Sulla base del lavoro di Bas Brekelmans sopra, ho anche creato due derivazioni -> dialoghi di "input" che consentono di ricevere dall'utente sia un valore di testo che un booleano (TextBox e CheckBox):

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());
    }
}

... e testo insieme a una selezione di una delle più opzioni (TextBox e 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());
    }
}

Entrambi richiedono gli stessi utilizzi:

using System;
using System.Windows.Forms;

Chiamali così:

Chiamali così:

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");

2

La risposta di Bas Brekelmans è molto elegante nella sua semplicità. Ma ho scoperto che per un'applicazione effettiva è necessario un po 'di più come:

  • Aumenta la forma in modo appropriato quando il testo del messaggio è troppo lungo.
  • Non compare automaticamente al centro dello schermo.
  • Non fornisce alcuna convalida dell'input dell'utente.

La classe qui gestisce queste limitazioni: http://www.codeproject.com/Articles/31315/Getting-User-Input-With-Dialogs-Part-1

Ho appena scaricato il sorgente e copiato InputBox.cs nel mio progetto.

Sorpreso che non ci sia qualcosa di meglio però ... La mia unica vera lamentela è che il testo della didascalia non supporta le nuove righe poiché utilizza un controllo etichetta.


Bella risposta, ma fuori dallo scopo della domanda posta
Munim Munna

1

Sfortunatamente il C # non offre ancora questa capacità nelle librerie incorporate. La soluzione migliore al momento è creare una classe personalizzata con un metodo che fa apparire un piccolo modulo. Se stai lavorando in Visual Studio puoi farlo facendo clic su Progetto> Aggiungi classe

Aggiungi classe

Elementi di Visual C #> codice> classe Aggiungi classe 2

Assegna un nome alla classe PopUpBox (puoi rinominarla in seguito se lo desideri) e incolla il seguente codice:

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();}
    }
}

Dovrai cambiare lo spazio dei nomi con quello che stai utilizzando. Il metodo restituisce una stringa, quindi ecco un esempio di come implementarlo nel metodo chiamante:

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);

Questo metodo controlla la stringa restituita per un valore di testo, una stringa vuota o "cancel" (il metodo getUserInput restituisce "cancel" se si fa clic sul pulsante Annulla) e agisce di conseguenza. Se l'utente non ha inserito nulla e ha fatto clic su OK, lo informerà e gli chiederà se desidera annullare o reinserire il testo.

Post notes: nella mia implementazione ho scoperto che tutte le altre risposte mancavano di 1 o più delle seguenti:

  • Un pulsante di annullamento
  • La capacità di contenere simboli nella stringa inviata al metodo
  • Come accedere al metodo e gestire il valore restituito.

Quindi, ho pubblicato la mia soluzione. Spero che qualcuno lo trovi utile. Ringraziamo Bas e Gideon + commentatori per i vostri contributi, mi avete aiutato a trovare una soluzione praticabile!


0

ecco la mia versione refactoring che accetta multiline / single come opzione

   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;
        }

-2

Ecco un esempio 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.