it-swarm.com.ru

Диалог подсказок в Windows Forms

Я использую System.Windows.Forms, но, как ни странно, не могу их создать.

Как я могу получить что-то вроде диалогового окна подсказок JavaScript без JavaScript?

MessageBox - это хорошо, но пользователь не может ввести данные.

94
user420667

Вам нужно создать свой собственный диалог подсказок. Возможно, вы могли бы создать класс для этого.

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

Обновление:

Добавлена ​​кнопка по умолчанию (enter key) и начальный фокус на основе комментариев и другой вопрос .

239
Bas

Добавьте ссылку на Microsoft.VisualBasic и используйте ее в своем коде C #:

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

В Windows Forms такого нет изначально.

Вы должны создать свою собственную форму для этого или:

используйте ссылку Microsoft.VisualBasic.

Inputbox - это устаревший код, введенный в .Net для совместимости с VB6, поэтому я советую не делать этого.

15
Marino Šimić

Обычно не очень хорошая идея импортировать библиотеки VisualBasic в программы на C # (не потому, что они не будут работать, а только для совместимости, стиля и возможности обновления), но вы можете вызвать Microsoft.VisualBasic.Interaction.InputBox () чтобы отобразить вид коробки, которую вы ищете.

Если вы можете создать объект Windows.Forms, это будет лучше, но вы говорите, что не можете этого сделать.

7
Sean Worle

Другой способ сделать это: Предполагая, что у вас есть тип ввода 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
user2347528

Основываясь на вышеописанной работе Баса Брекелмана, я также создал два деривации -> диалоговые окна «ввода», которые позволяют вам получать от пользователя как текстовое значение, так и логическое значение (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
B. Clay Shannon

Ответ Баса теоретически может привести к возникновению проблем с памятью, поскольку 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()
    {
        Prompt.Dispose();
    }
}

Реализация:

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

Ответ Бас Брекелманс очень элегантен в своей простоте. Но я обнаружил, что для реального приложения требуется немного больше, например:

  • Правильно увеличивайте форму, когда текст сообщения слишком длинный.
  • Не появляется автоматически в середине экрана.
  • Не обеспечивает проверки ввода пользователя.

Класс здесь обрабатывает эти ограничения: http://www.codeproject.com/Articles/31315/Getting-User-Input-With-Dialogs-Part-1

Я только что скачал источник и скопировал InputBox.cs в мой проект.

Удивлен, что нет ничего лучше ... Моя единственная реальная жалоба в том, что текст заголовка не поддерживает переводы строки, так как он использует элемент управления надписью.

1
blak3r

К сожалению, C # все еще не предлагает эту возможность во встроенных библиотеках. Лучшее решение в настоящее время - это создание собственного класса с методом, который вызывает маленькую форму . Если вы работаете в Visual Studio, вы можете сделать это, нажав Project> Add class

 Add Class

Visual C # items> code> class  Add Class 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 или более из следующего:

  • Кнопка отмены
  • Возможность содержать символы в строке, отправленной в метод
  • Как получить доступ к методу и обработать возвращаемое значение.

Таким образом, я разместил свое собственное решение. Я надеюсь, что кто-то найдет это полезным. Благодарим вас за комментарии и комментарии от Bas и Gideon +, вы помогли мне найти действенное решение! 

0
technoman23

вот моя версия с рефакторингом, которая принимает многострочный/одиночный в качестве опции

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