Revit中实现IWin32Window的非模态Form窗口重复创建问题求助
Revit非模态输出窗口单实例优化问题
我参照相关逻辑开发了一个随Revit启动、关闭的非模态WinForm窗口,用于显示Revit文档操作的动作/命令输出信息。目前功能正常,但存在每次执行Revit命令都会创建新窗口实例的问题,希望实现仅保留一个窗口,通过隐藏/显示来响应操作。
以下是优化后的完整代码实现及说明:
Win Form类
public partial class CmdWindowHandleForm : Form { public string LabelText { get { return _labelText.Text; } set { _labelText.Text = value; } } public CmdWindowHandleForm() { InitializeComponent(); } // 实现日志追加方法 public void AddText(string message) { _labelText.Text += $"{message}{Environment.NewLine}"; // 自动滚动到最新内容 _labelText.ScrollToCaret(); } } partial class CmdWindowHandleForm { private System.ComponentModel.IContainer components = null; private Label _labelText; private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this._labelText = new Label(); this._labelText.Text = string.Empty; // 优化布局:填充窗口、支持自动换行和滚动 this._labelText.AutoSize = false; this._labelText.Dock = DockStyle.Fill; this._labelText.Padding = new Padding(5); this._labelText.Font = new Font("Consolas", 9F); this._labelText.WordWrap = true; this._labelText.AutoScroll = true; this.Controls.Add(this._labelText); this.Size = new Size(450, 350); this.Text = "Revit操作日志控制台"; } }
实现IWin32Window的WindowHandle类
public class WindowHandle : IWin32Window { public IntPtr Handle { get { return _handleWindow; } } IntPtr _handleWindow; public WindowHandle(IntPtr handleWindow) { _handleWindow = handleWindow; } }
随Revit运行的静态InfoConsole类(核心优化)
public static class InfoConsole { private static WindowHandle _hWndRevit = null; private static CmdWindowHandleForm _window = null; public static void Show(string message) { if (_hWndRevit == null) { Process process = Process.GetCurrentProcess(); IntPtr h = process.MainWindowHandle; _hWndRevit = new WindowHandle(h); } // 检查窗口实例是否存在或已被释放 if (_window == null || _window.IsDisposed) { _window = new CmdWindowHandleForm(); // 绑定关闭事件,释放后重置引用 _window.FormClosed += (sender, e) => { _window = null; }; // 以非模态方式显示,绑定Revit主窗口为父窗口 _window.Show(_hWndRevit); // 设置窗口属性:不显示在任务栏、可前置 _window.ShowInTaskbar = false; _window.TopMost = true; } else { // 窗口已存在,确保可见并前置 if (!_window.Visible) { _window.Visible = true; } _window.BringToFront(); } _window.AddText(message); } }
命令调用代码
InfoConsole.Show(outputMessage);
核心优化点说明
- 实例有效性校验:将原判断
_window == null升级为_window == null || _window.IsDisposed,避免用户手动关闭窗口后,引用仍存在但窗口已释放的无效状态。 - 关闭事件绑定:在窗口创建时绑定
FormClosed事件,用户关闭窗口时自动重置_window引用,确保下次调用能正常重建。 - 窗口状态管理:显示时自动前置窗口,避免被Revit主窗口遮挡;仅在窗口不可见时设置可见性,减少不必要的状态切换。
- UI体验优化:给Label添加自动滚动、换行和等宽字体,提升日志可读性;设置窗口默认大小和标题,增强辨识度。
内容的提问来源于stack exchange,提问作者Lukasz
相关产品推荐
相关产品推荐

