Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 方法运行时无法单击按钮 private void addmyscrolleventhandler() { VScrollBar vScrollBar1=新的VScrollBar(); } 私有无效按钮1\u单击(对象发送者,事件参数e) { while(true) { if(vScrollBar1.Value+1_C#_Winforms_Scroll - Fatal编程技术网

C# 方法运行时无法单击按钮 private void addmyscrolleventhandler() { VScrollBar vScrollBar1=新的VScrollBar(); } 私有无效按钮1\u单击(对象发送者,事件参数e) { while(true) { if(vScrollBar1.Value+1

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事件都在应用程序的主线程中运行,因此应用程序一次只能处理一个事件。当应用程序正在处

我是新来的。我在写卷轴。这里我想要的是,如果有人点击按钮1,然后自动滚动到末尾,我想在标签1中显示渐变值。还有,当有人点击按钮2滚动停止

现在的问题是label1不显示值的逐渐变化。当滚动停止时,它显示一次值

另外,当滚动继续时,即当循环工作时,我不能单击按钮2。事实上,我甚至不能点击表格


有人请告诉我一些方法。

发生这种情况是因为执行任务的线程很忙,而更新UI的是同一个线程。您可以使用多线程解决方案。看看
所有UI事件都在应用程序的主线程中运行,因此应用程序一次只能处理一个事件。当应用程序正在处理事件时,不会处理其他事件

由于您定期执行与UI相关的工作,因此最好的选择是使用该类:

  • Timer
    从工具箱中放入表单中
  • 在“属性”窗口中,将间隔设置为200
  • 双击计时器对象以创建
    勾选
    事件处理程序
  • 将此代码放入新创建的
    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);
        }
    }