This guide describes how to update your code to be fully compatible with Catel 4.0.0.
Some classes in Catel have been renamed.
Some namespaces in Catel have been changed to match the functionality. For example, all services are now in Catel.Service instead of Catel.MVVM.Services because they can be used without MVVM.
Below is a list of changed namespaces:
Catel.Windows.Data.Converters => Catel.MVVM.Converters
Catel.Windows.Controls.MVVMProviders.Logic => Catel.MVVM.Providers
Some interfaces were moved (but not all classes in the namespace):
Catel.Windows => Catel.MVVM.Views
The ModelBase class exposed a lot of properties for validation such as HasErrors, HasFieldErrors, HasBusinessRuleErrors, etc. These all these properties are now explicitly implemented into interfaces to make models using ModelBase cleaner to use for end-developers. Below is a list of properties that are now implemented as explicit interface implementations:
Member name | Explicit interface implementation | Member type |
---|---|---|
BusinessRuleErrorCount | IModelValidation.BusinessRuleErrorCount | property |
BusinessRuleWarningCount | IModelValidation.BusinessRuleWarningCount | property |
Deserialized | IModelSerialization.Deserialized | event |
ErrorsChanged | INotifyDataErrorInfo.ErrorsChanged | event |
FieldErrorCount | IModelValidation.FieldErrorCount | property |
FieldWarningCount | IModelValidation.FieldWarningCount | property |
HasErrors | INotifyDataErrorInfo.HasErrors | property |
HasWarnings | INotifyDataWarningInfo.HasWarnings | property |
ValidationContext | IModelValidation.ValidationContext | property |
Validator | IModelValidation.Validator | property |
WarningsChanged | INotifyDataWarningInfo.WarningsChanged | event |
The LoadTabItemsBehavior has been refactored with new names. The old names will be removed in v5, but will error in v4. Below are the renames:
To support Xamarin, the IView interface has been extended with new members. Make sure to implement the new members.
When not using the ViewToViewModel attributes, it is not required to subscribe to all dependency properties in the UserControlLogic. Starting from Catel 4.0, Catel uses the FastViewPropertySelector by default which subscribes to no properties by default. This is a breaking change for users using the ViewToViewModel attribute.
To get back the behavior, there are 2 ways:
It is best to let Catel only subscribe to the properties that it should (for the best performance). To do so, use the IViewPropertySelector.AddPropertyToSubscribe method to add properties:
var serviceLocator = ServiceLocator.Default; var viewPropertySelector = serviceLocator.ResolveType<IViewPropertySelector>(); viewPropertySelector.AddPropertyToSubscribe("MyProperty", typeof(MyView)); |
In most cases, the only reason to subscribe to property changes is because of the ViewToViewModel attribute. If that is the case, it is best to use the extension method AutoDetectViewPropertiesToSubscribe in the static constructor of the view:
static MyView() { typeof(MyView).AutoDetectViewPropertiesToSubscribe(); } |
The default implementation of the ViewPropertySelector subscribes to all properties by default. By registering it in the ServiceLocator will ensure Catel subscribes to all dependency properties:
var serviceLocator = ServiceLocator.Default; serviceLocator.RegisterType<IViewPropertySelector, ViewPropertySelector>(); |
The IViewModel interface now returns tasks instead of direct values to support async/await.
public override void Initialize() { base.Initialize(); } |
Must be changed in:
public override async Task Initialize() { await base.Initialize(); } |
public override bool Save() { return base.Save(); } |
Must be changed in:
public override async Task<bool?> Save() { return await base.Save(); } |
public override void Close() { base.Close(); } |
Must be changed in:
public override async Task Close() { await base.Close(); } |
The use of await or Task.ContinueWith to await the result is now necessary or use the code below:
if (await messageService.ShowInfo("message", other parameters...) == MessageBoxResult.Yes) { // Handle yes here } |
The use of await or Task.ContinueWith to await the result is now necessary or use the code below:
await uiVisualizerService.ShowDialog<MyViewModel>(); // Window is closed here thanks to the await keyword |
Catel 4.0 introduces a much simpler way to use Catel on 3rd party controls. This means that the following changes have been applied and might be breaking:
The IServiceLocator.Remove[x] methods are removed. Use the RemoveType methods instead.
The composite command will always allow execution, even when commands don't allow it. Therefore the AllowPartialExecution is now set to false by default.
If there is a requirement to allow partial invocation, set this property to true.
The time parameter has been added to all log calls. This is a breaking change for all classes implementing ILogListener.
To improve multiple platforms support, all parameters of the following methods on BehaviorBase have been removed:
OnAssociatedObjectLoaded(object sender, EventArgs e) => OnAssociatedObjectLoaded() OnAssociatedObjectUnloaded(object sender, EventArgs e) => OnAssociatedObjectUnloaded() |