【问题标题】:moving an image on another image在另一个图像上移动一个图像
【发布时间】:2011-08-27 15:17:57
【问题描述】:
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 移动正常,但之前的位置图像保持 ON THE 直到循环结束。当循环完成时,旧部分将被删除。我不希望循环内的以前的画我只想在pictureBox1 上移动。我是 C# 新手,所以请帮助我:) 在 J2Me 中,我使用的是flushgraphics,但在这里我尝试过,但没有成功,如果你能举个例子,我会很高兴。

【问题讨论】:

  • 不要在带有 thread.sleep 的 for 循环中执行此操作,而是使用每 50 ms 将图像移动 5 个像素然后停止的计时器执行此操作。这将允许更改正确地绘制到屏幕上
  • 此代码不允许窗体的 PaintBackground 方法运行,需要替换像素。像这样的循环从来都不是问题,如果消息循环不运行,东西就会停止正常工作。改用定时器,this.Update() 是创可贴。

标签: c# winforms image move


【解决方案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/

【讨论】:

  • visual c#2010 express edition你能写一个示例代码吗,因为在j2me中我写了一个接口的runnable方法。在它里面有一个循环while(true),最后有一个线程,每个动作我都写了flushGraphics,它工作得很好但是在c#中我试过flushgraphics它不工作我是c#的新手,所以如果你可以写一个例子代码将不胜感激。顺便提一下
猜你喜欢
  • 1970-01-01
  • 2016-03-12
  • 1970-01-01
  • 1970-01-01
  • 2016-04-11
  • 1970-01-01
  • 1970-01-01
  • 2019-07-12
相关资源
最近更新 更多