Changes to WriteableBitmap pixels don't update screen

I have a WriteableBitmap in a Windows Phone 8 application that is hooked up to an Image control. I'm looping through each row of the image and painting a row of pixels at a time asynchronously and then scheduling the next row for painting. However, it appears that changing the underlying pixel data does not fire a property changed so the control is not being updated. If I set the image source to a new WriteableBitmap created from the same pixels, the image updates fine but I'm doing a lot of excessive array copying.

void PaintImage(object state)
{
    // get my height, width, row, etc. from the state
    int[] bitmapData = new int[width];
    // load the data for the row into the bitmap

    Dispatcher.BeginInvoke(() =>
    {
        var bitmap = ImagePanel.Source as WriteableBitmap;
        Array.Copy(bitmapData, 0, bitmap.Pixels, row * width, bitmapData.Length);

        if (row < height - 1)
        {
            var newState = ... // create new state
            ThreadPool.QueueUserWorkItem(PaintImage, newState);
        }
    });
}

If I add these lines after the Array.Copy above, the bitmap progressively is drawn to screen (although in reality it is just replacing the bitmap every time):

var newBitmap = new WriteableBitmap(width, height);
Array.Copy(bitmap.Pixels, newBitmap.Pixels, newBitmap.Pixels.Length);
ImagePanel.Source = newBitmap;

It seems like I need to manually have the WriteableBitmap fire some property changed notification so that the Image that has it. I'm guessing this problem will go away if I bind the image to a WriteableBitmap in a ViewModel?


I think you should call Invalidate() to request for a redraw. Ref: http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.invalidate(v=vs.95).aspx


Just add a dirty rectangle

 _myBitmap.Lock();
 _myBitmap.AddDirtyRect(new Int32Rect(0, 0, _myBitmap.PixelWidth, _myBitmap.PixelHeight));
 _myBitmap.Unlock();

or if you are on a background thread

 Application.Current.Dispatcher.InvokeAsync(() =>
    {
        _myBitmap.Lock();
        _myBitmap.AddDirtyRect(new Int32Rect(0, 0, _myBitmap.PixelWidth, _myBitmap.PixelHeight));
        _myBitmap.Unlock();
    });
链接地址: http://www.djcxy.com/p/26882.html

上一篇: 操作WriteableBitmap像素

下一篇: 对WriteableBitmap像素的更改不会更新屏幕