Dialog Prompt dalam Formulir Windows

115

saya menggunakan System.Windows.Forms tetapi anehnya tidak memiliki kemampuan untuk membuatnya.

Bagaimana saya bisa mendapatkan sesuatu seperti dialog prompt javascript, tanpa javascript?

MessageBox bagus, tetapi tidak ada cara bagi pengguna untuk memasukkan input.

Saya ingin pengguna memasukkan masukan teks apa pun yang memungkinkan.

pengguna420667
sumber
Dapatkah Anda memposting contoh kode tentang apa yang Anda coba lakukan?
Andrew Cooper
Jenis masukan apa yang Anda cari, berikan sedikit lebih banyak detail. CommonDialog melihat kelas yang mewarisinya, apakah ada yang terlihat cocok untuk Anda?
Sanjeevakumar Hiremath
21
Lucu sekali bagaimana tiga orang meminta OP untuk memberikan lebih banyak detail dan contoh kode tetapi cukup jelas apa yang dia maksud dengan "seperti dialog prompt javascript" .
Camilo Martin
2
Berikut adalah dua contoh, satu dasar dan lainnya dengan validasi input: 1. basic - csharp-examples.net/inputbox 2. validation - csharp-examples.net/inputbox-class
JasonM1

Jawaban:

274

Anda perlu membuat dialog Prompt Anda sendiri. Anda mungkin bisa membuat kelas untuk ini.

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

Dan menyebutnya:

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

Pembaruan :

Menambahkan tombol default (tombol enter ) dan fokus awal berdasarkan komentar dan pertanyaan lain .

Bas
sumber
1
Bagaimana seseorang memperluas ini ke A) memiliki tombol batal dan B) memvalidasi teks di bidang teks dengan beberapa cara sebelum kembali?
ewok
@ewok Buat saja formulir, Desainer Formulir akan membantu Anda mengaturnya seperti yang Anda inginkan.
Camilo Martin
1
@ SeanWorle Saya tidak melihat di mana hal itu disebutkan.
Bas
1
Yang saya selesaikan dengan menambahkan ini: prompt.AcceptButton = konfirmasi;
B. Clay Shannon
1
Menambahkan kode untuk menangani pengguna yang membatalkan permintaan dengan tombol tutup dan mengembalikan string kosong
Matthew Lock
53

Tambahkan referensi Microsoft.VisualBasicdan gunakan ini ke dalam kode C # Anda:

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

Untuk menambahkan refernce: klik kanan pada References di jendela Project Explorer Anda lalu pada Add Reference, dan centang VisualBasic dari daftar itu.

KurvaBG
sumber
4
Ini mengatakan Interactiontidak ada di namespaceMicrosoft.VisualBasic
Khalil Khalaf
1
ini sedikit lebih baik daripada solusi kelas khusus karena mendukung layar dpi tinggi
tandai gamache
Saya tahu mungkin menggunakan solusi khusus akan lebih baik tetapi saya mencari solusi cepat dan mudah, dan ini adalah yang terbaik. Terima kasih, sungguh, untuk semua.
Juano
14

Tidak ada hal seperti itu secara native di Windows Forms.

Anda harus membuat formulir Anda sendiri untuk itu atau:

gunakan Microsoft.VisualBasicreferensi.

Inputbox adalah kode warisan yang dibawa ke .Net untuk kompatibilitas VB6 - jadi saya menyarankan untuk tidak melakukan ini.

Marino Šimić
sumber
2
Ini berlaku untuk Microsoft.VisualBasic.Compatibilitynamespace. Microsoft.VisualBasiclebih merupakan kumpulan pustaka pembantu di atas .Net dan sama sekali tidak spesifik untuk VB.
Jim Wooley
-1 karena pernyataan tidak aktif tentang referensi VB. Tidak ada alasan untuk menakut-nakuti orang agar tidak menggunakan fitur bawaan yang sangat berguna ini.
UuDdLrLrSs
6

Biasanya bukan ide yang baik untuk mengimpor pustaka VisualBasic ke dalam program C # (bukan karena mereka tidak akan berfungsi, tetapi hanya untuk kompatibilitas, gaya, dan kemampuan untuk meningkatkan), tetapi Anda dapat memanggil Microsoft.VisualBasic.Interaction.InputBox () untuk menampilkan jenis kotak yang Anda cari.

Jika Anda dapat membuat objek Windows.Forms, itu yang terbaik, tetapi Anda mengatakan Anda tidak dapat melakukannya.

Sean Worle
sumber
26
Mengapa ini bukan ide yang bagus? Apa saja kemungkinan masalah "kompatibilitas" dan "kemampuan untuk meningkatkan"? Saya setuju bahwa berbicara "gaya", kebanyakan programmer C # lebih suka tidak menggunakan kelas dari namespace yang dipanggil VisualBasic, tapi itu hanya di kepala mereka. Tidak ada realitas untuk perasaan itu. Ini akan disebut sebagai Microsoft.MakeMyLifeEasierWithAlreadyImplementedMethodsnamespace.
Cody Gray
3
Secara umum, paket Microsoft.VisualBasic dimaksudkan untuk menyederhanakan kode pemutakhiran dari VB 6 saja. Microsoft terus mengancam untuk menghentikan VB secara permanen (meskipun ini mungkin tidak akan pernah benar-benar terjadi), jadi dukungan masa depan untuk namespace ini tidak dijamin. Selain itu, salah satu keuntungan .Net seharusnya portabilitas - kode yang sama akan berjalan di platform apa pun yang memasang kerangka .Net. Microsoft.VisualBasic, bagaimanapun, tidak dijamin akan tersedia di platform lain (termasuk, untuk apa nilainya, .Net seluler, jika tidak tersedia sama sekali).
Sean Worle
22
Salah. Itu Microsoft.VisualBasic.Compatibilitysub-namespace, bukan keseluruhannya. Banyak fungsi "inti" disertakan dalam Microsoft.VisualBasicnamespace; itu tidak akan berhasil. Microsoft telah mengancam untuk "menenggelamkan" VB 6, bukan VB.NET. Mereka telah berjanji berulang kali bahwa itu tidak akan berhasil. Beberapa orang tampaknya masih belum menemukan perbedaannya ...
Cody Grey
4

Cara lain untuk melakukan ini: Dengan asumsi Anda memiliki tipe input TextBox, Buat Formulir, dan memiliki nilai kotak teks sebagai properti publik.

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

Dalam bentuk utama, ini akan menjadi kode:

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

;

Dengan cara ini, kodenya terlihat lebih bersih:

  1. Jika logika validasi ditambahkan.
  2. Jika berbagai jenis masukan lainnya ditambahkan.
pengguna2347528
sumber
4

Jawaban dari Bas dapat membuat Anda mengalami masalah memori secara teoritis, karena ShowDialog tidak akan dibuang. Saya pikir ini adalah cara yang lebih tepat. Juga sebutkan textLabel dapat dibaca dengan teks yang lebih panjang.

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

Penerapan:

using(Prompt prompt = new Prompt("text", "caption")){
    string result = prompt.Result;
}
Gideon Mulder
sumber
2
Penggunaan manajemen memori yang baik. Tapi, ini gagal saat menambahkan tombol batal karena promptnol pada saat itu. Perbaikan sederhana untuk memungkinkan pembatalan prompt adalah dengan mengganti prompt.Dispose();di dalam public void Dispose()denganif (prompt != null) { prompt.Dispose(); }
Marcus Parsons
3

Berdasarkan karya Bas Brekelmans di atas, saya juga membuat dua derivasi -> dialog "input" yang memungkinkan Anda menerima dari pengguna baik nilai teks maupun boolean (TextBox dan 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());
    }
}

... dan teks beserta pilihan salah satu dari beberapa opsi (TextBox dan 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());
    }
}

Keduanya membutuhkan penggunaan yang sama:

using System;
using System.Windows.Forms;

Panggil mereka seperti ini:

Panggil mereka seperti ini:

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");
B. Clay Shannon
sumber
2

Jawaban Bas Brekelmans sangat elegan dalam kesederhanaannya. Tapi, saya menemukan bahwa untuk aplikasi yang sebenarnya dibutuhkan lebih banyak seperti:

  • Kembangkan bentuk dengan tepat saat teks pesan terlalu panjang.
  • Tidak otomatis muncul di tengah layar.
  • Tidak memberikan validasi apa pun atas input pengguna.

Kelas di sini menangani batasan ini: http://www.codeproject.com/Articles/31315/Getting-User-Input-With-Dialogs-Part-1

Saya baru saja mengunduh sumber dan menyalin InputBox.cs ke dalam proyek saya.

Terkejut tidak ada sesuatu yang lebih baik meskipun ... Satu-satunya keluhan saya adalah teks keterangan tidak mendukung baris baru di dalamnya karena menggunakan kontrol label.

blak3r
sumber
Jawaban yang bagus, tetapi di luar cakupan pertanyaan yang diajukan
Munim Munna
1

Sayangnya C # masih tidak menawarkan kemampuan ini pada libs bawaan. Solusi terbaik saat ini adalah membuat kelas khusus dengan metode yang memunculkan formulir kecil. Jika Anda bekerja di Visual Studio, Anda dapat melakukannya dengan mengklik Project> Tambahkan kelas

Tambahkan Kelas

Visual C # item> kode> kelas Tambahkan Kelas 2

Beri nama kelas PopUpBox (Anda dapat mengganti namanya nanti jika Anda mau) dan tempelkan kode berikut:

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

Anda perlu mengubah namespace menjadi apa pun yang Anda gunakan. Metode ini mengembalikan string, jadi berikut adalah contoh cara menerapkannya dalam metode panggilan Anda:

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

Metode ini memeriksa string yang dikembalikan untuk nilai teks, string kosong, atau "batal" (metode getUserInput mengembalikan "batal" jika tombol batal diklik) dan bertindak sesuai dengan itu. Jika pengguna tidak memasukkan apa pun dan mengeklik Oke, pengguna akan diberi tahu dan menanyakan apakah mereka ingin membatalkan atau memasukkan kembali teks mereka.

Catatan posting: Dalam implementasi saya sendiri, saya menemukan bahwa semua jawaban lain kehilangan 1 atau lebih dari yang berikut ini:

  • Tombol batal
  • Kemampuan untuk memuat simbol dalam string yang dikirim ke metode
  • Cara mengakses metode dan menangani nilai yang dikembalikan.

Jadi, saya telah memposting solusi saya sendiri. Saya berharap seseorang merasakan manfaatnya. Penghargaan untuk komentator Bas dan Gideon + atas kontribusi Anda, Anda membantu saya menghasilkan solusi yang bisa diterapkan!

teknisi23
sumber
0

inilah versi refactored saya yang menerima multiline / single sebagai opsi

   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;
        }
Alper Ebicoglu
sumber
-2

Berikut adalah contoh di 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
pengguna890332
sumber