Reputation: 3
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.
Upvotes: 0
Views: 72
Reputation: 5724
I think that the window also resolves to use FooViewModel
for 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 FooViewModel
will be resolved earlier than FooWindowViewModel
due to how the naming conventions are set up).
uiVisualizerService.Register<FooWindowViewModel, FooWindow>();
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.
Upvotes: 0