簡體   English   中英

Windows 窗體中的提示對話框

[英]Prompt Dialog in Windows Forms

我正在使用System.Windows.Forms但奇怪的是沒有能力創建它們。

如何在沒有 javascript 的情況下獲得類似 javascript 提示對話框的內容?

MessageBox 很好,但用戶無法輸入輸入。

我希望用戶輸入任何可能的文本輸入。

您需要創建自己的提示對話框。 您也許可以為此創建一個類。

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。

Windows 窗體中本身沒有這樣的東西。

您必須為此創建自己的表單,或者:

使用Microsoft.VisualBasic參考。

輸入框是為 VB6 兼容性引入 .Net 的遺留代碼 - 所以我建議不要這樣做。

將 VisualBasic 庫導入 C# 程序通常不是一個好主意(不是因為它們不起作用,而只是為了兼容性、樣式和升級能力),但您可以調用 Microsoft.VisualBasic.Interaction.InputBox()顯示您正在尋找的框類型。

如果您可以創建 Windows.Forms 對象,那最好不過,但您說您不能這樣做。

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

執行此操作的其他方法:假設您有一個 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. 如果添加了各種其他輸入類型。

基於上面 Bas Brekelmans 的工作,我還創建了兩個派生 ->“輸入”對話框,允許您從用戶那里接收文本值和布爾值(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");

Bas Brekelmans 的回答非常簡潔,非常優雅。 但是,我發現對於實際應用程序,還需要多一點,例如:

  • 當消息文本太長時,適當地增加表格。
  • 不會在屏幕中間自動彈出。
  • 不提供對用戶輸入的任何驗證。

這里的類處理這些限制: http : //www.codeproject.com/Articles/31315/Getting-User-Input-With-Dialogs-Part-1

我剛剛下載了源代碼並將 InputBox.cs 復制到我的項目中。

令人驚訝的是,沒有更好的東西......我唯一真正的抱怨是它的標題文本不支持其中的換行符,因為它使用了標簽控件。

不幸的是,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 + 評論者的貢獻,您幫助我提出了一個可行的解決方案!

這是我的重構版本,它接受多行/單行作為選項

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

這是 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM