在另一个图像上移动图像

时间:2011-08-27 15:17:58

标签: c# winforms image move

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace d3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            pictureBox1.Image = Image.FromFile("C:\\Users\\ocean\\Desktop\\deneme.png");
            pictureBox1.Location = new Point(0, 0);
            pictureBox2.Image = Image.FromFile("C:\\Users\\ocean\\Desktop\\pul1.png");
        }

        protected override void OnMouseClick(MouseEventArgs e)
        {
            Graphics theGraphics = Graphics.FromHwnd(this.Handle);

            for (int i = 0; i < 200; i += 5)
            {
                pictureBox2.Location = new Point(i, 100);
                theGraphics.Flush();

                System.Threading.Thread.Sleep(50);
                pictureBox2.Invalidate();
            }           
        }
    }
}

在此代码中,picturebox2正在移动,但之前的位置图像保持打开直到循环结束。循环完成后,旧部件将被删除。我不希望循环中的先前绘画我只想在pictureBox1上移动。我是C#的新手,所以请帮助我:)在J2Me中我使用的是flushgraphics,但在这里我尝试了它并没有用,如果你能给出一个例子,我会很高兴。

1 个答案:

答案 0 :(得分:1)

在C#中,就像在Swing中一样,如果你在UI或事件线程上,在你完成之前,用户就会注意到你所改变的一切。

所以,如果你想移动它们,最好的办法是先从启动一个新线程开始,然后通过你的循环来启动UI线程。

但是,问题是您需要在UI线程上进行更改。

这就是为什么你的睡眠无法正常工作,你只是把事件线程置于睡眠状态,顺便说一句。

您使用的是哪个版本的C#?创建线程和使用UI线程有很多选择。

以下是创建线程的链接: http://msdn.microsoft.com/en-us/library/7a2f3ay4(v=vs.80).aspx

这是一种处理如何返回UI线程的方法:

http://blogs.msdn.com/b/csharpfaq/archive/2004/03/17/91685.aspx

例如,要创建一个线程,您可以执行此操作,该线程来自http://www.rvenables.com/2009/01/threading-tips-and-tricks/

我以这种方式做我的线程,因为我发现更容易看到发生了什么。

 (new Thread(() => {
        DoLongRunningWork();
        MessageBox.Show("Long Running Work Finished!");
    }) { Name = "Long Running Work Thread",
        Priority = ThreadPriority.BelowNormal }).Start();

关于如何在UI线程上进行更新的最完整答案将是这个问题:

How to update the GUI from another thread in C#?

<强>更新

对于它声明要进行长时间运行的部分,您可以在线程块之前添加它:

TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

然后你可以在你的线程中执行此操作:

(new Task(() =>
    {
        //copy pixel
        pictureBox2.Invalidate();  // You may want to just invalidate a small block                 around the pixel being changed, or every some number of changes.
    }))
.Start(uiScheduler);

通过进行这些更改,您可以简化您想要的更改,但其中一些可能比您想要的更复杂,这就是为什么我提供了一些其他链接来提供更多信息。但是,有关使用Task的更多信息,您可以查看这个优秀的博客:

http://reedcopsey.com/2010/03/18/parallelism-in-net-part-15-making-tasks-run-the-taskscheduler/