0

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

为了实现这个目标,我使用 C# 和 Windows 窗体。我必须使用代理模式和 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());
    }

目前图片框只显示虚拟图像,因为后台工作人员已经加载了图像,但没有通知图片框使用它而不是虚拟图像。

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

4

0 回答 0