从C#控制台应用程序显示WinFrm并等待关闭

时间:2014-09-19 02:59:57

标签: c# winforms user-input

我正在尝试从C#中的控制台应用程序显示WinForm(输入框),并等待用户关闭表单。对我来说,将输入框置于顶部并在打开时激活是非常重要的。 ShowDialog()在我的情况下不起作用,因为在某些情况下它不会显示为活动表单。所以我想改变我的代码并使用Show()。通过这种方式,我可以手动查找表单是否处于活动状态,如果不是自己激活它。使用ShowDialog()。我的代码停止了,直到关闭后我才能做任何事情。

以下是我的代码。它确实显示输入框,但它被冻结。我做错了什么?在" inputBox.Show();"之后清除while循环没有做任何事情,但如果我能设法运行循环并且输入框没有冻结,我会自己理清其余部分。感谢您的帮助。

public static string mInputBox(string strPrompt, string strTitle, string strDefaultResponse)
    {
        string strResponse = null;
        Form inputBox = new Form();
        inputBox.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
        inputBox.ClientSize = new Size(500, 85);
        inputBox.Text = strTitle;
        inputBox.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
        inputBox.Left = (Screen.PrimaryScreen.Bounds.Size.Width / 2) - (inputBox.ClientSize.Width / 2);
        inputBox.Top = (Screen.PrimaryScreen.Bounds.Size.Height / 2) - (inputBox.ClientSize.Height / 2);

        Label lblPrompt = new Label();
        lblPrompt.Text = strPrompt;
        inputBox.Controls.Add(lblPrompt);

        TextBox textBox = new TextBox();
        textBox.Text = strDefaultResponse;
        inputBox.Controls.Add(textBox);

        Button okButton = new Button();
        okButton.Text = "&OK";
        inputBox.Controls.Add(okButton);

        Button cancelButton = new Button();
        cancelButton.Text = "&Cancel";
        inputBox.Controls.Add(cancelButton);

        okButton.Click += (sender, e) =>
        {
            strResponse = textBox.Text;
            inputBox.Close();
        };

        cancelButton.Click += (sender, e) =>
        {
            inputBox.Close();
        };
        inputBox.AcceptButton = okButton;
        inputBox.CancelButton = cancelButton;

        SetWindowPos(inputBox.Handle, HWND_TOPMOST, inputBox.Left, inputBox.Top, inputBox.Width, inputBox.Height, NOACTIVATE);

        inputBox.Show();

        while {true}
            Thread.Sleep(100);

        Application.DoEvents();
        return strResponse;
    }

2 个答案:

答案 0 :(得分:2)

我不确定你为什么选择这条路线,我确信有更好的方法可以做到(最后解释一下)。但是要使代码运行,您应该在循环中添加Application.DoEvents()

代码应该是这样的:

        var formActive = true;
        inputBox.FormClosed += (s, e) => formActive = false;
        inputBox.Show();
        inputBox.TopMost = true;
        inputBox.Activate();

        while (formActive)
        {
            Thread.Sleep(10);
            Application.DoEvents();
        }

,整个方法将是:

    public static string mInputBox(string strPrompt, string strTitle, string strDefaultResponse)
    {
        string strResponse = null;
        Form inputBox = new Form();
        inputBox.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
        inputBox.ClientSize = new Size(500, 85);
        inputBox.Text = strTitle;
        inputBox.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
        inputBox.Left = (Screen.PrimaryScreen.Bounds.Size.Width/2) - (inputBox.ClientSize.Width/2);
        inputBox.Top = (Screen.PrimaryScreen.Bounds.Size.Height/2) - (inputBox.ClientSize.Height/2);

        Label lblPrompt = new Label();
        lblPrompt.Text = strPrompt;
        inputBox.Controls.Add(lblPrompt);

        TextBox textBox = new TextBox();
        textBox.Text = strDefaultResponse;
        inputBox.Controls.Add(textBox);

        Button okButton = new Button();
        okButton.Text = "&OK";
        inputBox.Controls.Add(okButton);

        Button cancelButton = new Button();
        cancelButton.Text = "&Cancel";
        inputBox.Controls.Add(cancelButton);

        okButton.Click += (sender, e) =>
        {
            strResponse = textBox.Text;
            inputBox.Close();
        };

        cancelButton.Click += (sender, e) =>
        {
            inputBox.Close();
        };
        inputBox.AcceptButton = okButton;
        inputBox.CancelButton = cancelButton;


        var formActive = true;
        inputBox.FormClosed += (s, e) => formActive = false;
        inputBox.Show();
        inputBox.TopMost = true;
        inputBox.Activate();

        while (formActive)
        {
            Thread.Sleep(10);
            Application.DoEvents();
        }

        return strResponse;
    }

但我认为从Form派生并创建一个InputBox并设置TopMost并调用Activate OnLoad以创建您需要的内容是更好的主意,然后只需拨打ShowDialog,例如:

class Inputbox : Form
        {

            protected override void OnLoad(EventArgs e)
            {
                base.OnLoad(e);

                TopMost = true;
                Activate();
            }
        }

最好将UI代码放在InputBox类中,因为整个代码和用法如下:

class Inputbox : Form
{
    public string Response { get; set; }

    public Inputbox(string strTitle, string strPrompt, string strDefaultResponse)
    {
        //add UI and Controls here

        FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
        ClientSize = new Size(500, 85);
        Text = strTitle;
        StartPosition = System.Windows.Forms.FormStartPosition.Manual;
        Left = (Screen.PrimaryScreen.Bounds.Size.Width/2) - (ClientSize.Width/2);
        Top = (Screen.PrimaryScreen.Bounds.Size.Height/2) - (ClientSize.Height/2);

        Label lblPrompt = new Label();
        lblPrompt.Text = strPrompt;
        Controls.Add(lblPrompt);

        TextBox textBox = new TextBox();
        textBox.Text = strDefaultResponse;
        Controls.Add(textBox);

        Button okButton = new Button();
        okButton.Text = "&OK";
        Controls.Add(okButton);

        Button cancelButton = new Button();
        cancelButton.Text = "&Cancel";
        Controls.Add(cancelButton);

        okButton.Click += (sender, e) =>
        {
            Response = textBox.Text;
            Close();
        };

        cancelButton.Click += (sender, e) =>
        {
            Close();
        };
        AcceptButton = okButton;
        CancelButton = cancelButton;
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        TopMost = true;
        Activate();
    }
}

public static string mInputBox(string strPrompt, string strTitle, string strDefaultResponse)
{
    string strResponse = null;
    Inputbox inputBox = new Inputbox(strPrompt,strTitle,strDefaultResponse);

    inputBox.ShowDialog();

    return inputBox.Response;
}

答案 1 :(得分:0)

您需要运行一个消息循环:

Application.Run(inputBox);