Windows 窗体中的“提示”对话框

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

如果没有 javascript,我怎样才能得到类似 javascript 提示对话框的东西?

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

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

240519 次浏览

在 Windows 窗体中本来就没有这种东西。

你必须为此创建自己的表单,否则:

使用 Microsoft.VisualBasic引用。

Inputbox 是为了 VB6兼容性而带入.Net 的遗留代码-所以我建议不要这样做。

将 VisualBasic 库导入到 C # 程序中通常不是一个真正的好主意(不是因为它们不能工作,而只是为了兼容性、样式和升级能力) ,但是你可以打电话给微软。VisualBasic.互动。InputBox ()显示您要查找的框的类型。

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

您需要创建自己的提示对话框。

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

更新 :

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

添加对 Microsoft.VisualBasic的引用,并在 C # 代码中使用它:

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

要添加引用: 右键单击“项目资源管理器”窗口中的“引用”,然后单击“添加引用”,并从该列表中选中 VisualBasic。

Bas Brekelmans 的回答非常简洁,非常优雅。但是,我发现对于一个实际的应用程序来说,还需要更多的东西,比如:

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

这里的类处理了这些限制: Http://www.codeproject.com/articles/31315/getting-user-input-with-dialogs-part-1

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

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

另一种方法是: 假设您有一个 TextBox 输入类型, 创建一个 Form,并将文本框值作为公共属性。

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. 如果添加了各种其他输入类型。

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

下面是 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

理论上,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;
}

这是我的重构版本,它接受多行/单行作为一个选项

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

遗憾的是,C # 仍然没有在内置的库中提供这种功能。目前最好的解决方案是使用弹出一个小窗体的方法创建一个自定义类。 如果您在 VisualStudio 中工作,您可以通过单击 Project > Add class 来完成此操作

Add Class

Visual C # item > code > class Add Class 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 方法将返回“取消”) ,并相应地执行操作。如果用户没有输入任何内容并单击 OK,它将告诉用户并询问他们是否要取消或重新输入文本。

附注: 在我自己的实现中,我发现所有其他的答案都缺少以下一个或多个:

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

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