Prompt Dialog in Windows Forms

前端 未结 11 1377
名媛妹妹
名媛妹妹 2020-11-30 19:47

I am using System.Windows.Forms but strangely enough don\'t have the ability to create them.

How can I get something like a javascript prompt dialog, wi

相关标签:
11条回答
  • 2020-11-30 19:58

    You need to create your own Prompt dialog. You could perhaps create a class for this.

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

    And calling it:

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

    Update:

    Added default button (enter key) and initial focus based on comments and another question.

    0 讨论(0)
  • 2020-11-30 20:02

    Here's an example 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
    
    0 讨论(0)
  • 2020-11-30 20:03

    The answer of Bas can get you in memorytrouble theoretically, since ShowDialog won't be disposed. I think this is a more proper way. Also mention the textLabel being readable with longer text.

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

    Implementation:

    using(Prompt prompt = new Prompt("text", "caption")){
        string result = prompt.Result;
    }
    
    0 讨论(0)
  • 2020-11-30 20:07

    There is no such thing natively in Windows Forms.

    You have to create your own form for that or:

    use the Microsoft.VisualBasic reference.

    Inputbox is legacy code brought into .Net for VB6 compatibility - so i advise to not do this.

    0 讨论(0)
  • 2020-11-30 20:08

    Based on the work of Bas Brekelmans above, I have also created two derivations -> "input" dialogs that allow you to receive from the user both a text value and a boolean (TextBox and 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());
        }
    }
    

    ...and text along with a selection of one of multiple options (TextBox and 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());
        }
    }
    

    Both require the same usings:

    using System;
    using System.Windows.Forms;
    

    Call them like so:

    Call them like 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");
    
    0 讨论(0)
  • 2020-11-30 20:10

    Unfortunately C# still doesn't offer this capability in the built in libs. The best solution at present is to create a custom class with a method that pops up a small form. If you're working in Visual Studio you can do this by clicking on Project >Add class

    Visual C# items >code >class

    Name the class PopUpBox (you can rename it later if you like) and paste in the following code:

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

    You will need to change the namespace to whatever you're using. The method returns a string, so here's an example of how to implement it in your calling method:

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

    This method checks the returned string for a text value, empty string, or "cancel" (the getUserInput method returns "cancel" if the cancel button is clicked) and acts accordingly. If the user didn't enter anything and clicked OK it will tell the user and ask them if they want to cancel or re-enter their text.

    Post notes: In my own implementation I found that all of the other answers were missing 1 or more of the following:

    • A cancel button
    • The ability to contain symbols in the string sent to the method
    • How to access the method and handle the returned value.

    Thus, I have posted my own solution. I hope someone finds it useful. Credit to Bas and Gideon + commenters for your contributions, you helped me to come up with a workable solution!

    0 讨论(0)
提交回复
热议问题