Windowsフォームのプロンプトダイアログ


115

使用してSystem.Windows.Formsいますが、不思議なことにそれらを作成する能力がありません。

JavaScriptなしで、JavaScriptプロンプトダイアログのようなものを取得するにはどうすればよいですか?

MessageBoxは便利ですが、ユーザーが入力を入力する方法はありません。

ユーザーが可能なテキスト入力を入力できるようにしたい。


あなたがやろうとしていることのコード例を投稿できますか?
Andrew Cooper、

どのような入力を求めていますか、もう少し詳しく説明してください。CommonDialogはそれを継承するクラスを見て、それらのどれかがあなたに合っていると思いますか?
Sanjeevakumar Hiremath

21
3人がOPに詳細とコードサンプルを要求する方法はおかしいですが、「JavaScriptプロンプトダイアログのように」彼が何を意味するのかは明確です。
Camilo Martin

2
以下は2つの例です。1つは基本で、もう1つは入力検証があります。1.基本-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");

更新

デフォルトボタン(Enterキー)を追加し、コメントと別の質問に基づいた初期フォーカスを追加しました。


1
これをどのように拡張してA)キャンセルボタンを用意し、B)戻る前に何らかの方法でテキストフィールドのテキストを検証しますか?
ewok

@ewokフォームを作成するだけで、フォームデザイナがフォームを思い通りにレイアウトできるようになります。
Camilo Martin

1
@SeanWorleどこで言及されているのかわかりません。
2014年

1
これを追加することで達成したもの:prompt.AcceptButton = confirm;
B.クレイシャノン2014年

1
ユーザーが閉じるボタンでプロンプトをキャンセルし、空の文字列を返すように処理するコードを追加
Matthew Lock

53

への参照を追加しMicrosoft.VisualBasic、これをC#コードに使用します。

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

参照を追加するには:[プロジェクトエクスプローラー]ウィンドウで[参照]を右クリックし、[参照の追加]をクリックして、そのリストからVisualBasicを確認します。


4
これはInteraction名前空間に存在しないと言いますMicrosoft.VisualBasic
Khalil Khalaf 2017

1
これは、高dpi画面をサポートするため、カスタムクラスソリューションよりもわずかに優れています
マークガマッシュ

おそらくカスタムソリューションを使用する方が良いと思いますが、すばやく簡単なソリューションを探しています。これが最高でした。本当にありがとうございました。
Juano

14

Windowsフォームには、そのようなものは本来ありません。

そのための独自のフォームを作成する必要があります。

Microsoft.VisualBasic参照を使用します。

Inputboxは、VB6互換性のために.Netに導入されたレガシーコードです。そのため、これを行わないことをお勧めします。


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の利点の1つは移植性です。同じコードが.Netフレームワークがインストールされているすべてのプラットフォームで実行できます。ただし、Microsoft.VisualBasicは、他のプラットフォームでの使用が保証されていません(価値のあるものとしては、.Netモバイルなど、まったく使用できない場合を含みます)。
Sean Worle

22
不正解です。それMicrosoft.VisualBasic.Compatibilityは全体ではなく、サブ名前空間です。多くの「コア」機能がMicrosoft.VisualBasic名前空間に含まれています。それはどこにも行きません。マイクロソフトはVB.NETではなく、VB 6を「日没」すると脅迫しました。彼らはそれがどこにも行かないと繰り返し約束しました。一部の人々はまだ違いを理解していないようです...
コーディグレイ

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は破棄されないため、Basの答えは理論的にはメモリトラブルに陥ることがあります。これはもっと適切な方法だと思います。また、長いテキストでも読みやすい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、その時点ではがnullであるため、これは失敗します。プロンプトでキャンセルできるようにする簡単な修正置き換えることでprompt.Dispose();内部のpublic void Dispose()持つif (prompt != null) { prompt.Dispose(); }
マーカス・パーソンズ

3

上記のBas Brekelmansの研究に基づいて、テキスト値とブール値(TextBoxとCheckBox)の両方をユーザーから受け取ることができる2つの派生->「入力」ダイアログも作成しました。

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)の1つを選択したテキスト:

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

Bas Brekelmansの答えはその単純さの点で非常にエレガントです。しかし、実際のアプリケーションでは、次のようなもう少し必要なことがわかりました。

  • メッセージテキストが長すぎる場合、フォームを適切に拡大します。
  • 画面の中央に自動的にポップアップしません。
  • ユーザー入力の検証は行いません。

ここのクラスはこれらの制限を処理します:http : //www.codeproject.com/Articles/31315/Getting-User-Input-With-Dialogs-Part-1

ソースをダウンロードし、InputBox.csをプロジェクトにコピーしました。

でも、もっと良いものはないことに驚いています...私の唯一の不満は、ラベルコントロールを使用しているため、キャプションテキストが改行をサポートしていないことです。


いい答えですが、質問の範囲外
Munim Munna

1

残念ながら、C#はまだ組み込みライブラリでこの機能を提供していません。現在のところ最良の解決策は、小さなフォームをポップアップするメソッドを使用してカスタムクラスを作成することです。Visual Studioで作業している場合は、[プロジェクト]> [クラスの追加]をクリックしてこれを実行できます。

クラスを追加

Visual C#アイテム>コード>クラス クラス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メソッドは「キャンセル」を返します)、それに応じて動作します。ユーザーが何も入力せずに[OK]をクリックした場合、ユーザーに通知し、テキストをキャンセルするか再入力するかを尋ねます。

ノートを投稿する:私自身の実装では、他のすべての回答に次の1つ以上が欠けていることがわかりました。

  • キャンセルボタン
  • メソッドに送信される文字列にシンボルを含める機能
  • メソッドにアクセスして戻り値を処理する方法。

したがって、私は自分のソリューションを投稿しました。私は誰かがそれが役に立つと思うことを望みます。BasとGideonの貢献+あなたの貢献に対するコメント投稿者、あなたは私が実行可能な解決策を思い付くのを助けました!


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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.