后台工作完成后如何强制c#图片框更新其图像

时间:2015-11-14 10:30:10

标签: c# asynchronous backgroundworker image-loading proxy-pattern

我的主要目标是从服务器加载图像,当加载过程正在运行时,我想显示占位符而不是真实图像。

为了达到这个目标,我使用的是C#和Windows Forms。我必须使用代理模式和C#后台工作程序,这意味着加载和视图使用不同的线程。

我知道已经有使用代理模式进行图像加载的示例,但我没有找到任何使用后台工作程序从服务器加载图像的解决方案。

我已经实现了核心功能,但我现在仍然坚持这样一个问题:当图像完全加载并且因此后台工作人员完成了他的工作时,如何强制我的图片框加载真实图像。

我的设计如下:

public class MyPictureBox : PictureBox
{
    AbstractImage myImage;

    public MyPictureBox(AbstractImage image) : base()
    {
        this.myImage = image;
    }
}

public abstract class AbstractImage
{
    protected readonly String url;

    public AbstractImage(String url)
    {
        this.url = url;
    }

    public abstract Image getImage();
}

public class RealImage : AbstractImage
{
    private Image img;

    public RealImage(String url) : base(url)
    {

    }

    public override Image getImage()
    {
        if (img == null)
        {
            WebRequest requestPic = WebRequest.Create(url);
            WebResponse responsePic = requestPic.GetResponse();
            img = Image.FromStream(responsePic.GetResponseStream());
        }
        return img;
    }
}

public class ProxyImage : AbstractImage
{
    private readonly Image Dummy = Image.FromFile("Waiting.jpg");
    private readonly RealImage realImage;
    public readonly BackgroundWorker bgw;
    private bool done = false;

    public ProxyImage(String url) : base(url)
    {
        realImage = new RealImage(url);
        bgw = new BackgroundWorker();
        bgw.WorkerReportsProgress = true;
        bgw.DoWork += new DoWorkEventHandler(loadImage);
        bgw.RunWorkerAsync();
    }

    public void loadImage(object sender, DoWorkEventArgs e)
    {
        Console.WriteLine("Loading file" + url);
        realImage.getImage();
        Console.WriteLine("Finished loading file " + url);
        done = true;
        bgw.ReportProgress(100);
    }

    public override Image getImage()
    {
        return done ? realImage.getImage() : Dummy;
    }
}

public partial class Form1 : Form
{
    private String urlPrefix = "http://...";
    String[] filenames = { "Penguins.jpg", "Koala.jpg", "Desert.jpg"};

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void Form1_Shown(object sender, EventArgs e)
    {
        ProxyImage image = new ProxyImage(urlPrefix + filenames[0]);
        MyPictureBox pb = new MyPictureBox(image);
        pb.Image = image.getImage();
        pb.SizeMode = PictureBoxSizeMode.Zoom;
        pb.Size = new Size(200, 200);
        pb.Location = new Point(0, 0);
        Controls.Add(pb);
    }
}

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

目前图片框仅显示虚拟图像,因为后台工作人员已加载图像但未通知图片框使用此图像而不是虚拟图像。

如果有人能告诉我如何将真实图像设置为图片框的图像,我会很高兴。

0 个答案:

没有答案