创建输出表单 C#

Creating an output form C#

我正在尝试使用 windows 表单创建 "Debug window" 或 "Output window",因此如果用户输入有错误,我可以在此 "output window",代码和问题如下:

public partial class DebugWindow : Form
    {
        public DebugWindow()
        {
            InitializeComponent();
        }

        public void WriteDebugWindow(string text)
        {
            DateTime dt = DateTime.Now;
            text = dt.ToString("[yyyy-MM-dd HH:mm:ss] ") + text;
            listBox1.Items.Add(text);
        }
    }

还有 class

public class Debug
    {
        DebugWindow debugWindow;

        public Debug() { debugWindow = new DebugWindow(); }

        public void WriteDebugWindow(string text)
        {
            this.debugWindow.WriteDebugWindow(text);
            OpenWindow();
        }

        public void OpenWindow()
        {
            if (debugWindow.Visible)
                debugWindow.BringToFront();
            else
                debugWindow.Show(); //Problem here
        }
    }

所以,如果我尝试 运行 这样的代码:

int i = 10;
Debug.WriteDebugWindow(i.ToString());
i = 20;
Debug.WriteDebugWindow(i.ToString());

它会将文本写入列表框,但如果我使用“.Show()”,调试 window 打开,但它冻结了,我不能 close/move/etc,如果我使用“ .ShowDialog()" 它不会冻结,但它会将 i 设置为 20 并仅在我关闭 "debug window" 表单时再次打印它。

有解决办法吗?因为我尝试了一切,运行 它在一个线程中,创建一个新的立场等等,但是问题仍然存在,因为我想在以后的 "Debug.Write..." 调用中保留 listBox 项目,我不想要一个空白的 listBox每次我调用它(在使用 new DebugWindow() 的情况下)。

谢谢。

我建议您在这里查看 servys 的回答:

Run two winform windows simultaneously

以及此处的 msdn 文章:

https://msdn.microsoft.com/en-us/library/system.windows.forms.application.applicationexit.aspx

我不太确定你是如何阻塞 UI 线程的,但正如你所看到的,在没有单独线程的情况下同时显示两种形式是可能的,所以也许它是你在 "on show"调试表单的事件?

你打了多少次"write to debug window"?我会把你的调试写到一个单独的列表中,并在函数末尾有一个 "update debug form" 运行。

您甚至可以花哨并使用某种范围逻辑(使用临时日志记录 class,当它超出范围时会使用其内容更新表单)

编辑:找到解决方案:

创建了 ShowDialog() 线程

public void OpenWindow()
        {
            if (debugWindow.Visible)
                debugWindow.SafeBringToFront();
            else
                new Thread(() => debugWindow.ShowDialog()).Start();
        }

以及第二种形式的 SafeBringToFront():

public void SafeBringToFront()
        {
            this.Invoke(new MethodInvoker(delegate() { this.BringToFront(); }));
        }

谢谢大家!