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
}
我是C#的新手。我正在做卷轴。我想要的是,如果有人点击button1然后滚动自动移动到最后我想在label1中显示渐变值。当有人点击button2滚动停止时。
现在问题是label1没有显示值的逐渐变化。它在滚动停止时显示一次值。
当滚动继续i时,e在while循环工作时我无法点击button2。实际上我甚至无法点击表格。
有人请告诉我如何做到这一点。
答案 0 :(得分:5)
这是因为执行任务的线程正忙,而且它是更新UI的相同线程。您可以使用多线程解决方案。看一眼
BackgroundWorker
答案 1 :(得分:1)
所有UI事件都在应用程序的主线程中运行,因此应用程序一次只能处理一个事件。当应用程序处理事件时,不会处理任何其他事件。
由于您定期进行与UI相关的工作,最好的选择是使用Timer
类:
Timer
从工具箱中删除到表单中。Tick
事件处理程序。将此代码放在新创建的timer1_Tick
方法中:
if (vScrollBar1.Value + 1 < vScrollBar1.Maximum)
{
vScrollBar1.Value = vScrollBar1.Value + 1;
label1.Text = vScrollBar1.Value.ToString();
}
else
{
timer1.Stop();
}
更改您的方法如下:
private void AddMyScrollEventHandlers()
{
timer1.Start();
}
private void button2_Click(object sender, EventArgs e)
{
timer1.Stop();
}
现在你已经完成了。
答案 2 :(得分:0)
我建议使用{em> Agustin Meriles 建议的BackgroundWorker
控件。但是,需要注意的另一个重要事项是,您应该使用Control.Invoke(...)
方法从另一个线程更新控件。
我修改了您的代码,在示例应用程序中对其进行了测试,但它似乎正常运行。
首先,向您的表单添加一个新的BackgroundWorker
控件,并将backgroundWorker1_DoWork
分配给其DoWork
事件。
然后,您可以使用以下代码:
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);
}
}
如果您在使用此代码时遇到任何问题,请告知我们。
<强>更新强>
如评论中所述,您还可以使用ProgressChanged
的{{1}}事件。它需要在代码中进行一些更改,但在这种情况下更合适。您可以在此处找到有关它的一些信息:http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.progresschanged.aspx。
如果您不打算在BackgroundWorker
循环中添加任何其他代码以及更多处理,您也可以按照 MD.Unicorn 的建议使用while
控件他的回答。