none
C#,winform跨线程控制控件的可见性问题。 RRS feed

  • 问题

  • 目的:窗体一堆控件,想要先把这些控件隐藏起来,然后再按钮的事件里到适当的时候把这些控件再显示出来。

    如果在form构造函数中将这些控件的visible=false(留个button可见)。然后在这个button下开一个线程使这些控件可见:visible=true;结果好多控件都没有画出来,有的画了一半,而且很久后这个线程才结束。

    如果在form_load里将这些控件的visible=false,然后再用另外一线程设置visible=true就没有问题。很奇怪。

     

    如果不开线程只使用窗体自己的STA线程使不可见控件变可见也没有问题。

    代码:
     public partial class frmCore 
      {
        public frmCore()
        {
          InitializeComponent();
    
          Control.CheckForIllegalCrossThreadCalls = false;
          this.progressBar1.Maximum = 222;
    
          HideCC();
        }
        private void button1_Click(object sender, EventArgs e)
        {
          ThreadStart t = new ThreadStart(delegate()
          {
            for (int i = 0; i < 220; i++)
            {
              Thread.Sleep(100);
              textBox1.Text = i.ToString();
              progressBar1.Value = i;
              if (i == 50)
                ShowCC();//<-这里画不出所有的控件,
              if (i == 100)
                HideCC();
              if (i == 150)
                ShowCC();
              if (i == 200)
                HideCC();
            }
          });
          t.BeginInvoke(null, null);
    
        }
        private void button4_Click(object sender, EventArgs e)
        {
          ShowCC();//<-这个可以
        }
    
    
        void HideCC()
        {
          button2.Visible = false;
          checkBox1.Visible = false;
          comboBox1.Visible = false;
          label1.Visible = false;
          progressBar1.Visible = false;
          radioButton1.Visible = false;
          textBox2.Visible = false;
          pictureBox1.Visible = false;
        }
    
        void ShowCC()
        {
          button2.Visible = true;
          checkBox1.Visible = true;
          comboBox1.Visible = true;
          label1.Visible = true;
          progressBar1.Visible = true;
          radioButton1.Visible = true;
          textBox2.Visible = true;
          pictureBox1.Visible = true;
        }
    
    
    
        private void frmCore_Load(object sender, EventArgs e)
        {
          //HideCC();
        }
    
    
      }
    2011年8月15日 5:27

全部回复

  • 楼主禁用了跨线程检测,可能问题出在这里,建议使用Invoke来更新UI。

    楼主可以试试在显示控件后调用一下窗体的Update方法。

    2011年8月15日 8:39
  • 啊哈,有可能是木有UPDATE....
    2015年7月30日 9:15
  • 亲,你犯了Windows 控件不能跨线程访问的大忌。这样做程序居然没崩溃你已经算是运气好了。问题出在你在button1_Click 创建了一个线程t 去显示控件。这样一来设置控件属性的线程就不是创建控件的线程(UI 线程或称0号线程)。因此,会引发跨线程访问异常。正确地跨线程操作UI 控件的方法,请参考:

    http://stackoverflow.com/questions/661561/how-to-update-the-gui-from-another-thread-in-c

    解决方法两个:

    1. 在button1_Click 方法内直接调用ShowCC(); 不必再创建线程。

    2. 修改线程t 的代码参考上面给出的连接。


    Would you know my name, if I saw you in heaven......

    2015年8月7日 23:17