public class TankClient : Form
    {
        int xPos = 30;
        int yPos = 30;
        public static void Main()
        {
            TankClient tc = new TankClient();
            tc.LaunchForm();
        }
        protected void LaunchForm()
        {
            this.Size = new Size(800, 600);
            Thread t = new Thread(new ThreadStart(Run));
            t.Start();
            this.ShowDialog();
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            SolidBrush sb=new SolidBrush(Color.Red);
            g.FillEllipse(sb,xPos, yPos,50,50);
        }
        private void Run()
        {
            while (true)
            {
                yPos += 5;
                Thread.Sleep(50);
                //怎么重画?
            }
        }
    }我想复习一下C#,现在想实现的是:在窗体上画个圆,每隔一段时间改变这个圆的位置.

解决方案 »

  1.   

    //怎么重画?
                
    加这个 Refresh(); 
      

  2.   

    就是出错啊:线程间操作无效: 从不是创建控件“”的线程访问它。唉,平时我都是直接建WindowsApplication然后拖控件,现在想自己写,发现什么都不会。
      

  3.   

           public delegate void dTest();
            void invokeThread()
            {
                System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                sw.Reset();
                sw.Start();
                if (this.InvokeRequired)
                {
                    this.Invoke(new dTest(CreateTreeView));
                }
                else
                {
                    CreateTreeView();//方法名
                }
                sw.Stop();
            }
      

  4.   

    public partial class Form1 : Form
        {
            int xPos = 30;
            int yPos = 30;        //线程定义
            Thread t = null;        public Form1()
            {
                InitializeComponent();
            }        protected override void OnPaint(PaintEventArgs e)
            {
                Graphics g = e.Graphics;
                SolidBrush sb = new SolidBrush(Color.Red);
                g.FillEllipse(sb, xPos, yPos, 50, 50);
            }        private void Run()
            {
                while (true)
                {
                    yPos += 5;
                    Thread.Sleep(50);
                    //怎么重画?
                    this.Refresh();
                }
            }        //重绘代理
            private delegate void RefreshDele();
            //重载一下重绘方法
            public override void Refresh()
            {
                if (!this.IsDisposed && this.InvokeRequired)
                {                this.Invoke(new RefreshDele(Refresh));
                }
                else
                {
                    base.Refresh();
                }
            }        private void Form1_Load(object sender, EventArgs e)
            {
                //启动线程
                this.Size = new Size(800, 600);
                t = new Thread(new ThreadStart(Run));
                t.Start();
            }        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                //关闭线程
                if (t.ThreadState != ThreadState.Stopped)
                {
                    t.Abort();
                }
            }    }
      

  5.   

    Control.CheckForIllegalCrossThreadCalls = false;
      

  6.   

    通用的 delegate 调用, 来自 Programming .NET Components 一书    static void InvokeDelegate(Delegate del, object[] args)
        {
          ISynchronizeInvoke synchronizer = del.Target as ISynchronizeInvoke;
          if (synchronizer != null)//Requires thread affinity
          {
            if (synchronizer.InvokeRequired)
            {
              synchronizer.Invoke(del, args);
              return;
            }
          }
          //Not requiring thread afinity or invoke is not required
          del.DynamicInvoke(args);
        }
      

  7.   

    其实道理很简单,你也知道这个是跨线程调用控件的,WinForm里的控件只可以由创建这个控件的线程去使用,我们所看到的窗体界面是由一个窗体线程管理的,若要操作它的控件就要把要做到是委托给它,让它去做这件事,这就需要使用到代理,窗体线程拿到这个代理方法后就可以去执行了,这就有了下面一段代码:        //重绘代理
            private delegate void RefreshDele();
            //重载一下重绘方法
            public override void Refresh()
            {
                if (!this.IsDisposed && this.InvokeRequired)
                {
                    //调用反射方法
                    this.Invoke(new RefreshDele(Refresh));
                }
                else
                {
                    base.Refresh();
                }
            }
    PS:这么做的道理也很好理解,举个例子讲:假设你是研发部的小喽罗,如果市场部经理看你不爽,他不能直接训你,他要把情况反映到你们研发部经理那,让你们研发部的经理训你,^_^