Dec 12, 2011 at 10:44 AM
Edited Dec 12, 2011 at 11:22 AM
So I spent some time this weekend updating the WPF version. I have not completed it, am doing testing.
What I have done is I checked out the latest source from codeplex and in-place (in the Silverlight files) I have made them dual-configured for WPF and Silverlight. I realised that you used to have the WPF version in its own branch. I believe the reason
for this was because the code was hard to read and maintain with all the Preprocessor statements mixed in the methods, hence you did not want to pollute the trunk with preprocessor directives.
I have made the SL code compatible with WPF in trunk as I want to keep up to date with new features in the SL version and not do all this work again when new features are released. I believe I have come up with a viable solution to keep the code readable
and maintainable throughout (reduction of preprocessor statements in code). I hope that is ok.
In order to reduce the number of hacks (#if SILVERLIGHT etc...) I created a helper class and moved all hacking to there. You will see when you get the source code. I created a class called BitmapContext which implements IDisposable and exposes the Pixels
property for the bitmap, either of type int for Silverlight or int * for WPF (conditional compilation). the result is quite unified code throughout the extensions with minimal preprocessor hacks. You can call this and it works in both WPF and SL. BitmapContext
also contains SL and WPF specific implementations of Copy (using memcpy for WPF and Buffer.BlockCopy for SL) and Clear.
The WBEx extension methods use BitmapContext instead of calling directly writeableBitmap.Pixels, Lock and Unlock as follows:
// calls an extension method to return a type BitmapContext
// which implements IDisposable.
// Internally BitmapContext
// has many #if SILVERLIGHT hacks to keep the rest of
// the code as clean as possible.
// When the BitmapContext is constructed if WPF it Locks
// the bitmap
// When the BitmapContext
// is disposed if WPF it unlocks the bitmap and invalidates
using (var context = bmp.GetBitmapContext())
// Example usage. The Pixels property exposes int for SL and int* for WPF
var pixels = context.Pixels;
pixels[i] = newValue;
Also, new bitmaps can be created using a BitmapFactory class
// Replacement for new WriteableBitmap(x, y) as SL and WPF
// have different constructors for this class
var newBitmap = BitmapFactory.New(pixelWidth, pixelHeight);
The result is unified code with minimal preprocessor hacks in the extension methods themselves. The preprocessor directives have been moved to the BitmapContext and BitmapFactory classes, resulting in cleaner code but cross-platform compatibility.
I am in the process of testing this. So far it compiles across WPF/SL and all Silverlight examples run fine with no discernable drop in performance. I am creating WPF examples to mirror the SL and when I get these working I will send the files. I have not
tested against Windows Phone.
Are you interested in this implementation? I can zip up and put on my website if you want, or email to you direct. For your records, the project I am working on with WBEx is described on my
This is why I am interested in keeping WBEx up to date as it is an excellent and powerful library! I also have some extensions I wish to add such as a BlitQuad method which I am working on to allow gradient filled polygons to be drawn using a combination
of Blit and DrawQuad. I am also interested in chaining operations so you only get one bmp.Lock / bmp.Unlock operation for multiple calls. I can do this via the BitmapContext ctor/dispose method.