posted on
Thursday, May 15, 2008 1:12 AM |
Filed Under [
WPF
]
In a previous post, I showed how you can directly bind a Binary LINQ type to a WPF Image control implementing an ad-hoc type converter, not so much useful unless you don't have your images already stored on your database. What we need is something that is capable to achieve a two way binding, both displaying images and allowing users to upload their own; what about a brand new, completely skinnable, WPF custom control? So, let's create a new WPF project and add a new CustomControl called ImageUploader and take care of its logic first. As I wrote elsewhere, it's a good practice to design control's behavior (and implement it) without references to any UI element.
First of all, we need a property where to store an ImageSource object; we want it to be two-way bindable, so we are going to build a dependency property instead of a plain CLR one with appropriate FrameworkPropertyMetadataOptions:
Next, we need a couple of commands:
- a Clear command (we want the user being able to remove the current image)
- a Browse command to upload a new picture
If you've read some posts of mine, lately, you should perfectly know how to create custom commands and bind them to handlers 
The ClearImageCommand handler is pretty straightforward:
Same for the BrowseCommand handler, although it deserves one little note: we could obviously use the BitmapImage constructor with a URI as argument to directly reference the file; however this approach leaves the file locked for the whole BitampImage lifetime (which unfortunately ends only when GC wants to). Therefore what we do is manually handling its loading, setting the CacheOption property to load the entire image data during its init stage and caching it in a MemoryStream:
Now that our control's logic is completely defined (and, again, without references to any UI element), we can move to creating a default layout on the generic.xaml file; a very simple one could be the following
that is not so bad if we add a bit of animation...
Anyway, doing something fancier is only a matter of Blend skills (and mine are awful).
One last note: the BinaryToImageConverter I showed you here is still one-way only. To get it work in both directions, we must implement the ConvertBack method:
Here's the complete source code, obviously released under the "Works on my machine" license 
Enjoy!
