Windows窗体中的提示对话框


115

我正在使用,System.Windows.Forms但奇怪的是没有创建它们的能力。

没有javascript,如何获得类似javascript提示对话框的内容?

MessageBox很不错,但是用户无法输入输入。

我希望用户输入任何可能的文本输入。


您可以张贴您要执行的代码示例吗?
Andrew Cooper

您正在寻找什么样的输入,请提供更多细节。CommonDialog看看继承它的类,它们中的任何一个看起来都适合您吗?
Sanjeevakumar Hiremath,2011年

21
有趣的是,三个人如何要求OP提供更多详细信息和代码示例,但是很清楚他的意思是“像javascript提示对话框”
卡米洛·马丁

2
这是两个示例,一个基本示例,另一个具有输入验证功能:1.基本-csharp-examples.net/inputbox 2.验证-csharp-examples.net/inputbox-class
JasonM1 2013年

Answers:


274

您需要创建自己的提示对话框。您也许可以为此创建一个类。

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

并调用它:

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

更新

添加了默认按钮(输入键)和基于注释和另一个问题的初始焦点。


1
在返回之前,如何将其扩展到A)具有取消按钮和B)验证文本字段中的文本?
ewok 2012年

@ewok只需创建一个表单,Forms Designer就会帮助您以所需的方式进行布局。
卡米洛·马丁

1
@SeanWorle我看不到提到的地方。
2014年

1
我通过添加以下内容完成了:hint.AcceptButton =确认;
B. Clay Shannon 2014年

1
添加代码来处理用户取消提示与关闭按钮,并返回一个空字符串
马修锁定

53

添加对的引用,Microsoft.VisualBasic并将其用于您的C#代码中:

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

要添加引用,请执行以下操作:在“项目资源管理器”窗口中右键单击“引用”,然后在“添加引用”上单击鼠标右键,然后从该列表中选择“ VisualBasic”。


4
这表示Interaction名称空间中不存在Microsoft.VisualBasic
Khalil Khalaf

1
这比自定义类解决方案稍好一点,因为它支持高dpi的屏幕
mark gamache

我知道使用自定义解决方案可能会更好,但是我正在寻找一种快速简便的解决方案,这是最好的。真的,谢谢大家。
Juano

14

Windows窗体本身没有这样的东西。

您必须为此创建自己的表单,或者:

使用Microsoft.VisualBasic参考。

Inputbox是.Net中为VB6兼容性引入的旧代码-所以我建议不要这样做。


2
对于Microsoft.VisualBasic.Compatibility名称空间而言,这是正确的。Microsoft.VisualBasic在.Net之上是更多的帮助程序库集,并且实际上并不是VB特定的。
吉姆·伍利

-1是因为有关VB参考的说明不够准确。没有理由让人们远离使用此非常有用的内置功能。
UuDdLrLrSs

6

将VisualBasic库导入C#程序通常不是一个好主意(不是因为它们不起作用,而是为了兼容性,样式和升级能力),但是您可以调用Microsoft.VisualBasic.Interaction.InputBox()以显示您要查找的框。

如果可以创建Windows.Forms对象,那将是最好的选择,但是您却说不能这样做。


26
为什么这不是一个好主意?有哪些可能的“兼容性”和“升级能力”问题?我同意“从风格上讲”,大多数C#程序员都希望不要使用名为的命名空间中的类VisualBasic,但这只是在他们的脑海中。这种感觉是不现实的。它将也称为Microsoft.MakeMyLifeEasierWithAlreadyImplementedMethods命名空间。
科迪·格雷

3
通常,Microsoft.VisualBasic软件包仅用于简化从VB 6升级代码。Microsoft一直威胁要永久停用VB(尽管这实际上可能永远不会发生),因此不能保证将来对此名称空间的支持。此外,.Net的优点之一是可移植性-相同的代码将在安装了.Net框架的任何平台上运行。但是,不能保证Microsoft.VisualBasic可在任何其他平台上使用(就其价值而言,包括.Net移动版,而该平台根本不可用)。
肖恩·沃勒

22
不正确 那是Microsoft.VisualBasic.Compatibility子命名空间,而不是全部。Microsoft.VisualBasic名称空间中包含许多“核心”功能;它不会去任何地方。微软威胁要“淘汰” VB 6,而不是VB.NET。他们一再承诺,它不会去任何地方。有些人似乎仍未弄清区别...
Cody Gray

4

执行此操作的其他方法:假设您具有TextBox输入类型,请创建一个Form,并将textbox值作为公共属性。

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

在主要形式中,这将是代码:

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

;

这样,代码看起来更加简洁:

  1. 如果添加了验证逻辑。
  2. 如果添加了其他各种输入类型。

4

从根本上讲,Bas的答案可以使您陷入困境,因为不会丢弃ShowDialog。我认为这是一种更适当的方法。还要提到textLabel可以读取更长的文本。

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

实现方式:

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

2
善用内存管理。但是,当添加取消按钮时,此操作将失败,因为那时的promptnull为null。一个简单的修正,以允许迅速的消除是取代prompt.Dispose();内的public void Dispose()if (prompt != null) { prompt.Dispose(); }
马库斯帕森斯

3

基于上述Bas Brekelmans的工作,我还创建了两个派生窗口->“ input”对话框,使您可以从用户接收文本值和布尔值(TextBox和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());
    }
}

...和文本,以及多个选项之一的选择(TextBox和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());
    }
}

两者都需要相同的用法:

using System;
using System.Windows.Forms;

这样称呼他们:

这样称呼他们:

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

Bas Brekelmans的回答非常简洁。但是,我发现对于实际的应用程序,还需要执行以下操作:

  • 当消息文本太长时,适当地增加表单。
  • 不会自动在屏幕中间弹出。
  • 不提供用户输入的任何验证。

这里的类处理这些限制:http : //www.codeproject.com/Articles/31315/Getting-User-Input-With-Dialogs-Part-1

我只是下载源代码并将InputBox.cs复制到我的项目中。

令人惊讶的是,这里没有更好的东西了……我唯一真正的抱怨是字幕文本不支持换行符,因为它使用了标签控件。


不错的答案,但超出了所提问题的范围
Munim Munna

1

不幸的是,C#仍未在内置库中提供此功能。当前最好的解决方案是使用弹出小表格的方法创建自定义类。如果您在Visual Studio中工作,则可以通过单击“项目”>“添加类”来执行此操作

新增课程

Visual C#项目>代码>类 添加类别2

将类命名为PopUpBox(如果愿意,可以稍后重命名)并粘贴以下代码:

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

您将需要将名称空间更改为您正在使用的名称空间。该方法返回一个字符串,因此这是如何在调用方法中实现它的示例:

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

此方法检查返回的字符串是否为文本值,空字符串或“取消”(如果单击“取消”按钮,则getUserInput方法将返回“取消”)并采取相应的措施。如果用户未输入任何内容并单击“确定”,它将告诉用户并询问他们是否要取消或重新输入其文本。

贴子:在我自己的实现中,我发现所有其他答案都缺少以下一项或多项内容:

  • 取消按钮
  • 在发送给方法的字符串中包含符号的能力
  • 如何访问方法并处理返回的值。

因此,我发布了自己的解决方案。我希望有人觉得它有用。感谢Bas和Gideon +评论者的贡献,您帮助我提出了一个可行的解决方案!


0

这是我的重构版本,可以接受多行/单行

   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

这是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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.