有没有办法为 LINQPad 应用程序获取 IWin32Window?

Is there a way to get a IWin32Window for LINQPad application?

我正在尝试为 WinForm 调用 ShowDialog(创建表单的实际代码位于 .linq 脚本中)并且一切正常,但对话框没有显示在 LINQPad 应用程序的中心。当多个显示器在运行并且我盯着 LINQPad 时,这是有问题的,运行 我的脚本和对话框会在不同的显示器上弹出。我假设将 IWin32Window 传递给 ShowDialog 将显示以所有者为中心的对话框,但我不知道如何从 LINQPad 获取 IWin32Window ...这可能吗?

您在尝试为表单设置父级时将面临的困难是您的查询运行在与 LINQPad.exe 不同的进程中。

您可以使用 LINQPad.Util.HostProcessID 获取 LINQPad 的进程 ID,然后使用 Process.GetProcessById (Util.HostProcessID).MainWindowHandle 获取 Windows 句柄,但您仍然无法为您的表单设置父级。您可以做的最好的事情是调用 Win32 函数,例如 GetWindowRect 以获得 LINQPad 的主要 window 位置,然后手动将您的表单居中。

与其胡思乱想,您是否考虑过放弃所需的控件?然后 LINQPad 将在输出窗格中呈现它并启动消息循环。例如:

var panel = new Panel { Padding = new Padding(10) };
panel.Controls.Add (new TextBox { Dock = DockStyle.Top });
panel.Controls.Add (new Label { Dock = DockStyle.Top, AutoSize=true, Text="Testing" });
panel.Dump();

请注意,您随后从控件的事件处理程序中显示的任何表单以父项为中心:

panel.Controls[1].Click += (sender, args) =>
    new Form { StartPosition = FormStartPosition.CenterParent }.ShowDialog();

作为对@Albahari 回答的小小贡献:

var dialog = new FolderBrowserDialog();
var handle = Process.GetProcessById(Util.HostProcessID).MainWindowHandle;
var win32Window = new NativeWindow();
win32Window.AssignHandle(handle);
if (dialog.ShowDialog(win32Window) != DialogResult.OK)
{
    "Aborted".Dump();
    return;
}