Діалог підказок у формах Windows


115

Я використовую, System.Windows.Formsале як не дивно, не мають можливості їх створювати.

Як я можу отримати щось на зразок діалогового вікна javascript без javascript?

MessageBox приємно, але користувач не може ввести вхід.

Я хочу, щоб користувач вводив будь-яке можливе введення тексту.


Чи можете ви розмістити приклад коду того, що ви намагаєтесь зробити?
Ендрю Купер

Який внесок ви шукаєте, дайте трохи більше деталей. Подивіться CommonDialog на класи, що їх успадковують, чи будь-який з них виглядає саме вам
Sanjeevakumar Hiremath

21
Смішно, як троє людей просять ОП надати більше деталей та зразків коду, але цілком зрозуміло, що він має на увазі під «діалоговим вікном діалогу javascript» .
Каміло Мартін

2
Ось два приклади, один основний та інший з перевіркою вхідних даних: 1. basic - csharp-examples.net/inputbox 2. валідація - csharp-examples.net/inputbox-class
JasonM1

Відповіді:


274

Вам потрібно створити власне діалогове вікно підказок. Ви можете, можливо, створити для цього клас.

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

Оновлення :

Додана кнопка за замовчуванням ( клавіша введення ) та початкове фокусування на основі коментарів та іншого питання .


1
Як можна розширити це на A) мати кнопку скасування та B) якось перевірити текст у текстовому полі перед поверненням?
ewok

@ewok Просто створіть форму, конструктор форм допоможе вам розкласти її так, як ви хочете.
Каміло Мартін

1
@SeanWorle Я не бачу, де це згадується.
Бас

1
Що я досяг, додавши це: prompt.AcceptButton = підтвердження;
Б. Клей Шеннон

1
Додано код для обробки скасування запиту користувачем кнопкою закриття та поверненням порожнього рядка
Matthew Lock

53

Додайте посилання Microsoft.VisualBasicта використовуйте це у своєму коді C #:

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

Щоб додати референцію: клацніть правою кнопкою миші посилання Посилання у вашому вікні провідника проектів, а потім - Додати посилання та перевірте VisualBasic у цьому списку.


4
Це говорить, Interactionщо не існує в просторі іменMicrosoft.VisualBasic
Халил Халаф

1
це трохи краще, ніж рішення на замовлення класу, оскільки воно підтримує екрани з
високою точністю на

Я знаю, напевно, використання користувальницького рішення було б краще, але я шукаю швидке та просте рішення, і це було найкраще. Дякую, справді, всім.
Жуано

14

У Windows Forms подібного не існує.

Ви повинні створити власну форму для цього або:

використовувати Microsoft.VisualBasicпосилання.

Inputbox - це застарілий код, внесений до .Net для сумісності VB6 - тому я раджу не робити цього.


2
Це справедливо для Microsoft.VisualBasic.Compatibilityпростору імен. Microsoft.VisualBasicце більше набір бібліотек-помічників на вершині .Net і насправді не є специфічним для VB.
Джим Вулі

-1 через неточне твердження про посилання на VB. Немає причин відлякувати людей від використання цієї дуже корисної вбудованої функції.
UuDdLrLrSs

6

Імпортувати бібліотеки VisualBasic до програм C # зазвичай не дуже реально (не тому, що вони не працюватимуть, а лише для сумісності, стилю та можливості оновлення), але ви можете зателефонувати в Microsoft.VisualBasic.Interaction.InputBox () щоб відобразити тип поля, який ви шукаєте.

Якщо ви можете створити об’єкт Windows.Forms, це було б найкраще, але ви кажете, що не можете цього зробити.


26
Чому це не гарна ідея? Які можливі проблеми "сумісності" та "можливості оновлення"? Я погоджусь, що "стилістично" кажучи, більшість програмістів на C # вважають за краще не використовувати класи з названого простору імен VisualBasic, але це лише в їх голові. Цьому почуттю немає реальності. Це так само добре називатиметься Microsoft.MakeMyLifeEasierWithAlreadyImplementedMethodsпростором імен.
Коді Грей

3
Загалом, пакет Microsoft.VisualBasic призначений для спрощення оновлення коду лише з VB 6. Microsoft постійно загрожує постійним заходом VB (хоча це, мабуть, ніколи не відбудеться), тому майбутня підтримка цього простору імен не гарантується. Крім того, однією з переваг .Net передбачається портативність - той самий код буде працювати на будь-якій платформі, на якій встановлена ​​рамка .Net. Microsoft.VisualBasic, однак, не гарантується, що він буде доступний на будь-якій іншій платформі (в тому числі, для чого це варто .Net mobile, де вона взагалі недоступна).
Шон Ворле

22
Неправильно. Це Microsoft.VisualBasic.Compatibilityпростір імен, а не вся справа. У Microsoft.VisualBasicпросторі імен включено багато основних функціональних можливостей ; це нікуди не дінеться. Microsoft погрожувала "заходом" VB 6, а не VB.NET. Вони неодноразово обіцяли, що нікуди не дінеться. Деякі люди, здається, не зрозуміли різницю ...
Коді Грей

4

Інший спосіб зробити це: якщо припустити, що у вас є тип введення 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. Якщо додаються різні інші типи введення.

4

Відповідь Баса теоретично може вас заспокоїти, оскільки 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;
}

2
Гарне використання управління пам'яттю. Але це не вдається при додаванні кнопки скасування, оскільки promptв цій точці значення є нульовим. Просте виправлення , щоб скасування запрошення є заміна prompt.Dispose();всередині public void Dispose()зif (prompt != null) { prompt.Dispose(); }
Марк Парсонс

3

Виходячи з роботи Бас Брекельманса вище, я також створив дві діалоги виведення -> "введення", які дозволяють отримувати від користувача як текстове значення, так і булеве (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");

2

Відповідь Бас Брекельманса дуже елегантна своєю простотою. Але я виявив, що для фактичного застосування потрібно трохи більше, таких як:

  • Формуйте належним чином, коли текст повідомлення занадто довгий.
  • Не відображається автоматично в середині екрана.
  • Не надає перевірки введення користувача.

Клас тут обробляє ці обмеження: http://www.codeproject.com/Articles/31315/Getting-User-Input-With-Dialogs-Part-1

Щойно я завантажив джерело і скопіював InputBox.cs у свій проект.

Здивований, що немає нічого кращого, хоча ... Моя єдина скарга - це те, що текст підпису не підтримує нові рядки в ньому, оскільки він використовує елемент управління мітками.


Приємна відповідь, але поза
межею

1

На жаль, C # все ще не пропонує цю можливість у вбудованих libs. Найкраще рішення на даний момент - створити спеціальний клас із методом, який вискакує невелику форму. Якщо ви працюєте в Visual Studio, ви можете зробити це, натиснувши на проект> Додати клас

Додати клас

Visual C # items> code> клас Додати клас 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 повертає "скасувати", якщо натиснути кнопку скасування) і діє відповідно. Якщо користувач нічого не ввів і натиснув ОК, він скаже користувачеві і запитає, чи хоче він скасувати або повторно ввести текст.

Примітки до пошти: В моїй власній реалізації я виявив, що в усіх інших відповідях бракує 1 або більше з наступного:

  • Кнопка скасування
  • Можливість містити символи у рядку, надісланому методу
  • Як отримати доступ до методу та обробити повернене значення.

Таким чином, я розмістив власне рішення. Сподіваюся, хтось вважає це корисним. Подяка Базі та Гедеону + коментаторам за ваш внесок, ви допомогли мені придумати дієве рішення!


0

ось моя реконструйована версія, яка приймає багаторядкові / сингли як опцію

   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

Ось приклад у 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.