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.

user420667
fonte
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 .

Bas
fonte
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.

KurvaBG
fonte
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.

Marino Šimić
fonte
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.

Sean Worle
fonte
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.
user2347528
fonte
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;
}
Gideon Mulder
fonte
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");
B. Clay Shannon
fonte
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.

blak3r
fonte
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!

technoman23
fonte
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;
        }
Alper Ebicoglu
fonte
-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
user890332
fonte