The English Patient
The English Patient

Reputation: 21

Appropriate handling of WPF Canvas (Scaling) in MVVM

A question for the pattern experts: I am refactoring an application that analyses (heavy maths!) and draws a lot of diverse, resulting geometry on a canvas (window).

Currently the actual drawing is done by a helper class triggered by the ChangeSize event of the container control of the Canvas. Zoom/Pan are handled by a similar construct using the various mouse events.

Here is the question: In my understanding, MVVM declares event handling as evil und wants commands handled in the view model - I can do this but the crux is that to properly position the geometry, which the view model gets from the model in world coordinates, the view model would need to know the size of the view canvas and that's evil as well. So, where (and how) do you do the plotting, particularly the scaling from world coordinates to screen(canvas). I have looked at value converters, item templates etc. - but that would mean writing a forest of extra intermediate code or a XAML jungle ...

All the examples I can find are somewhat simplistic (just a few buttons or pics and labels), but how does one do proper accurate geometry drawing in MVVM?

Upvotes: 1

Views: 482

Answers (1)

Mike Eason
Mike Eason

Reputation: 9723

In my opinion, pure MVVM is not suited to your scenario. When I say pure, I mean using bindings to model properties.

In order to implement the pattern, you'd have to use Binding to bind geometry values to the Canvas, and assuming that you have a lot of shapes which need to be rendered on the Canvas then Binding will simply result in a loss of performance.

Remember, Binding relies on reflection, in the scenario where you have lots of geometry to draw (and therefore lots of binding to do), this will slow down the UI considerably therefore it's faster to simply draw the geometry using the view's code-behind.

UI is UI, Data is Data. My suggestion would be to let your view model do the maths, and once it's done, asynchronously plot the data on the Canvas from the views code-behind.

MVVM isn't about having no code-behind, it's about keeping code where it belongs. In your situation, there is absolutely nothing wrong with subscribing to a view model event from your view. But if you really want to reduce dependencies, you can use messaging services.

Upvotes: 2

Related Questions