Windows Forms'da İstem İletişim Kutusu


115

Ben kullanıyorum System.Windows.Formsbunları oluşturmak için yeteneği olmayan garip ama.

JavaScript olmadan javascript komut istemi iletişim kutusu gibi bir şeyi nasıl edinebilirim?

MessageBox güzel, ancak kullanıcının bir giriş girmesinin bir yolu yok.

Kullanıcının mümkün olan herhangi bir metin girişi girmesini istiyorum.


Yapmaya çalıştığınız şeyin bir kod örneğini gönderebilir misiniz?
Andrew Cooper

Ne tür bir girdi arıyorsunuz, biraz daha fazla ayrıntı verin. CommonDialog onu devralan sınıflara bakın, bunlardan herhangi biri sizin için doğru görünüyor mu?
Sanjeevakumar Hiremath

21
Üç kişinin OP'den daha fazla ayrıntı ve kod örneği vermesini istemesi komik, ancak "javascript iletişim kutusu gibi" derken ne demek istediği oldukça açık .
Camilo Martin

2
İşte iki örnek, biri temel ve diğeri giriş doğrulamalı: 1. temel - csharp-examples.net/inputbox 2. doğrulama - csharp-examples.net/inputbox-class
JasonM1

Yanıtlar:


274

Kendi Bilgi İstemi diyaloğunuzu oluşturmanız gerekir. Bunun için belki bir sınıf oluşturabilirsiniz.

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

Ve ona sesleniyoruz:

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

Güncelleme :

Varsayılan düğme ( anahtar girin ) ve yorumlara ve başka bir soruya göre ilk odak eklendi .


1
Bunu A) şeklinde genişletmek nasıl olur) bir iptal düğmesine sahip olur ve B) geri dönmeden önce metin alanındaki metni bir şekilde doğrular?
ewok

@ewok Sadece bir form oluşturun, Form Tasarımcısı formu istediğiniz şekilde düzenlemenize yardımcı olacaktır.
Camilo Martin

1
@SeanWorle Nereden bahsedildiğini anlamıyorum.
Bas

1
Bunu ekleyerek başardım: istem.AcceptButton = onay;
B. Clay Shannon

1
Kullanıcının kapat düğmesiyle istemi iptal etmesini ve boş bir dizeyi döndürmesini işlemek için kod eklendi
Matthew Lock

53

Referans ekleyin Microsoft.VisualBasicve bunu C # kodunuzda kullanın:

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

Referans eklemek için: Proje Gezgini pencerenizdeki Referanslara sağ tıklayın, ardından Referans Ekle'ye tıklayın ve bu listeden VisualBasic'i kontrol edin.


4
Bu Interaction, ad alanında bulunmadığını söylüyorMicrosoft.VisualBasic
Khalil Khalaf

1
bu, yüksek dpi ekranları desteklediği için özel sınıf çözümden biraz daha iyidir
mark gamache

Muhtemelen özel çözümü kullanmanın daha iyi olacağını biliyorum ancak hızlı ve kolay bir çözüm arıyorum ve bu en iyisiydi. Herkese gerçekten teşekkürler.
Juano

14

Windows Forms'da yerel olarak böyle bir şey yoktur.

Bunun için kendi formunuzu oluşturmanız gerekir veya:

Microsoft.VisualBasicreferansı kullanın .

Inputbox, .Net for VB6 uyumluluğuna getirilen eski bir koddur - bu yüzden bunu yapmamanızı tavsiye ederim.


2
Bu Microsoft.VisualBasic.Compatibilityad alanı için geçerlidir . Microsoft.VisualBasicdaha çok .Net üzerinde bir dizi yardımcı kitaplıktır ve gerçekten VB'ye özgü değildir.
Jim Wooley

-1, VB referansı ile ilgili hatalı ifade nedeniyle. İnsanları bu çok kullanışlı yerleşik özelliği kullanmaktan korkutmak için hiçbir neden yok.
UuDdLrLrSs

6

VisualBasic kitaplıklarını C # programlarına aktarmak genellikle iyi bir fikir değildir (çalışmayacaklarından değil, yalnızca uyumluluk, stil ve yükseltme yeteneği için), ancak Microsoft.VisualBasic.Interaction.InputBox () 'ı çağırabilirsiniz. aradığınız kutuyu görüntülemek için.

Bir Windows.Forms nesnesi oluşturabiliyorsanız, bu en iyisidir, ancak bunu yapamayacağınızı söylüyorsunuz.


26
Bu neden iyi bir fikir değil? Olası "uyumluluk" ve "yükseltme yeteneği" sorunları nelerdir? "Biçimsel" olarak konuşursak, çoğu C # programcısının adı verilen bir isim alanındaki sınıfları kullanmamayı tercih edeceği konusunda hemfikirim VisualBasic, ama bu sadece kafalarında. Bu hissin gerçekliği yok. Microsoft.MakeMyLifeEasierWithAlreadyImplementedMethodsAd alanı olarak da adlandırılabilir .
Cody Grey

3
Genel olarak, Microsoft.VisualBasic paketinin yalnızca VB 6'dan yükseltme kodunu basitleştirmesi amaçlanmıştır. Microsoft, VB'yi kalıcı olarak sonlandırmakla tehdit etmeye devam ediyor (muhtemelen bu asla olmayacak olsa da), bu nedenle bu ad alanı için gelecekte destek garanti edilemiyor. Ek olarak, .Net'in avantajlarından birinin taşınabilirlik olduğu varsayılır - aynı kod .Net çerçevesi kurulu olan herhangi bir platformda çalışacaktır. Bununla birlikte, Microsoft.VisualBasic'in başka herhangi bir platformda mevcut olacağı garanti edilmemektedir (değerine göre, hiç mevcut olmadığı .Net mobil dahil).
Sean Worle

22
Yanlış. Bu Microsoft.VisualBasic.Compatibilityalt ad alanıdır, her şey değil. Ad alanında birçok "temel" işlev bulunur Microsoft.VisualBasic; hiçbir yere gitmiyor. Microsoft, VB.NET'i değil, VB 6'yı "kullanımdan kaldırma" tehdidinde bulundu. Bunun hiçbir yere gitmeyeceğine defalarca söz verdiler . Bazı insanlar hala farkı anlamamış görünüyorlar ...
Cody Gray

4

Bunu yapmanın diğer yolu: Bir TextBox giriş türüne sahip olduğunuzu varsayarsak, Form Oluşturun ve metin kutusu değerine genel bir özellik olarak sahip olun.

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

Ana formda bu kod olacaktır:

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

;

Bu şekilde kod daha temiz görünür:

  1. Doğrulama mantığı eklenirse.
  2. Çeşitli diğer giriş türleri eklenirse.

4

Bas'ın cevabı, teorik olarak sizi belleğe sokabilir, çünkü ShowDialog elden çıkarılmayacaktır. Bunun daha uygun bir yol olduğunu düşünüyorum. Ayrıca textLabel'in daha uzun metinlerle okunabilir olduğundan bahsedin.

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

Uygulama:

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

2
Bellek yönetiminin iyi kullanımı. Ancak, bir iptal düğmesi eklendiğinde bu başarısız olur çünkü prompto noktada boştur. Basit bir düzeltme istemi iptali izin değiştirmektir prompt.Dispose();içinde public void Dispose()birlikteif (prompt != null) { prompt.Dispose(); }
Marcus Parsons

3

Yukarıdaki Bas Brekelmans'ın çalışmasına dayanarak, kullanıcıdan hem bir metin değeri hem de bir boole (TextBox ve CheckBox) almanıza olanak tanıyan iki türev -> "giriş" iletişim kutusu oluşturdum:

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

... ve birden çok seçenekten (TextBox ve ComboBox) bir seçimle birlikte metin:

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

Her ikisi de aynı kullanımı gerektirir:

using System;
using System.Windows.Forms;

Onları şu şekilde arayın:

Onları şu şekilde arayın:

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'ın cevabı sadeliğiyle çok şık. Ancak, gerçek bir uygulama için biraz daha fazlasına ihtiyaç olduğunu buldum, örneğin:

  • Mesaj metni çok uzun olduğunda formu uygun şekilde büyütün.
  • Ekranın ortasında otomatik olarak açılmaz.
  • Kullanıcı girişi için herhangi bir doğrulama sağlamaz.

Buradaki sınıf, bu sınırlamaları ele alır: http://www.codeproject.com/Articles/31315/Getting-User-Input-With-Dialogs-Part-1

Kaynağı indirdim ve InputBox.cs'yi projeme kopyaladım.

Şaşırdım, daha da iyi bir şey yok ... Tek gerçek şikayetim, başlık metninin bir etiket kontrolü kullandığı için içindeki yeni satırları desteklememesi.


Güzel cevap, ancak sorulan sorunun kapsamı dışında
Munim Munna

1

Maalesef C # yerleşik kitaplarda bu özelliği hala sunmuyor. Şu anda en iyi çözüm, küçük bir form ortaya çıkaran bir yöntemle özel bir sınıf oluşturmaktır. Visual Studio'da çalışıyorsanız bunu Proje> Sınıf ekle'ye tıklayarak yapabilirsiniz.

Sınıf Ekle

Visual C # öğeleri> kod> sınıf 2. Sınıfı Ekle

PopUpBox sınıfını adlandırın (isterseniz daha sonra yeniden adlandırabilirsiniz) ve aşağıdaki kodu yapıştırın:

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

Ad alanını kullandığınız şeyle değiştirmeniz gerekecek. Yöntem bir dize döndürür, bu nedenle, onu çağırma yönteminizde nasıl uygulayacağınıza dair bir örnek:

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

Bu yöntem, bir metin değeri, boş dize veya "iptal" için döndürülen dizeyi kontrol eder (iptal düğmesi tıklanırsa getUserInput yöntemi "iptal" döndürür) ve buna göre davranır. Kullanıcı hiçbir şey girmediyse ve Tamam'ı tıklarsa, kullanıcıya bunu iptal etmek veya yeniden girmek isteyip istemediklerini sorar.

Notları gönder: Kendi uygulamamda, diğer tüm yanıtların aşağıdakilerden 1 veya daha fazlasının eksik olduğunu buldum:

  • Bir iptal düğmesi
  • Yönteme gönderilen dizede semboller içerme yeteneği
  • Yönteme nasıl erişilir ve döndürülen değer nasıl kullanılır?

Böylece kendi çözümümü yayınladım. Umarım birisi onu yararlı bulur. Katkılarınız için Bas ve Gideon + yorumcularına teşekkür edin, uygulanabilir bir çözüm bulmama yardımcı oldunuz!


0

işte seçenek olarak çok satırlı / tekli kabul eden yeniden düzenlenmiş sürümüm

   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

İşte VB.NET'te bir örnek

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.