Refactoring with MVVM is easy!

I’ve built up a kind of intellectual appreciation for some of the things MVVM gives you, but today I had a real “wow!” moment.

I’ve been working on a WPF UserControl, and it was getting kind of big and cumbersome. I wanted to extract some pieces from it into smaller UserControls to make it more manageable (and to make it easier to make some changes to the high-level layout).

So I created a new UserControl, moved my XAML into it, and referenced it from the original spot.

And that was it. I ran it, and it worked. That simple. No worries about moving dozens of code-behind methods onto the new control. No messing with method and field visibilities, and figuring out which objects the new control needed to have references to so it could do its work. No re-hooking event handlers.

Okay, it wasn’t quite cut-and-paste — there was some fixup to be done. The new UserControl needed some xmlns: attributes added. And I wanted the attached layout properties (Grid.Row, Grid.Column) to stay in the original file, not move into the new one (they’re part of the parent layout, not intrinsic to the child UI). So it took maybe a minute or so.

But it was nothing like the splitting headache that is extracting a UserControl in WinForms.

And then I extracted another UserControl. And I ran. And it just worked.

Wow.

Just, wow.

But the downside is, now I’ve got this overwhelming temptation to rewrite our million-line codebase in WPF…

Comments on the survey #2: Refactorings

The survey had little room for comments, so here are mine, starting with refactorings.

Delphi’s refactorings are crap. They leave you with non-compilable code more often than not.

A few examples of brokenness off the top of my head:

  • Class Completion got broken in CDS 2007. It usually completes stuff into the wrong class.
  • Class Completion mangles your visibilities if you ever try to use strict private or strict protected.
  • Delphi’s refactorings still don’t work across units if you don’t have every single unit explicitly added to your project file, so a Rename will usually break the build.

And that’s just the brokenness, not the suckiness. Extract Method still won’t do functions, but that’s just an annoyance. Automatic variable declarations usually get the wrong type, but that doesn’t break code that already compiled. What’s utterly unacceptable is that there are cases where the “refactorings” actually make previously-working code stop compiling.

Pretty much our entire team just ignores Delphi’s refactorings, because we know they’ll usually break our code. Please, please, please, put some effort toward making the refactorings work. In this day and age, we should not have to refactor by hand.