Діалог підказок у формах 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.