如何在C#控制台应用程序中创建无模式对话框
我想用下面的代码创建一个无模式对话框。 然而,表单在创建后似乎没有响应。 我想如果我以这种方式创建消息循环,它可能会被阻塞。 有人知道如何以正确的方式创建它吗如何在C#控制台应用程序中创建无模式对话框,c#,.net,dialog,modal-dialog,modeless-dialog,C#,.net,Dialog,Modal Dialog,Modeless Dialog,我想用下面的代码创建一个无模式对话框。 然而,表单在创建后似乎没有响应。 我想如果我以这种方式创建消息循环,它可能会被阻塞。 有人知道如何以正确的方式创建它吗 class Program { static void Main(string[] args) { Form form = new Form(); form.Show(); Console.ReadLine(); } } 显示模式和非模式Windows窗体: 要将窗
class Program
{
static void Main(string[] args)
{
Form form = new Form();
form.Show();
Console.ReadLine();
}
}
显示模式和非模式Windows窗体: 要将窗体显示为无模式对话框,请调用Show方法:
以下示例显示如何以非模态格式显示“关于”对话框
// C#
//Display frmAbout as a modeless dialog
Form f= new Form();
f.Show();
要将窗体显示为模式对话框,请调用ShowDialog方法。下面的示例演示如何以模式显示对话框
// C#
//Display frmAbout as a modal dialog
Form frmAbout = new Form();
frmAbout.ShowDialog();
见:
请参阅以下控制台应用程序代码:
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
class Test
{
[STAThread]
static void Main()
{
var f = new Form();
f.Text = "modeless ";
f.Show();
var f2 = new Form() { Text = "modal " };
Application.Run(f2);
Console.WriteLine("Bye");
}
}
您可以使用另一个线程,但必须等待该线程加入或中止:与此工作示例代码类似:
using System;
using System.Threading;
using System.Windows.Forms;
namespace ConsoleApplication2
{
static class Test
{
[STAThread]
static void Main()
{
var f = new Form { Text = "Modeless Windows Forms" };
var t = new Thread(() => Application.Run(f));
t.Start();
// do some job here then press enter
Console.WriteLine("Press Enter to Exit");
var line = Console.ReadLine();
Console.WriteLine(line);
//say Hi
if (t.IsAlive) f.Invoke((Action)(() => f.Text = "Hi"));
if (!t.IsAlive) return;
Console.WriteLine("Close The Window");
// t.Abort();
t.Join();
}
}
}
最后,我让它工作了。
为了解除主线程的阻塞,我必须使用一个新线程并调用applicationin.Run为表单创建一个消息泵。
现在窗体和主线程都处于活动状态。
谢谢大家
class Program
{
public static void ThreadProc(object arg)
{
Form form = arg as Form;
Application.Run(form);
}
[STAThread]
static void Main(string[] args)
{
Form form = new Form() { Text = "test" };
Thread t = new Thread(ThreadProc);
t.Start(form);
string line = Console.ReadLine();
Console.WriteLine(line);
form.Close();
}
}
你肯定是说非模态的?Application.Run()是必需的,您不必在主线程上调用它。而且您不能这样做,Thread.SetApartmentState()是UI线程的硬要求。这使得ShowDialog()成为一个bug,一个很难诊断的bug。使用Thread类。@Hans Passant是的,你说得对。谢谢,你的代码可以工作。但Application.Run将被阻止。所以我必须将它移动到另一个线程。@shi frank:是的,您可以使用另一个线程,但您必须等待该线程加入或中止它,请参阅最后一个示例代码。如果在关闭该窗体之前按Enter键,会发生什么情况:您必须等待另一个线程加入,请参阅我的上一个示例代码:System.InvalidOperationException未经处理。如果没有t.Join(),我无法获得此错误;实际上,Application.Run将一直阻塞,直到调用form.Close()为止。所以在窗体之前连接。关闭将是一个死锁。嗯,是的,在关闭()之前连接()是错误的。它不会导致死锁,您仍然可以在GUI上关闭表单,但是当表单已经关闭并且可能已被释放时,将调用close()。另一方面,Close()之后的Join()是可以的。