Hộp thoại nhắc trong Windows Forms


115

Tôi đang sử dụng System.Windows.Formsnhưng thật kỳ lạ là không có khả năng tạo ra chúng.

Làm cách nào tôi có thể nhận được một cái gì đó như hộp thoại nhắc javascript mà không có javascript?

MessageBox rất hay, nhưng không có cách nào để người dùng nhập đầu vào.

Tôi muốn người dùng nhập bất kỳ kiểu nhập văn bản nào có thể.


Bạn có thể đăng một ví dụ mã về những gì bạn đang cố gắng làm không?
Andrew Cooper

Bạn đang tìm kiếm loại đầu vào nào, hãy cho biết thêm chi tiết. CommonDialog hãy xem các lớp kế thừa nó có lớp nào phù hợp với bạn không?
Sanjeevakumar Hiremath

21
Thật buồn cười khi ba người yêu cầu OP cung cấp thêm chi tiết và mẫu mã nhưng khá rõ ràng ý của anh ta là "như hộp thoại nhắc javascript" .
Camilo Martin

2
Dưới đây là hai ví dụ, một trong những cơ bản và khác với xác nhận đầu vào: 1. cơ bản - csharp-examples.net/inputbox 2. validation - csharp-examples.net/inputbox-class
JasonM1

Câu trả lời:


274

Bạn cần tạo hộp thoại Nhắc của riêng mình. Bạn có thể tạo một lớp cho việc này.

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

Và gọi nó là:

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

Cập nhật :

Đã thêm nút mặc định ( phím nhập ) và tiêu điểm ban đầu dựa trên nhận xét và câu hỏi khác .


1
Làm thế nào để mở rộng điều này cho A) có nút hủy và B) xác thực văn bản trong trường văn bản theo một cách nào đó trước khi quay lại?
ewok

@ewok Chỉ cần tạo một biểu mẫu, Trình thiết kế biểu mẫu sẽ giúp bạn sắp xếp nó theo cách bạn muốn.
Camilo Martin

1
@SeanWorle Tôi không thấy điều đó được đề cập ở đâu.
Bas

1
Điều mà tôi đã hoàn thành bằng cách thêm điều này: prompt.AcceptButton = xác nhận;
B. Clay Shannon

1
Nhập mã để người dùng xử lý hủy nhanh chóng với nút đóng và trở về một chuỗi rỗng
Matthew Khóa

53

Thêm tham chiếu vào Microsoft.VisualBasicvà sử dụng nó vào mã C # của bạn:

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

Để thêm giới thiệu: bấm chuột phải vào Tài liệu tham khảo trong cửa sổ Project Explorer của bạn, sau đó vào Thêm tài liệu tham khảo, và kiểm tra VisualBasic từ danh sách đó.


4
Điều này nói Interactionkhông tồn tại trong không gian tênMicrosoft.VisualBasic
Khalil Khalaf

1
này là hơi tốt hơn so với giải pháp lớp tùy chỉnh như nó hỗ trợ màn hình-dpi cao
dấu ấn Gamache

Tôi biết có lẽ sử dụng giải pháp tùy chỉnh sẽ tốt hơn nhưng tôi đang tìm kiếm một giải pháp nhanh chóng và dễ dàng, và đây là giải pháp tốt nhất. Cảm ơn, thực sự, cho tất cả.
Juano

14

Không có điều này nguyên bản trong Windows Forms.

Bạn phải tạo biểu mẫu của riêng mình cho điều đó hoặc:

sử dụng Microsoft.VisualBasictài liệu tham khảo.

Inputbox là mã kế thừa được đưa vào .Net để tương thích với VB6 - vì vậy tôi khuyên bạn không nên làm điều này.


2
Điều này đúng với Microsoft.VisualBasic.Compatibilitykhông gian tên. Microsoft.VisualBasiclà một tập hợp các thư viện trợ giúp trên .Net và không thực sự là VB cụ thể nào cả.
Jim Wooley

-1 vì tuyên bố thiếu cân nhắc về tham chiếu VB. Không có lý do gì để xua đuổi mọi người sử dụng tính năng tích hợp rất hữu ích này.
UuDdLrLrSs

6

Nói chung không phải là một ý tưởng hay khi nhập các thư viện VisualBasic vào các chương trình C # (không phải vì chúng sẽ không hoạt động, mà chỉ vì khả năng tương thích, kiểu dáng và khả năng nâng cấp), nhưng bạn có thể gọi Microsoft.VisualBasic.Interaction.InputBox () để hiển thị loại hộp bạn đang tìm kiếm.

Nếu bạn có thể tạo một đối tượng Windows.Forms, đó là cách tốt nhất, nhưng bạn nói rằng bạn không thể làm điều đó.


26
Tại sao đây không phải là một ý kiến ​​hay? Các vấn đề về "khả năng tương thích" và "khả năng nâng cấp" có thể xảy ra là gì? Tôi đồng ý rằng nói một cách "theo kiểu", hầu hết các lập trình viên C # không muốn sử dụng các lớp từ một không gian tên được gọi VisualBasic, nhưng đó chỉ là trong đầu của họ. Không có thực tế cho cảm giác đó. Nó cũng được gọi là Microsoft.MakeMyLifeEasierWithAlreadyImplementedMethodskhông gian tên.
Cody Grey

3
Nói chung, gói Microsoft.VisualBasic chỉ nhằm đơn giản hóa việc nâng cấp mã từ VB 6. Microsoft liên tục đe dọa sẽ ngừng cung cấp VB vĩnh viễn (mặc dù điều này có thể sẽ không bao giờ thực sự xảy ra), vì vậy hỗ trợ trong tương lai cho không gian tên này không được đảm bảo. Ngoài ra, một trong những lợi thế của .Net được cho là tính di động - cùng một đoạn mã sẽ chạy trên bất kỳ nền tảng nào đã cài đặt .Net framework. Tuy nhiên, Microsoft.VisualBasic không được đảm bảo khả dụng trên bất kỳ nền tảng nào khác (bao gồm, đối với những gì nó đáng giá, .Net mobile, nơi nó hoàn toàn không khả dụng).
Sean Worle

22
Sai. Đó là Microsoft.VisualBasic.Compatibilitykhông gian tên phụ, không phải toàn bộ. Rất nhiều chức năng "cốt lõi" được bao gồm trong Microsoft.VisualBasickhông gian tên; nó sẽ không đi đâu cả. Microsoft đã đe dọa "hoàng hôn" VB 6 chứ không phải VB.NET. Họ đã hứa nhiều lần rằng nó sẽ không đi đến đâu. Một số người dường như vẫn chưa tìm ra sự khác biệt ...
Cody Grey

4

Cách khác để làm điều này: Giả sử rằng bạn có kiểu nhập TextBox, Tạo biểu mẫu và có giá trị hộp văn bản là thuộc tính công khai.

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

Trong biểu mẫu chính, đây sẽ là mã:

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

;

Bằng cách này, mã trông sạch hơn:

  1. Nếu logic xác nhận được thêm vào.
  2. Nếu nhiều loại đầu vào khác được thêm vào.

4

Câu trả lời của Bas có thể khiến bạn gặp rắc rối về bộ nhớ về mặt lý thuyết, vì ShowDialog sẽ không được xử lý. Tôi nghĩ rằng đây là một cách đúng đắn hơn. Đồng thời đề cập đến textLabel có thể đọc được với văn bản dài hơn.

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

Thực hiện:

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

2
Sử dụng tốt việc quản lý bộ nhớ. Tuy nhiên, điều này không thành công khi thêm nút hủy bỏ vì nút promptnày là null tại thời điểm đó. Một sửa chữa đơn giản để cho phép hủy của dấu nhắc là để thay thế prompt.Dispose();bên trong public void Dispose()vớiif (prompt != null) { prompt.Dispose(); }
Marcus Parsons

3

Dựa trên công việc của Bas Brekelmans ở trên, tôi cũng đã tạo hai dẫn xuất -> hộp thoại "đầu vào" cho phép bạn nhận từ người dùng cả giá trị văn bản và boolean (TextBox và 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());
    }
}

... và văn bản cùng với lựa chọn một trong nhiều tùy chọn (TextBox và 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());
    }
}

Cả hai đều yêu cầu cách sử dụng giống nhau:

using System;
using System.Windows.Forms;

Gọi họ như vậy:

Gọi họ như vậy:

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

Câu trả lời của Bas Brekelmans rất thanh lịch trong sự đơn giản của nó. Tuy nhiên, tôi thấy rằng đối với một ứng dụng thực tế cần nhiều hơn một chút như:

  • Phát triển biểu mẫu một cách thích hợp khi văn bản tin nhắn quá dài.
  • Không tự động bật lên ở giữa màn hình.
  • Không cung cấp bất kỳ xác thực đầu vào của người dùng.

Lớp ở đây xử lý những hạn chế này: http://www.codeproject.com/Articles/31315/Getting-User-Input-With-Dialogs-Part-1

Tôi vừa tải xuống mã nguồn và sao chép InputBox.cs vào dự án của mình.

Ngạc nhiên là không có thứ gì tốt hơn mặc dù ... Khiếu nại thực sự duy nhất của tôi là văn bản phụ đề không hỗ trợ dòng mới trong đó vì nó sử dụng điều khiển nhãn.


Nice câu trả lời, nhưng ra khỏi phạm vi của câu hỏi hỏi
Munim Munna

1

Thật không may, C # vẫn không cung cấp khả năng này trong libs tích hợp. Giải pháp tốt nhất hiện tại là tạo một lớp tùy chỉnh với một phương thức bật lên một biểu mẫu nhỏ. Nếu bạn đang làm việc trong Visual Studio, bạn có thể thực hiện việc này bằng cách nhấp vào Dự án> Thêm lớp

Thêm lớp

Các mục C # trực quan> mã> lớp Thêm lớp 2

Đặt tên cho lớp là PopUpBox (bạn có thể đổi tên sau nếu muốn) và dán vào mã sau:

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

Bạn sẽ cần thay đổi không gian tên thành bất cứ điều gì bạn đang sử dụng. Phương thức trả về một chuỗi, vì vậy đây là một ví dụ về cách triển khai nó trong phương thức gọi của bạn:

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

Phương thức này kiểm tra chuỗi được trả về để tìm giá trị văn bản, chuỗi trống hoặc "hủy" (phương thức getUserInput trả về "hủy" nếu nút hủy được nhấp) và hoạt động tương ứng. Nếu người dùng không nhập bất cứ thứ gì và nhấp vào OK, nó sẽ thông báo cho người dùng và hỏi họ có muốn hủy hoặc nhập lại văn bản của họ hay không.

Đăng ghi chú: Trong quá trình triển khai của riêng mình, tôi nhận thấy rằng tất cả các câu trả lời khác đều thiếu 1 hoặc nhiều câu sau:

  • Nút hủy
  • Khả năng chứa các ký hiệu trong chuỗi được gửi đến phương thức
  • Cách truy cập phương thức và xử lý giá trị trả về.

Vì vậy, tôi đã đăng giải pháp của riêng tôi. Tôi hy vọng ai đó thấy nó hữu ích. Tín dụng cho Bas và Gideon + những người bình luận vì những đóng góp của bạn, bạn đã giúp tôi đưa ra một giải pháp khả thi!


0

đây là phiên bản được tái cấu trúc của tôi chấp nhận nhiều dòng / đơn như một tùy chọn

   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

Đây là một ví dụ trong 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.