Catel: an MVVM platform for WPF with automatic model mapping
An application development platform
At a glance
- What is it?
- Catel is a C# application development platform whose centre of gravity is MVVM for WPF, built around attribute-driven mapping between model and view model plus a set of platform services. The catch is scope: it targets desktop Windows, it expects Visual Studio 2022 to build, and it does not have the reach of a general-purpose .NET foundation library.
- Who is it for?
- Catel fits a Windows desktop team writing WPF applications that want model to view model mapping, automatic validation and the service abstractions handled by the framework rather than by hand. It does not fit a team building for the web, on Linux, or on a stack that already has an MVVM layer it does not want to replace.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two packages, and only one of them is about your UI
Catel ships as a set of libraries, and the split matters for how you reference it. Catel.Core is the package described as the one to include in all your projects, whether or not the project has a UI, and it holds the general purpose pieces: argument validation, caching, data types such as ModelBase, PropertyBag and validation, messaging, a reflection API described as the same for every supported platform, and weak references through WeakEventListener. Catel.MVVM is the one you add when you are writing a WPF user interface and want the MVVM pattern. The split means a service layer or a console tool can take the core dependency without dragging in the WPF stack. It also explains the argument validation example the project gives, where a null check reads as Argument.IsNotNull(() => myArgument) rather than a hand-written guard clause in every constructor.
Mapping a model to a view model with two attributes
The mechanism that removes the most boilerplate is the pair of mapping attributes on the view model. The project describes a view model with automatic injection of the DataContext and automatic mapping of properties and validation from model to view model, and the example shows how that is expressed. A private property marked with the Model attribute holds the model instance, and public properties marked with ViewModelToModel are populated from it:
public class PersonViewModel : ViewModelBase
{
public PersonViewModel(Person person)
{
Argument.IsNotNull(() => person);
Person = person;
}
[Model]
private Person Person { get; set; }
[ViewModelToModel]
public string FirstName { get; set; }
[ViewModelToModel]
public string LastName { get; set; }
}The constructor takes the model as a parameter and guards it with the core argument validation call, then assigns it to the private Model property. Everything a view binds to is public and decorated, and the view model does not repeat the validation logic that lives on the model.
Validation is a method you override, not a base class you configure
Validation on the model side follows the same explicit style. The example model derives from ValidatableModelBase, inherits automatic change notifications, and overrides ValidateFields to add results to a list of field validation results. Each entry is created with FieldValidationResult.CreateError, passing the property name and the message text, so the message and the offending field are produced at the point of the failure rather than through a separate attributes file:
public class Person : ValidatableModelBase
{
public string FirstName { get; set; }
public string LastName { get; set; }
protected override void ValidateFields(List<IFieldValidationResult> validationResults)
{
if (string.IsNullOrWhitespace(FirstName))
{
validationResults.Add(FieldValidationResult.CreateError(nameof(FirstName), "First name is required"));
}
if (string.IsNullOrWhitespace(LastName))
{
validationResults.Add(FieldValidationResult.CreateError(nameof(LastName), "Last name is required"));
}
}
}The nameof operator supplies the field name, so renaming a property does not break the message that points at it. The results accumulate in the list the framework hands in, which is how the error reaches the view without the model knowing anything about views.
Services cover the calls a view model should not make itself
Catel.MVVM carries a set of services that exist so view models do not have to talk to the platform directly. The list includes MessageService, NavigationService, OpenFileService, BusyIndicatorService, SaveFileService and UIVisualizerService. Alongside them the package provides commands, among them Command and TaskCommand, a large set of converters, collections including FastObservableCollection, auditing, and view components such as DataWindow, UserControl and Window. View models get automatic validation and automatic mappings as well. The practical effect is that the plumbing of a desktop application, file dialogs, navigation and busy state, is provided as replaceable abstractions instead of being written per project. Whether that is a win depends on how much of your application is desktop specific, which is worth thinking about before you commit to the platform.
The nested user control problem is the reason the library exists
The stated motivation for Catel.MVVM is a specific structural problem with WPF, not a general preference for MVVM. Catel provides context-aware view and view-model creation, and the project points at that as the way to solve what it calls the nested user controls problem. The WPF DataContext inherits down the visual tree, so a user control that needs its own model ends up either capturing a parent's context or fighting it, and the usual workarounds involve bolted-on interfaces or manual binding plumbing. Generating a view and its view model together, with the context supplied at the point of creation, addresses that directly. This is also the sharpest difference from writing MVVM by hand: a hand-rolled implementation has to solve the same inheritance problem, usually with a naming convention for the context property or by keeping views stateless and injecting everything.
Building it means Visual Studio 2022 and a cake script
This is where the friction sits. The project states that Catel requires Visual Studio 2022 to compile successfully, along with a set of installed features, and it points at the .vsconfig file in the src root, which should report missing components when the solution is opened. The build itself runs through a script rather than through Visual Studio alone, and the commands are meant to be run with powershell from the root of the repository:
.\build.ps1 -target buildRunning the build with the unit tests included takes a different target:
.\build.ps1 -target buildandtestA third target produces local packages, and the project notes that this assumes a local packages directory at C:\Source\_packages which can be added to the NuGet feeds. The root of the repository also holds a Cake build file, a cake.config and a separate build-docs.ps1 script, so the build logic is split between PowerShell and Cake, and the .vsconfig file is the piece that tells Visual Studio which components are missing before you start.
Translating a .xlf file is the documented contribution path
Localisation is part of the repository rather than a separate effort, and the process is specified precisely enough to follow. Adding translations requires the Multilingual App Toolkit, and the MAT Editor is the tool used to do it. The workflow opens a specific language, or creates it, in the MultilingualResources folder, with the example given being a Dutch resource file for the Catel.MVVM project under src. You then edit the xlf file and open a pull request containing only that file. The restriction to a single file per request keeps translation changes from colliding with code changes in review. The repository root also shows the usual supporting files, including the AUTHORS and CONTRIBUTORS files, design and data directories, build scripts in both PowerShell and cake form, and a GitVersion configuration, which together indicate that versioning is driven by a tool rather than by hand-edited tags.
A 7.0.0 release after a long gap in the tag history
The release picture is uneven, and that matters if you are planning a dependency. The most recent release is 7.0.0, dated 2026-08-21, and the two before it are 6.0.7 and 6.0.6, both dated 2025-02-26 within about half an hour of each other. So there is a large gap between the 6.0.x line and 7.0.0, and a major version jump suggests breaking changes rather than a smooth upgrade path. The last push was on 2026-10-18, so work continues after the release rather than stopping at it. The licence situation needs attention before you build on it: the licence field on the repository is a custom licence that GitHub cannot classify, and the terms live in the LICENSE file, so read that file yourself rather than assuming a permissive grant. The project is also funded through Open Collective, and a set of more than sixty free open source WPF components built on Catel is maintained by a company called WildGums and provided to the community, which is where the real usage evidence sits.
Editorial conclusion
Catel fits a Windows desktop team writing WPF applications that want model to view model mapping, automatic validation and the service abstractions handled by the framework rather than by hand. It does not fit a team building for the web, on Linux, or on a stack that already has an MVVM layer it does not want to replace. Before adopting it, check that your target framework sits inside the WPF support the project describes, confirm your Visual Studio 2022 installation has the components the .vsconfig file expects, and read the LICENSE file, since the licence field on the repository is a custom one that GitHub cannot classify.
Frequently asked questions
What is the difference between Catel.Core and Catel.MVVM?
Catel.Core is the general purpose library meant for every project, holding argument validation, caching, data types, messaging, reflection and weak references. Catel.MVVM is the one to reference when you are building a WPF user interface and want the MVVM pattern, adding services, commands, converters and the view and view model components.
How does Catel map a model to a view model?
The view model holds its model in a property marked with the Model attribute, and the public properties that should be filled from it are marked with ViewModelToModel. The mapping, and the DataContext injection, then happen automatically.
What do I need to build Catel from source?
The project requires Visual Studio 2022 with the listed features installed, and the .vsconfig file in the src root reports missing components when the solution is opened. Builds run through build.ps1 with powershell from the root of the repository, and the Cake and PowerShell build scripts are both in the repository root.
How do I add a translation to Catel?
Install the Multilingual App Toolkit and its MAT Editor, open or create the language file in the MultilingualResources folder, such as the Catel.MVVM.nl.xlf file under src, edit the xlf file, and open a pull request containing only that file.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/catel-catel)Was this useful?