我的程序是整个项目中的大屏幕显示部分。
大屏幕用一个4X4个单元格的TableLayoutPanel控件(控件名:tableLayoutPanel1)来控制屏幕分布。
自定义了一个有很多Label的控件UCPointMachineNewStatistic(控件名:ustate1)
程序初始化时,利用自己写的布局方法动态地把ustate1分布在tableLayoutPanel1上,并且有规定显示ustate1的个数。
现有别的程序的线程给我发送一个消息:改变ustate1的显示个数。
屏幕显示要根据新的个数要求刷新屏幕并重新分布。部分代码如下:namespace FS0501
{
    public partial class frmPoint : Form
    {
        #region 设定控件委托
        delegate void ScreenMessage();
        ScreenMessage SM1;
        #endregion        #region 构造函数
        public frmPoint()
        {
            InitializeComponent();
            this.Probot.BeginListening();//启动信息侦听
            GetConfig();
        }
        #endregion        #region 侦听函数
        private void Probot_ReceiveMessage(object sender, ReceiveMessageEventArgs e)
        {
            try
            {
                if (某几种e的消息种类)
                {
                    SM1 = new ScreenMessage(GetConfig);
                    SM1.Invoke();
                }
            }
            catch (Exception ex)
            {
                Log.OutputLog(ModuleType.WinForm, "FS0501", "大屏程序", LogLevel.Error, "", ex);
            }
        }
        #endregion        #region 屏幕关闭 结束侦听
        private void frmPoint_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.Probot.EndListening();
        }
        #endregion        #region 获取配置信息
        /// <summary>
        /// 获取配置信息
        /// </summary>
        private void GetConfig()
        {
            //访问数据库获得要显示的控件个数代码省略
            ...
            
            
            if (dt.Rows.Count > 0)//dt是DataTable类型
            {
                /// 确定要显示的控件个数
                string count = dt.Rows[0]["COUNT"].ToString();
                ///////////////////这里出问题///////////////////////
                if (this.tableLayoutPanel1.InvokeRequired == true) 
                {
                    this.tableLayoutPanel1.Controls.Clear();
                }
                else
                {
                    this.tableLayoutPanel1.Controls.Clear();
                }
                switch (count)
                {
                    case "2": //显示2个控件
                        {
                            int rn = 1;//行数
                            int cn = 2;//列数
                            int i = 1; //控件号码
                            for (int row = 0; row < cn; row++)//行
                            {
                                for (int col = 0; col < rn; col++)//列
                                {
                                    创建ustate1并SetColumnSpan和SetRowSpan
                                    ustate1.lblNo.Text = i.ToString();//lblNo是ustate1中的一个Label
                                    
                                    i++;
                                }
                            }
                        } break;
                    case "4": //显示4个控件
                        {
                            方法与"2"相同
                        } break;
                    case "8": //显示8个控件
                        {
                            方法与"2"相同
                        } break;
                    case "16":  //显示16个控件
                        {
                            方法与"2"相同
                        } break;
                    default:
                        {
                            this.tableLayoutPanel1.Controls.Clear();
                        } break;
                }
            }
            else
            {
                throw new Exception("大屏没有配置,请先配置大屏!");
            }
        }
        #endregion
    }
}
请大家看一看,委托相关真心不太会……
tableLayoutPanel1.Controls.Clear();用委托方式怎么写呢?

解决方案 »

  1.   


    delegate void SetTextCallback(string text);
            private void SetText(string text)
            {
                if (ustate1.lblNo.InvokeRequired)
                {
                    SetTextCallback d = new SetTextCallback(SetText);
                    this.Invoke(d, new object[] { text });
                }
                else
                {
                    ustate1.lblNo.Text = text;
                }
            }
    ustate1.lblNo.Text = i.ToString();
    改为
    SetText(i.ToString());
      

  2.   


         if (this.tableLayoutPanel1.InvokeRequired == true) 
                    {
                        tableLayoutPanel1。Invoke (new del(你委托的方法名))
                   }
      

  3.   

    最简单的方法是在LOAD()事件或者提示出错事件的前面加上System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls=fasle;
      

  4.   


    我委托的是GetConfig()方法……现在方法中的tableLayoutPanel1.Controls.Clear();函数出问题了……
      

  5.   


     if (this.tableLayoutPanel1.InvokeRequired == true) 
                    {
                        tableLayoutPanel1.Invoke(new del(你委托的方法名))
                      }刚上面那个打错了...
      

  6.   


    if (this.tableLayoutPanel1.InvokeRequired == true) 
                    {
                        tableLayoutPanel1.Invoke(new del(GetConfig))
                    }
                    else
                    {
                        this.tableLayoutPanel1.Controls.Clear();
                    }      private  void GetConfig()
            {   
               this.tableLayoutPanel1.Controls.Clear();        }
      

  7.   

    虽然
    tableLayoutPanel1.Controls.Clear();
    语句执行过去了,然而GetConfig()中要动态创建新控件,于是现在出现了:
    在某个线程上创建的控件不能成为在另一个线程上创建的控件的父级。
    的问题……
      

  8.   

    主线程创建了,但是当管理者要求改变现实的控件个数,就会给屏幕发送信息,需要重新创建一遍控件。所以会用到Clear()……
      

  9.   

    tableLayoutPanel1.Controls.Clear();的问题解决了,然而
    在某个线程上创建的控件不能成为在另一个线程上创建的控件的父级。
    的问题依然没解决:
    不是在创建ustate1的时候问题被Catch出来,而是在执行:
    this.tableLayoutPanel1.Controls.Add(ustate1, -1, -1);
    这句话时Catch出来了……
    为了让问题明白些,我把count == "2"的情况拿出来吧……
    if (dt.Rows.Count > 0)
    {
        /// 确定要显示的控件个数
        string count = dt.Rows[0]["COUNT"].ToString();
        if (this.tableLayoutPanel1.InvokeRequired == true)
        {
            this.tableLayoutPanel1.Invoke(new ScreenMessage(TLPClear));
        }
        else
        {
            this.tableLayoutPanel1.Controls.Clear();
        }
        switch (count)
        {
            case "2": //显示2个控件
                {
                    int rn = 1;//行数
                    int cn = 2;//列数
                    int i = 1; //控件号码
                    for (int row = 0; row < cn; row++)//行
                    {
                        for (int col = 0; col < rn; col++)//列
                        {
                            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
                            TPCSCommon.Controls.UCPointMachineNewStatistic ustate1 = new TPCSCommon.Controls.UCPointMachineNewStatistic();
                            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
                            this.tableLayoutPanel1.Controls.Add(ustate1, -1, -1); //这句话……
                            this.tableLayoutPanel1.SetColumnSpan(ustate1, 2);
                            this.tableLayoutPanel1.SetRowSpan(ustate1, 4);
                            ustate1.Dock = DockStyle.Fill;
                            ustate1.Margin = new System.Windows.Forms.Padding(0);
                            ustate1.lblNo.Text = i.ToString();
                            ustate1.PointMachineNo = ustate1.lblNo.Text; //点位端序号
                            ustate1.AutoStatistic(); //统计点位端包装信息                        ustate1.lblNo.Font = new Font("微软雅黑", 50F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
                            ustate1.lblType.Font = new Font("微软雅黑", 45F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
                            ustate1.lblUser.Font = new Font("微软雅黑", 45F, System.Drawing.GraphicsUnit.Point);
                            ustate1.lblPackingReal.Font = new Font("微软雅黑", 35F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
                            ustate1.lblPackingRealNum.Font = new Font("微软雅黑", 55F, System.Drawing.GraphicsUnit.Point);
                            ustate1.lblPackingEfficiency.Font = new Font("微软雅黑", 35F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
                            ustate1.lblPackingEfficiencyNum.Font = new Font("微软雅黑", 55F, System.Drawing.GraphicsUnit.Point);                        i++;
                        }
                    }
                } break;        default:
                {
                    this.tableLayoutPanel1.Invoke(new ScreenMessage(TLPClear));
                } break;
        }
    }
      

  10.   

    http://topic.csdn.net/u/20111101/10/6ebf484a-f987-4eb0-add4-7167c0b6bcab.html