C#C
C#3y ago
8 replies
Cyclonit

❔ Refresh WriteableBitmap

Hi,
I would like to use a WriteableBitmap in my application. However, the Image control does not update when the backing WriteableBitmap changes. The examples I could find online appear to use WriteableBitmap.AddDirtyRect to trigger the update. But in my case this does not nothing.

My control looks like this:
<UserControl ... />
    <Image x:Name="bitmap"
           Source="{Binding Bitmap}"
           Opacity=".25">
    </Image>
</UserControl>


And the relevant code within the ViewModel:
public class BitGridViewModel : ObservableBase
{
    private static readonly Color trueColor = Color.FromArgb(0xAA, 0xFF, 0x00, 0x00);
    private static readonly Color falseColor = Color.FromArgb(0xAA, 0xFF, 0xFF, 0xFF);

    public WriteableBitmap Bitmap
    {
        get => _bitmap;
        set => SetProperty(ref _bitmap, value);
    }
    private WriteableBitmap _bitmap;

...

    // https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.writeablebitmap?view=windowsdesktop-7.0
    private static void DrawPixel(WriteableBitmap bitmap, int x, int y, Color color)
    {
        if (bitmap.Format != PixelFormats.Bgr32)
            throw new ArgumentException();

        try
        {
            bitmap.Lock();
 
            unsafe
            {
                // determine the pixel's address within the Bitmap, depends on the Bitmap's PixelFormat
                IntPtr pBackBufferAddr = bitmap.BackBuffer;
                IntPtr pixelAddr = pBackBufferAddr + y * bitmap.BackBufferStride + x * 4;
 
                // compute the pixel's color, depends on the Bitmap's PixelFormat
                int colorData = (color.R << 16) | (color.G << 8) | (color.B << 0);
 
                // set the pixel
                *((int*)pixelAddr) = colorData;
            }
 
            bitmap.AddDirtyRect(new Int32Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
        }
        finally
        {
            bitmap.Unlock();
        }
    }
}
Was this page helpful?