ss11
ss11

Reputation: 3

Reset after cancelled dialog in catel

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

Answers (1)

Geert van Horrik
Geert van Horrik

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

Related Questions