Here at Chersoft we're all very excited about the possibilities offered by WPF.
As interest grows, we're getting more and more requests for help getting ENCX into WPF applications, so we've decided to put together a sample application that uses WPF to overlay things on an ENCX chart.
We were pleasantly surprised at how painless this was, and hopefully you will be too.
The sample is included with the ENCX installer download.
If you're anything like me, the first thing you'll want to do is run it up and see what happens, so start the S57Example app.
All being well, you are now looking at a chart of the River Humber, England. Along the bottom of the window, we have some labels that are databound to properties of the chart drawing control. In the top right we have a North arrow which you should be able to drag to rotate the chart, and finally we have a few simple WPF shapes overlaid onto the display.
The Encx.Wpf project contains the control (Encx.Wpf.S57Control) that we use to wrap some ENCX S57 chart drawing functionality in a WPF-friendly way.
Various properties are provided to allow databinding but we had no appetite to wrap up every method of the ENCX S57Draw object, so some operations require you to manipulate that directly — the S57Draw property gives you access to this. After you do anything with the S57Draw object you must call UpdateBitmap() in order to ask ENCX to redraw the chart. Every time the chart is redrawn, the control fires the OnBitmapUpdated event — this helps you know when to update the position of any overlaid visuals.
Moving on to the S57Example project and MainWindow.xaml, we can start to see how the sample app fits together — we simply declare an S57Control along with a Canvas upon which we draw our overlaid shapes.
Our NorthArrow control is placed at the top right of the window. (I won't go into any detail on the NorthArrow, as it's incidental to getting ENCX to work with WPF, but the code is there if you want to take a look.)
We also have a few TextBlocks bound to properties of the S57Control.
With the XAML already written, we only need a few lines of actual code to get our first chart displayed. The bare minimum is to create an ENCX.Library and an ENCX.S57Manager, then set the appropriate properties on the S57Control.
After that, we just need to set the display scale of the control and tell it the geo-position we'd like to look at (via S57Control.UpdatePosition()). This is enough to display a chart which can be drag-scrolled and zoomed with the mousewheel.
Our example app does a little bit more than that:
Conversion from geographical space into pixel space and detecting when a geographical point is out of view is efficiently done by the GeoPix object, accessed via S57Control.S57Draw.GeoPix.
The great thing about overlaying shapes in this way is that the shapes are proper WPF objects that can efficiently leverage visual effects, styling, hit testing, event bubbling and all the other things that make WPF desirable — we demonstrate this by setting a Style, ToolTip and MouseDown event handler for each shape. Clicking a shape should centre it in the view, and all the shapes have a common base style which adds a drop shadow (I understand better-looking effects are available!)
You can set the DisplayScale property when you declare the S57Control in XAML; the same is not currently possible for GeographicCenter. The missing link is an IValueConverter that provides a conversion between a string representation of a latitude/longitude and GeoPoint. It's also quite possible for the GeographicCenter property to be made animatable to allow you to 'fly' from place to place…
Have fun with ENCX and WPF!