i just started to explore Catel and i really like it.
But now I am stuck, as I cannot find a reason why the following does not work. I created a Foo Model, a FooViewModel and a FooWindowViewModel. I use the FooViewModel to show the state of the Foo Model and use the FooWindowViewModel to show a dialog to edit it.
My problem is that when I press cancel in the dialog, the changes I made are not reverted.
Short sidenote: In the example project (https://docs.catelproject.com/5.12/getting-started/wpf/) the resetting behaviour is as i expect it.
Here you can find some example code: Model:
using Catel.Data;
using System;
using System.Collections.Generic;
using System.Text;
namespace My1stCatelProject.Models
{
public class Foo : ModelBase
{
public string TextProp { get; set; }
}
}
public class FooWindowViewModel : ViewModelBase
{
public FooWindowViewModel(Foo model)
{
Model = model;
}
public override string Title { get => "FooWindow"; protected set => base.Title = value; }
[Model]
public Foo Model { get; set; }
[ViewModelToModel(nameof(Model))]
public string TextProp { get; set; }
}
using Catel.Data;
using Catel.IoC;
using Catel.MVVM;
using Catel.Services;
using My1stCatelProject.Models;
using System.ComponentModel;
using System.Threading.Tasks;
using Catel;
namespace My1stCatelProject.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
private readonly IUIVisualizerService _uiVisualizerService;
public MainWindowViewModel(IUIVisualizerService uiVisualizerService)
{
_uiVisualizerService = uiVisualizerService;
EditCommand = new TaskCommand(OnEdit);
}
public override string Title { get { return "Welcome to My1stCatelProject"; } }
public Foo MyFoo
{
get { return GetValue<Foo>(MyFooProperty); }
set { SetValue(MyFooProperty, value); }
}
public static readonly PropertyData MyFooProperty = RegisterProperty(nameof(MyFoo), typeof(Foo), () => new Foo() { TextProp = "XY" });
// TODO: Register models with the vmpropmodel codesnippet
// TODO: Register view model properties with the vmprop or vmpropviewmodeltomodel codesnippets
// TODO: Register commands with the vmcommand or vmcommandwithcanexecute codesnippets
protected override async Task InitializeAsync()
{
await base.InitializeAsync();
// TODO: subscribe to events here
}
protected override async Task CloseAsync()
{
// TODO: unsubscribe from events here
await base.CloseAsync();
}
public TaskCommand EditCommand { get; set; }
private async Task OnEdit()
{
var typeFactory = this.GetTypeFactory();
var fooWindowViewModel = typeFactory.CreateInstanceWithParametersAndAutoCompletion<FooWindowViewModel>(MyFoo);
if (await _uiVisualizerService.ShowDialogAsync(fooWindowViewModel) ?? false)
{
;
} else
{
// ((IEditableObject)fooWindowViewModel).CancelEdit(); // Doesnt work either
}
}
}
}
Thank you!
Edit 1: If I insert breakpoints into the beginEdit und cancelEdit EventHandler in the model and viewmodel, I can see that the cancelEdit is never exectued.
To reproduce the unexpected behaviour, you can use the link to the repository: https://github.com/Stjefan/My1stCatelProject
Edit 2: CancelEdit is executed on ending the application. So I guess, I messed up something in the initialisation.
I think that the window also resolves to use
FooViewModelfor the view model. You can test this by putting a breakpoint in the constructor and see if it's actually being called.If not, then you can / should manually register the correct view model for the window (since
FooViewModelwill be resolved earlier thanFooWindowViewModeldue to how the naming conventions are set up).Note that you can use the same vm for both the window and the control if you want. Then the user control will re-use the parent vm (in this case the window vm), but whether you want that is eventually up to you.