web-dev-qa-db-ja.com

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

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

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

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

ユーザーに可能なテキスト入力を入力してほしい。

99
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)およびコメントと 別の質問 に基づく初期フォーカスを追加しました。

254
Bas

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

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

Windows Formsにはそのようなことはネイティブにはありません。

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

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

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

15
Marino Šimić

VisualBasicライブラリをC#プログラムにインポートすることは一般的には良い考えではありません(動作しないためではなく、互換性、スタイル、およびアップグレード機能のためだけです)が、Microsoft.VisualBasic.Interaction.InputBox()を呼び出すことができます探している種類のボックスを表示します。

Windows.Formsオブジェクトを作成できる場合はそれが最善ですが、それはできないと言います。

7
Sean Worle

これを行う他の方法:TextBox入力タイプがあると仮定して、フォームを作成し、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

Basの答えは、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;
}
3
Gideon Mulder

上記の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)のいずれかの選択:

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

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

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

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

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

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

1
blak3r

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

Add Class

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

投稿メモ:私自身の実装では、他のすべての回答に次の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