我最近开始了一个C#项目(VS 2008),作为一个'Console'项目,我写了一些库,测试程序等.现在我想添加几个WPF窗口,但看起来控制台项目不会让我这样做.我来自Java所以这有点奇怪.如何添加WPF表单(我将从我的"主"类中实例化我的自我?
Jam*_*ins 25
我有同样的问题,正在寻找类似的答案.我发现了整个地方的信息,所以我把我在一个地方找到的东西放进去了.我还需要一种隐藏和显示控制台窗口的方法,所以我发现这有效(对于VS 2013+):
创建一个新的控制台项目(确保选择您需要使用的.NET框架版本 - 我需要自己使用.Net 4.0).确保有以下参考:
右键单击解决方案资源管理器中的项目,选择"属性",然后将项目输出类型更改为Windows应用程序.这可以防止控制台窗口在启动时显示(如果需要,可以跳过此步骤).
虽然为了添加WPF窗口不需要控制控制台窗口,但它可能很有用.如果您不需要,请跳至#4.在控制台的"Program"类中,添加此项以控制窗口:
public class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AllocConsole(); // Create console window
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow(); // Get console window handle
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_HIDE = 0;
const int SW_SHOW = 5;
Run Code Online (Sandbox Code Playgroud)
这允许创建,隐藏和显示控制台窗口.我创建了这些方法来执行此操作:
static void ShowConsole()
{
var handle = GetConsoleWindow();
if (handle == IntPtr.Zero)
AllocConsole();
else
ShowWindow(handle, SW_SHOW);
}
static void HideConsole()
{
var handle = GetConsoleWindow();
if (handle != null)
ShowWindow(handle, SW_HIDE);
}
Run Code Online (Sandbox Code Playgroud)
这些大多是自解释的,但如果项目处于窗口模式,则GetConsoleWindow();返回null,所以这里我们测试句柄是否为空(在这种情况下为零),如果是,则需要创建一个控制台窗口(仅一次).在此之后,GetConsoleWindow();将始终返回一个使用的句柄.
正如另一个答案中所述,您需要[STAThread]在控制台Main方法之前添加一行.这是必需的,因为WPF需要在Single Threaded Apartment环境中运行.
[STAThread]
static void Main(string[] args)
{
}
Run Code Online (Sandbox Code Playgroud)添加窗口:为此,只需将用户控件添加到项目中并将其命名为"MainWindow"(或任何您喜欢的名称).只需右键单击解决方案资源管理器中的项目节点,然后选择Add->User Control....打开后面的MainWindow.xaml.cs代码并更改MainWindow : UserControl为MainWindow : Window.接下来,打开MainWindow.xaml文件并将第一个标记更改<UserControl为<Window(并确保也重命名结束标记,如果使用Visual Studio,则应该是自动的).关闭所有"MainWindow"编辑器选项卡并重新打开(只是为了确保,可能没有必要).您应该看到MainWindow.xaml现在在设计窗格中显示一个窗口.
显示WPF窗口:为此,我们需要启动窗口消息循环,这非常简单.首先,我创建了一些属性来存储对象.把它放在Program课堂上的某个地方.
public static Application WinApp { get; private set; }
public static Window MainWindow { get; private set; }
Run Code Online (Sandbox Code Playgroud)
接下来,我们必须通过创建一个System.Windows.Application对象来创建消息循环,然后将其传递给主窗口.我创建了此方法来执行此任务:
static void InitializeWindows()
{
WinApp = new Application();
WinApp.Run(MainWindow = new MainWindow()); // note: blocking call
}
Run Code Online (Sandbox Code Playgroud)
就是这样!要对此进行测试,请在主窗口中放置一些内容并执行以下操作:
[STAThread]
static void Main(string[] args)
{
ShowConsole(); // Show the console window (for Win App projects)
Console.WriteLine("Opening window...");
InitializeWindows(); // opens the WPF window and waits here
Console.WriteLine("Exiting main...");
}
Run Code Online (Sandbox Code Playgroud)希望有助于节省时间,欢呼!;)
提示:在我的情况下,我发现InitializeWindows()在新线程中调用是有帮助的; 但是,这意味着您必须在创建对象的同一个线程中创建UI对象(以及其他内容)Application.为了与新线程通信,我只是使用Dispatcherclass(WinApp.Dispatcher.BeginInvoke())在WPF线程上下文中运行请求.
对于Windows 8/10:如果您正在调试并且在输出窗口中没有看到任何文本,请查看此处:https://stackoverflow.com/a/49145317/1236397
aku*_*aku -1
您确定需要控制台项目吗?您可以创建“WPF 应用程序”项目并添加对库的引用等。如果尝试从控制台应用程序显示 WPF 窗口,由于控制台和 WPF 应用程序之间的线程模型存在差异,您将生成异常。