gpt4 book ai didi

c# - 鼠标 "buffering"单击禁用按钮

转载 作者:行者123 更新时间:2023-11-30 21:37:03 29 4
gpt4 key购买 nike

我的程序是一个文本游戏,它使用 WindowsForm 上的文本框模拟控制台输出。我试图实现的一个功能是通过单击一个按钮,它将以一定的速度输出到 TextBox,这是通过这种方法实现的 atm:

public static void Write(String text, Color color, TextBox textArea, UI ui)
{
ui.Enabled = false;
foreach (Control b in ui.Controls)//Disable controls
{
if (b.GetType() == typeof(Button))
b.Enabled= false;
}
textArea.ForeColor = color;
foreach (char c in text) //Write the text
{
textArea.AppendText(c.ToString());
if (c == '\n')
{
textArea.AppendText("\n");
Thread.Sleep(100);
}
Thread.Sleep(30);
}
textArea.AppendText("\n");
foreach (Control b in ui.Controls)//Enable controls
{
if (b.GetType() == typeof(Button))
b.Enabled= true;
}
ui.Enabled = true;
}

按钮事件是这样调用的:

    private void btn1_Click(object sender, EventArgs e)
{
Core.Write("this is button 1", Color.Red, txtDialog, this);
}
private void btn2_Click(object sender, EventArgs e)
{
Core.Write("this is button 2", Color.Green, txtDialog, this);
}
private void btn3_Click(object sender, EventArgs e)
{
Core.Write("this is button 3", Color.Blue, txtDialog,this);
}
private void btn4_Click(object sender, EventArgs e)
{
Core.Write("this is button 4", Color.White, txtDialog,this);
}

我注意到的是,即使在没有完成编写逻辑的情况下禁用了按钮和表单,通过多次单击任何给定按钮,它也会“保存”单击并在编写后立即输出前面的已经完成。

我应该怎么做才能消除这个错误?非常感谢

最佳答案

据我所知,这段代码应该不会像您预期的那样工作,但它应该会像您描述的那样工作为错误。这种情况不是错误,这就是 Windows 的工作方式。 Windows 为每个应用程序创建一个消息队列,并将每个事件转发到该消息队列和该应用程序的主线程(WinForms 的 GUI 线程),并按顺序处理消息。

您的代码所做的是,它禁用容器(UI?)并隐藏按钮并尝试通过暂停几毫秒来编写一些文本,然后启用所有内容。所有这些都发生在本应处理消息的 UI 线程中。

现在,当您点击时,应用会收到一个点击事件,并运行您的代码,这需要一些时间。当您的代码正在运行时(请记住 Thread.Sleep),用户单击您的按钮所在的位置,Windows 会将消息发布到您的应用队列以供下一步处理。何时处理此消息?在您的代码完成后,因为它是处理消息和运行您自己的代码的同一个线程。当您的代码完成时(按钮和 UI 再次可用),然后处理下一条消息。

尝试使用在另一个线程中运行的 BackgroundWorker

public static void Write(String text, Color color, TextBox textArea, Form ui)
{
textArea.ForeColor = color;

var handler = new Action<string>(textArea.AppendText);

foreach (char c in text) //Write the text
{
textArea.Invoke(handler, c.ToString());
if (c == '\n')
{
textArea.Invoke(handler, "\n");
Thread.Sleep(100);
}
Thread.Sleep(30);
}
textArea.Invoke(handler, "\n");
}

private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
button1.Enabled = true;

}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Write("this is button 1", Color.Red, textBox1, this);
}

关于c# - 鼠标 "buffering"单击禁用按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47659284/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com