Caixa de diálogo de prompt em formulários do Windows


115

Estou usando, System.Windows.Formsmas estranhamente não tenho a capacidade de criá-los.

Como posso obter algo como uma caixa de diálogo de prompt de javascript, sem javascript?

MessageBox é bom, mas não há como o usuário inserir uma entrada.

Quero que o usuário insira qualquer entrada de texto possível.


Você pode postar um exemplo de código do que está tentando fazer?
— Andrew Cooper

Que tipo de informação você está procurando, dê mais alguns detalhes. CommonDialog veja as classes que o herdam, alguma delas parece certa para você?
— Sanjeevakumar Hiremath

21
É engraçado como três pessoas pedem ao OP para fornecer mais detalhes e exemplos de código, mas é bastante claro o que ele quer dizer com "como uma caixa de diálogo de prompt de javascript" .
— Camilo Martin

2
Aqui estão dois exemplos, um básico e outro com validação de entrada: 1. básico - csharp-examples.net/inputbox 2. validação - csharp-examples.net/inputbox-class
— JasonM1

Respostas:


274

Você precisa criar sua própria caixa de diálogo Prompt. Você poderia talvez criar uma classe para isso.

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

E chamando de:

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

Atualização :

Adicionado botão padrão ( tecla enter ) e foco inicial com base em comentários e outra pergunta .


1
Como estender isso para A) ter um botão de cancelamento e B) validar o texto no campo de texto de alguma forma antes de retornar?
— ewok

@ewok Basta criar um formulário, o Forms Designer irá ajudá-lo a defini-lo da maneira que você deseja.
— Camilo Martin

1
@SeanWorle Não vejo onde isso é mencionado.
— Bas

1
O que eu consegui adicionando: prompt.AcceptButton = confirmation;
— B. Clay Shannon

1
Adicionado código para lidar com o cancelamento do prompt pelo usuário com o botão Fechar e o retorno de uma string vazia
— Matthew Lock

53

Adicione referência Microsoft.VisualBasice use isso em seu código C #:

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

Para adicionar a referência: clique com o botão direito do mouse em References na janela Project Explorer e, em seguida, em Add Reference, e marque VisualBasic nessa lista.


4
Diz Interactionque não existe no namespaceMicrosoft.VisualBasic
— Khalil Khalaf

1
isso é ligeiramente melhor do que a solução de classe personalizada, pois suporta telas de alto dpi
— marque gamache

Sei que provavelmente usar a solução customizada seria melhor, mas estou procurando uma solução rápida e fácil, e essa foi a melhor. Obrigado, realmente, a todos.
— Juano

14

Não existe tal coisa nativamente no Windows Forms.

Você deve criar seu próprio formulário para isso ou:

use a Microsoft.VisualBasicreferência.

O Inputbox é um código legado trazido para o .Net para compatibilidade com VB6 - portanto, aconselho a não fazer isso.


2
Isso é verdade para o Microsoft.VisualBasic.Compatibilitynamespace. Microsoft.VisualBasicé mais um conjunto de bibliotecas auxiliares em cima do .Net e não é nada específico do VB.
— Jim Wooley

-1 por causa da declaração imprecisa sobre a referência VB. Não há razão para assustar as pessoas com o uso desse recurso integrado muito útil.
— UuDdLrLrSs

6

Geralmente não é uma boa ideia importar as bibliotecas VisualBasic para programas C # (não porque elas não funcionem, mas apenas para compatibilidade, estilo e capacidade de atualização), mas você pode chamar Microsoft.VisualBasic.Interaction.InputBox () para exibir o tipo de caixa que você está procurando.

Se você pudesse criar um objeto Windows.Forms, seria melhor, mas você diz que não pode fazer isso.


26
Por que isso não é uma boa ideia? Quais são os possíveis problemas de "compatibilidade" e "capacidade de atualização"? Concordo que, falando "estilisticamente", a maioria dos programadores C # prefere não usar classes de um namespace chamado VisualBasic, mas isso é apenas em sua cabeça. Não há realidade nesse sentimento. Ele também seria chamado de Microsoft.MakeMyLifeEasierWithAlreadyImplementedMethodsnamespace.
— Cody Gray

3
Em geral, o pacote Microsoft.VisualBasic se destina a simplificar a atualização do código do VB 6 apenas. A Microsoft continua ameaçando encerrar permanentemente o VB (embora isso provavelmente nunca aconteça), portanto, o suporte futuro para esse namespace não é garantido. Além disso, uma das vantagens do .Net deve ser a portabilidade - o mesmo código será executado em qualquer plataforma que tenha o .Net framework instalado. O Microsoft.VisualBasic, no entanto, não tem garantia de estar disponível em qualquer outra plataforma (incluindo, para valer a pena, .Net móvel, onde não está disponível de todo).
— Sean Worle

22
Incorreta. Esse é o Microsoft.VisualBasic.Compatibilitysub-namespace, não tudo. Muitas funcionalidades "principais" estão incluídas no Microsoft.VisualBasicnamespace; não vai a lugar nenhum. A Microsoft ameaçou "encerrar" o VB 6, não o VB.NET. Eles prometeram repetidamente que não vai a lugar nenhum. Algumas pessoas ainda não parecem ter descoberto a diferença ...
— Cody Gray

4

Outra maneira de fazer isso: Supondo que você tenha um tipo de entrada TextBox, crie um formulário e tenha o valor textbox como uma propriedade pública.

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

No formulário principal, este será o código:

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

;

Dessa forma, o código parece mais limpo:

  1. Se a lógica de validação for adicionada.
  2. Se vários outros tipos de entrada forem adicionados.

4

A resposta de Bas pode te colocar em problemas de memória, teoricamente, já que ShowDialog não será descartado. Acho que essa é a maneira mais adequada. Mencione também que o textLabel pode ser lido com um texto mais longo.

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

Implementação:

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

2
Bom uso de gerenciamento de memória. Mas, isso falha ao adicionar um botão de cancelamento porque o prompté nulo nesse ponto. Uma correção simples para permitir o cancelamento do prompt é substituir prompt.Dispose();dentro de public void Dispose()porif (prompt != null) { prompt.Dispose(); }
— Marcus Parsons

3

Com base no trabalho de Bas Brekelmans acima, eu também criei duas derivações -> diálogos de "entrada" que permitem que você receba do usuário um valor de texto e um booleano (TextBox e 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());
    }
}

... e texto junto com uma seleção de uma das várias opções (TextBox e 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());
    }
}

Ambos requerem os mesmos usos:

using System;
using System.Windows.Forms;

Chame-os assim:

Chame-os assim:

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

A resposta de Bas Brekelmans é muito elegante em sua simplicidade. Mas, descobri que para um aplicativo real é necessário um pouco mais, como:

  • Aumente a forma apropriadamente quando o texto da mensagem for muito longo.
  • Não aparece automaticamente no meio da tela.
  • Não fornece nenhuma validação de entrada do usuário.

A classe aqui lida com essas limitações: http://www.codeproject.com/Articles/31315/Getting-User-Input-With-Dialogs-Part-1

Acabei de baixar o código-fonte e copiei InputBox.cs para o meu projeto.

Surpreso que não haja algo ainda melhor ... Minha única reclamação é que o texto da legenda não suporta novas linhas, pois usa um controle de rótulo.


Boa resposta, mas fora do escopo da pergunta feita
— Munim Munna

1

Infelizmente, o C # ainda não oferece esse recurso nas bibliotecas internas. A melhor solução no momento é criar uma classe personalizada com um método que exibe um pequeno formulário. Se você estiver trabalhando no Visual Studio, pode fazer isso clicando em Projeto> Adicionar classe

Adicionar classe

Visual C # items> code> class Adicionar classe 2

Nomeie a classe PopUpBox (você pode renomeá-la mais tarde, se quiser) e cole o seguinte código:

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

Você precisará alterar o namespace para o que estiver usando. O método retorna uma string, então aqui está um exemplo de como implementá-lo em seu método de chamada:

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

Este método verifica a string retornada para um valor de texto, string vazia ou "cancel" (o método getUserInput retorna "cancel" se o botão cancelar é clicado) e age de acordo. Se o usuário não inserir nada e clicar em OK, isso informará ao usuário e perguntará se deseja cancelar ou inserir novamente o texto.

Postar notas: em minha própria implementação, descobri que todas as outras respostas estavam faltando 1 ou mais dos seguintes:

  • Um botão de cancelamento
  • A capacidade de conter símbolos na string enviada para o método
  • Como acessar o método e tratar o valor retornado.

Assim, postei minha própria solução. Espero que alguém ache útil. Agradecemos aos comentaristas do Bas e do Gideon + por suas contribuições, vocês me ajudaram a encontrar uma solução viável!


0

aqui está minha versão refatorada que aceita multilinha / simples como opção

   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

Aqui está um exemplo em 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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.