C# 方法运行时无法单击按钮 private void addmyscrolleventhandler() { VScrollBar vScrollBar1=新的VScrollBar(); } 私有无效按钮1\u单击(对象发送者,事件参数e) { while(true) { if(vScrollBar1.Value+1
我是新来的。我在写卷轴。这里我想要的是,如果有人点击按钮1,然后自动滚动到末尾,我想在标签1中显示渐变值。还有,当有人点击按钮2滚动停止 现在的问题是label1不显示值的逐渐变化。当滚动停止时,它显示一次值 另外,当滚动继续时,即当循环工作时,我不能单击按钮2。事实上,我甚至不能点击表格C# 方法运行时无法单击按钮 private void addmyscrolleventhandler() { VScrollBar vScrollBar1=新的VScrollBar(); } 私有无效按钮1\u单击(对象发送者,事件参数e) { while(true) { if(vScrollBar1.Value+1,c#,winforms,scroll,C#,Winforms,Scroll,我是新来的。我在写卷轴。这里我想要的是,如果有人点击按钮1,然后自动滚动到末尾,我想在标签1中显示渐变值。还有,当有人点击按钮2滚动停止 现在的问题是label1不显示值的逐渐变化。当滚动停止时,它显示一次值 另外,当滚动继续时,即当循环工作时,我不能单击按钮2。事实上,我甚至不能点击表格 有人请告诉我一些方法。发生这种情况是因为执行任务的线程很忙,而更新UI的是同一个线程。您可以使用多线程解决方案。看看 所有UI事件都在应用程序的主线程中运行,因此应用程序一次只能处理一个事件。当应用程序正在处
有人请告诉我一些方法。发生这种情况是因为执行任务的线程很忙,而更新UI的是同一个线程。您可以使用多线程解决方案。看看
所有UI事件都在应用程序的主线程中运行,因此应用程序一次只能处理一个事件。当应用程序正在处理事件时,不会处理其他事件 由于您定期执行与UI相关的工作,因此最好的选择是使用该类:
Timer
从工具箱中放入表单中勾选
事件处理程序timer1\u Tick
方法中:
private void AddMyScrollEventHandlers()
{
VScrollBar vScrollBar1 = new VScrollBar();
}
private void button1_Click(object sender, EventArgs e)
{
while (true)
{
if (vScrollBar1.Value + 1 < vScrollBar1.Maximum)
{
vScrollBar1.Value = vScrollBar1.Value + 1;
label1.Text = vScrollBar1.Value.ToString();
}
else
{
break;
}
System.Threading.Thread.Sleep(200);
}
}
private void button2_Click(object sender, EventArgs e)
{
// vScrollBar1.Scroll
}
现在您完成了。我建议使用Agustin Meriles建议的
BackgroundWorker
控件。然而,需要注意的一点是,您应该使用Control.Invoke(…)
方法从另一个线程更新控件
我已经修改了您的代码,在一个示例应用程序中对其进行了测试,它似乎工作正常
首先,在表单中添加一个新的BackgroundWorker
控件,并将backgroundWorker1\u DoWork
分配给它的DoWork
事件
然后,您可以使用以下代码:
private void AddMyScrollEventHandlers()
{
timer1.Start();
}
private void button2_Click(object sender, EventArgs e)
{
timer1.Stop();
}
private void按钮1\u单击(对象发送者,事件参数e)
{
//代码从这里移到BackgroundWorker控件
backgroundWorker1.RunWorkerAsync();
}
私有无效按钮2\u单击(对象发送者,事件参数e)
{
}
私有void backgroundWorker1\u DoWork(对象发送方,DoWorkEventArgs e)
{
//while(true)
//在我看来,while中直接出现的情况更清楚
而(vScrollBar1.Value+1
如果您在使用此代码时遇到任何问题,请告诉我
更新
如注释中所述,您还可以使用BackgroundWorker
的ProgressChanged
事件。它需要对代码进行更多的更改,但更适合这种情况。您可以在此处找到有关它的一些信息:
如果您不打算在
while
循环中添加任何其他具有更多处理的代码,您也可以使用计时器
控件,正如MD.Unicorn在其回答中所建议的那样。BackgroundWorker不适合此场景。所有流程都与用户界面相关。他可以很容易地使用windows窗体计时器。你是对的,但我想System.Threading.Thread.Sleep(200)代码>表示将在DoWork
中执行的任务。否则,代码就没有太多的意义Well,这正是设计的目的。ProgressChagned
事件和BackgroundWorker
类的ReportProgress
方法旨在消除这一点。不需要通过使用调用。实际上,使用计时器
更容易解决所有问题。是的,您也可以使用报告进度
<如果在while
循环中没有添加额外的处理,但是如果提出问题的人希望改进代码并添加一些其他计算等,BackgroundWorker
可能会更好,那么code>定时器在这种特殊情况下更合适。
private void AddMyScrollEventHandlers()
{
timer1.Start();
}
private void button2_Click(object sender, EventArgs e)
{
timer1.Stop();
}
private void button1_Click(object sender, EventArgs e)
{
//code from here is moved to BackgroundWorker control
backgroundWorker1.RunWorkerAsync();
}
private void button2_Click(object sender, EventArgs e)
{
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
//while (true)
//the condition directly in the while looks more clear to me
while (vScrollBar1.Value + 1 < vScrollBar1.Maximum)
{
//update controls using Invoke method and anonymous functions
vScrollBar1.Invoke((MethodInvoker)delegate() { vScrollBar1.Value += 1; });
label1.Invoke((MethodInvoker)delegate() { label1.Text = vScrollBar1.Value.ToString(); });
//when called inside BackgroundWorker, this sleeps the background thread,
//so UI should be responsive now
System.Threading.Thread.Sleep(200);
}
}