创建输出表单 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(); }));
}
谢谢大家!
我正在尝试使用 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(); }));
}
谢谢大家!