NDepend

Improve your .NET code quality with NDepend

WPF / Winforms UI Refactoring: A Case Study

WPF Winforms UI Refactoring A Case Study

WPF and Winforms are still so massively used that Microsoft fully supports those technologies in .NET Core, .NET 5, 6 , 7 and so on. However WPF and Winforms are not multi-platforms and it is clear that they are not the future of .NET desktop UI. Microsoft will soon release MAUI RTM (currently in Release Candidate stage) but there are debates about its adoption and future.

Indeed .NET Developers should be careful in which technology to invest in since Microsoft has a long track-record of dead (or so) UI technologies (Silverlight, UWP, WinUI, WinRT, Metro… ). Also many .NET shops already migrated to the Avalonia or Uno platforms and are happy with it.

In this context, the only wise action to prepare the future is to segregate as much code as possible from your actual UI framework. Of course this is the number one general advice when it comes to UI code. But in practice all legacies have far too much code still entangled with WPF and Winforms framework to decouple. We – at NDepend – are no exception, and since the UI future is uncertain we are now in this process of taming our UI dependencies.

Our goal is to have all our logic implemented in .NET Standard 2.0. The new APIs in .NET 6, .NET 7 and so on are very exciting but as explained in the post 5x Lessons Learned from Migrating a Large Legacy to .NET 5/6 it is quite a desirable achievement to be runnable within .NET Fx, .NET 5/6/7 process and who knows, maybe in the browser with Blazor that has full .NET standard support. Moreover we will still have to support users developing with .NET Fx based tools (like Visual Studio 2022 and lower) for many years. This is why .NET Standard still really makes sense.

Case Study

WPF and Winforms UI logic can usually be split in two categories:

The NDepend code query result panel is quite a beast. Hopefully when developing it we segregated it into a Physical namespace (that handles the rows on screen, expanding, collapsing, virtual data grid view…) and a Logical namespace (the rows model inferred from the code query result). See the Logical namespace Solution Explorer view below:

Large-Winforms-Namespace

This Logical namespace is still consuming Winforms and GDI a bit and is a good candidate to be re-used in the future. Thus it needs some refactoring. To better understand the coupling let’s edit this C# LINQ code query:

Here is the result (drawn by the code query result code analyzed by the way):

Coupling-with-winform-GDI

We can see that several rows classes like RowItemIssue are still coupled with the Winforms / GDI framework to do some drawing stuff. Thus thanks to this query result we can now choose which classes to uncouple and which one will remain on the WPF/Winforms side (like CellDrawer or FormSuppressIssue).

To ease this refactor-decision-phase we can export the 68 matched classes to the dependency graph to see how they interact. Here the class RowItemIssue is selected. Blue cells represent classes directly used by RowItemIssue while light-blue cells are classes used indirectly by RowItemIssue.

Dependency-Graph-UI-coupling

We can now go to the source code and eliminate the unwanted dependencies. For that we will define some interfaces to abstract the drawing logic from the row model that we want to preserve. This is the SOLID principle Dependency Inversion Principle (DIP) in action.

Conclusion

Today it is hard to chose a modern .NET desktop UI technology with confidence. The future is still uncertain. This is why it makes sense to segregate code now to prepare for the future.

Refactoring a large legacy to reduce (or eliminate) the adherence to a framework is not an easy task. However this process can be simplified by using a tool like NDepend that can be an eye-opener in many situations.

My dad being an early programmer in the 70's, I have been fortunate to switch from playing with Lego, to program my own micro-games, when I was still a kid. Since then I never stop programming.

I graduated in Mathematics and Software engineering. After a decade of C++ programming and consultancy, I got interested in the brand new .NET platform in 2002. I had the chance to write the best-seller book (in French) on .NET and C#, published by O'Reilly and also did manage some academic and professional courses on the platform and C#.

Over my consulting years I built an expertise about the architecture, the evolution and the maintenance challenges of large & complex real-world applications. It seemed like the spaghetti & entangled monolithic legacy concerned every sufficiently large team. As a consequence, I got interested in static code analysis and started the project NDepend in 2004.

Nowadays NDepend is a full-fledged Independent Software Vendor (ISV). With more than 12.000 client companies, including many of the Fortune 500 ones, NDepend offers deeper insight and full control on their application to a wide range of professional users around the world.

I live with my wife and our twin kids Léna and Paul in the beautiful island of Mauritius in the Indian Ocean.