在图片框中显示随机图片C#

时间:2016-01-21 13:11:49

标签: c# winforms

我有6张图片名为image_1,image_2 ...现在我想在图片框中以随机顺序显示这些图片,所以我创建了这段代码:

for (int i = 0; i < 10; i++)
{
    diceBox.ImageLocation = "images/dice_" + rn.Next(1,6).ToString() + ".png";
    diceBox.Update();
    Task.Delay(1000);
}

但这不起作用。它只显示其中一张图片。我觉得它正在跳过&#34; Task.Delay(1000)&#34;,我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

代码问题不是Task.Delay(1000);。这基本上立即创建了一个任务,其结果从未被查看过,但调用它的代码会立即继续前进。它没有等待任务完成。它在这段代码中实际上是一个无操作。

问题在于,即使使用diceBox.Update(),用户界面也无法实际重绘控件。 for循环阻止UI进行任何重绘。因此,在for循环中选择的最终图像是唯一显示的图像,因为它仅在UI可以更新的循环之后。

诀窍是使用某种计时器来更新控制。我最喜欢的选择是使用微软的Reactive Extensions(NuGet&#34; Rx-WinForms&#34;)。这是代码的样子:

Observable
    .Interval(TimeSpan.FromSeconds(1.0))
    .Take(10)
    .ObserveOn(diceBox)
    .Subscribe(fn =>
    {
        diceBox.ImageLocation = String.Format("images/dice_{0}.png", rn.Next(1, 7));
        diceBox.Update();
    });

更标准的计时器方法是:

var i = 0;
var timer = new System.Windows.Forms.Timer();
EventHandler handler = null;
handler = (s2, e2) =>
{
    diceBox.ImageLocation = String.Format("images/dice_{0}.png", rn.Next(1, 7));
    diceBox.Update();
    if (++i >= 10)
    {
        timer.Enabled = false;
        timer.Tick -= handler;
        timer.Dispose();
    }
};
timer.Tick += handler;
timer.Interval = 1000;
timer.Enabled = true;

我喜欢Reactive Extensions方法 - 它从上到下读得很好。标准计时器方法遍布整个地方,但可能更熟悉。

我测试了这两种方法,它们似乎工作正常。