从menuitem更新WPF窗口图像,但在while循环中更新

时间:2013-07-18 16:08:13

标签: c# wpf menuitem writeablebitmap

好的,这是一个真正令人头疼的问题:

如果我选择一个导致图像的菜单项,构成整个窗口(writeableBitmap)以在其上绘制一些像素,它会这样做并正确显示。

但是,如果我为同一个方法添加一个while循环(假设有5个循环),则位图上的绘图不会显示,直到循环完成,然后正确显示第5个重绘位图。

那么,当选择了一个菜单项但是在while循环中被跳过时,窗口中是否会出现某种“自动刷新”?

更多细节。 这很好用(带来一个'干净'的图像,在它上面绘制一些东西,显示它):

// This brings in a 'clean' image
writeableBitmap = new WriteableBitmap(CleanVegMap);
image.Source = writeableBitmap;
// This makes a bunch of draws on the bitmap
DrawDinos2d();

然而,这会“消失”10秒,然后只显示最后一张(即第5张)图像:

int z = 0;
while (z < 5){
z++;
   // This brings in a 'clean' image
   writeableBitmap = new WriteableBitmap(CleanVegMap);
   image.Source = writeableBitmap;
   // This makes a bunch of draws on the bitmap
   DrawDinos2d();
}

新想法:有可能以某种方式将5'绘制的'writeableBitmaps缓存在内存中,不知何故是由系统?

尝试使用Dispatcher(如下所示):

                Dispatcher.Invoke((Action)delegate
            {               
                writeableBitmap = new WriteableBitmap(CleanVegMap);
                image.Source = writeableBitmap;
                DrawDinos2d();
            });

同样的事情(消失了10秒,然后只显示最后一张图像。

另一个线索:我只是在每个循环底部的循环中放置一个MessageBox,并且正如我在某种程度上所怀疑的那样,它正确地重新绘制了重绘屏幕。以某种方式:

 System.Windows.MessageBox.Show("Glarp!");

这个电话'唤醒了'系统。再一次,任何想法?

1 个答案:

答案 0 :(得分:1)

当您将MessageBox插入到处理过程中并获得您期望的结果时,发生了什么事情是UI线程有机会在MessageBox打开时被“捕获”。所以它创造了一种“错觉”,即使用MessageBox突然使其工作,但在幕后,它只是线程整理自己并清除其指令队列。

要以编程方式创建相同的效果,您可以使用这样的方法更新位图(ETA:需要.NET 4.5 Framework)...

    public void UpdateBitmap()
    {
        WriteableBitmap writeableBitmap = new WriteableBitmap
                                (100, 100, 96, 96, PixelFormats.Bgr32, null);
        writeableBitmap.Dispatcher.InvokeAsync(() =>
            {
                Console.WriteLine("work goes here");
            });
    }

这将在与位图的调度程序关联的线程上异步运行操作,并使UI有机会赶上。根据“DrawDinos2d”方法的有效负载, MIGHT 必须将处理迁移到后台线程,并逐个将其提供给UI线程。但首先从这种方法开始。

ETA:在.NET 4.0框架中,上面的对应部分看起来像这样......

    public void UpdateBitmap()
    {
        object[] objs = new object[] {null};
        WriteableBitmap writeableBitmap = new WriteableBitmap(
             100, 100, 96, 96, PixelFormats.Bgr32, null);
        writeableBitmap.Dispatcher.BeginInvoke((SendOrPostCallback)delegate
            {
                Console.WriteLine(@"work goes here");
            }, objs);
    }

文档读取“与创建System.Windows.Threading.Dispatcher的线程上的指定参数异步执行指定的委托。