web-dev-qa-db-fra.com

Dialogue d'invite dans Windows Forms

J'utilise System.Windows.Forms mais étrangement, je n'ai pas la possibilité de les créer.

Comment puis-je obtenir quelque chose comme un dialogue d'invite javascript, sans javascript?

MessageBox est agréable, mais l'utilisateur n'a aucun moyen de saisir une entrée.

94
user420667

Vous devez créer votre propre boîte de dialogue d'invite. Vous pourriez peut-être créer une classe pour cela.

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

Et en l'appelant:

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

Mettre à jour:

Bouton par défaut ajouté (touche entrée) et focus initial basé sur les commentaires et une autre question .

239
Bas

Ajoutez une référence à Microsoft.VisualBasic et utilisez-la dans votre code C #:

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

Il n'y a rien de tel en mode natif dans Windows Forms.

Vous devez créer votre propre formulaire pour cela ou:

utilisez la référence Microsoft.VisualBasic.

Inputbox est un code hérité introduit dans .Net pour la compatibilité VB6 - je vous conseille donc de ne pas le faire.

15
Marino Šimić

Ce n'est généralement pas une bonne idée d'importer les bibliothèques VisualBasic dans des programmes C # (non pas parce qu'elles ne fonctionneront pas, mais uniquement pour des raisons de compatibilité, de style et de mise à niveau), mais vous pouvez appeler Microsoft.VisualBasic.Interaction.InputBox (). pour afficher le type de boîte que vous recherchez.

Si vous pouvez créer un objet Windows.Forms, ce serait mieux, mais vous dites que vous ne pouvez pas le faire.

7
Sean Worle

Autre moyen de procéder: En supposant que vous ayez un type d’entrée TextBox, Créez un formulaire et que la valeur de la zone de texte soit propriété publique.

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

Dans la forme principale, ce sera le code:

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

;

De cette façon, le code a l'air plus propre:

  1. Si la logique de validation est ajoutée.
  2. Si plusieurs autres types d’entrée sont ajoutés.
4
user2347528

Sur la base des travaux de Bas Brekelmans ci-dessus, j'ai également créé deux boîtes de dialogue de dérivations -> "input" qui vous permettent de recevoir de l'utilisateur une valeur texte et une valeur booléenne (TextBox et 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());
    }
}

... et du texte avec une sélection de plusieurs options (TextBox et 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());
    }
}

Les deux nécessitent les mêmes utilisations:

using System;
using System.Windows.Forms;

Appelez-les comme suit:

Appelez-les comme suit:

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

La réponse de Bas peut vous mettre théoriquement en mémoire, double-sens, puisque ShowDialog ne sera pas disposé . Je pense que c'est une manière plus appropriée . Mentionnez également que textLabel est lisible avec un texte plus long.

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

La mise en oeuvre:

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

La réponse de Bas Brekelmans est très élégante par sa simplicité. Mais, j'ai trouvé que pour une application réelle, un peu plus est nécessaire, tel que:

  • Développez la forme de manière appropriée lorsque le texte du message est trop long.
  • Ne surgit pas automatiquement au milieu de l'écran.
  • Ne fournit aucune validation de la saisie de l'utilisateur.

La classe gère ici les limitations suivantes: http://www.codeproject.com/Articles/31315/Getting-User-Input-With-Dialogs-Part-1

Je viens de télécharger le code source et de copier InputBox.cs dans mon projet.

Surpris, il n'y a rien de mieux, cependant ... Mon seul reproche, c'est que le texte de la légende ne prend pas en charge les retours à la ligne car il utilise un contrôle d'étiquette.

1
blak3r

Malheureusement, C # n'offre toujours pas cette possibilité dans les bibliothèques intégrées. La meilleure solution à l’heure actuelle consiste à créer une classe personnalisée avec une méthode qui affiche un petit formulaire . Si vous travaillez dans Visual Studio, vous pouvez le faire en cliquant sur Projet> Ajouter une classe.

 Add Class

Éléments Visual C #> code> classe  Add Class 2

Nommez la classe PopUpBox (vous pourrez la renommer ultérieurement si vous le souhaitez) et collez le code suivant:

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

Vous devrez modifier l’espace de nom en fonction de ce que vous utilisez. La méthode retourne une chaîne, alors voici un exemple de la façon de la mettre en œuvre dans votre méthode d'appel:

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

Cette méthode recherche dans la chaîne renvoyée une valeur textuelle, une chaîne vide ou "cancel" (la méthode getUserInput renvoie "cancel" si le bouton d'annulation est cliqué) et agit en conséquence. Si l'utilisateur n'a rien saisi et cliqué sur OK, il le prévient et lui demande s'il souhaite annuler ou ressaisir son texte.

Notes sur le poste: Dans ma propre mise en œuvre, j'ai constaté qu'il manquait toutes les autres réponses avec au moins un des éléments suivants:

  • Un bouton d'annulation
  • La possibilité de contenir des symboles dans la chaîne envoyée à la méthode
  • Comment accéder à la méthode et gérer la valeur renvoyée.

Ainsi, j'ai posté ma propre solution. J'espère que quelqu'un le trouvera utile. Merci à Bas et à Gideon + pour vos contributions, vous m'avez aidé à trouver une solution viable! 

0
technoman23

voici ma version refactorisée qui accepte multiligne/single en option

   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