Search code examples
c#.netmvvmcatelmodern-ui

Multiple VM creation while using Catel with Modern UI


I love Catel framework. Modern UI looks pretty good. But I've faced with problem while trying to make them works together.

I've added two catels usercontrols Home and Second in mui project. The problem is that when transition from Home to Second performing HomeViewModel has been created 3 times.

This behavior caused by next code in TransitioningContentControl

    private void StartTransition(object oldContent, object newContent)
    {
        // both presenters must be available, otherwise a transition is useless.
        if (CurrentContentPresentationSite != null && PreviousContentPresentationSite != null) {
            CurrentContentPresentationSite.Content = newContent;

            PreviousContentPresentationSite.Content = oldContent;

            // and start a new transition
            if (!IsTransitioning || RestartTransitionOnContentChange) {
                IsTransitioning = true;
                VisualStateManager.GoToState(this, NormalState, false);
                VisualStateManager.GoToState(this, Transition, true);
            }
        }
    }

If I comment some lines:

private void StartTransition(object oldContent, object newContent)
    {
        // both presenters must be available, otherwise a transition is useless.
        if (CurrentContentPresentationSite != null && PreviousContentPresentationSite != null) {
            CurrentContentPresentationSite.Content = newContent;

            //PreviousContentPresentationSite.Content = oldContent;

            // and start a new transition
            if (!IsTransitioning || RestartTransitionOnContentChange) {
                IsTransitioning = true;
                //VisualStateManager.GoToState(this, NormalState, false);
                //VisualStateManager.GoToState(this, Transition, true);
            }
        }
    }

Same transition in this case results in creating HomeViewModel 1 times, but I dont want creating HomeViewModel while performing navigation from Home control. How can I achieve this?

Project to taste


Solution

  • There are 2 possible options you can solve this issue:

    1) Use existing feature (CloseViewModelOnUnloaded). Will keep VM alive during transition.

    Then you need this code in TransitioningContentControl.StartTransition

    var userControl = oldContent as Catel.Windows.Controls.UserControl;
    if (userControl != null)
    {
        userControl.CloseViewModelOnUnloaded = false;
    }
    
    PreviousContentPresentationSite.Content = oldContent;
    

    Add this to OnTransitionCompleted:

    var userControl = PreviousContentPresentationSite.Content as Catel.Windows.Controls.UserControl;
    if (userControl != null)
    {
        userControl.CloseViewModelOnUnloaded = true;
        var vm = userControl.ViewModel;
        if (vm != null)
        {
            vm.CloseViewModel(true);
        }
    }
    
    AbortTransition();
    

    2) Use new feature (PreventViewModelCreation) Will not keep VM alive during transition.

    Then you need this code in TransitioningContentControl.StartTransition

    var vmContainer = oldContent as IViewModelContainer;
    if (vmContainer != null)
    {
        vmContainer.PreventViewModelCreation = true;
    }
    
    PreviousContentPresentationSite.Content = oldContent;
    

    Add this to the OnTransitionCompleted method:

    var vmContainer = PreviousContentPresentationSite.Content as IViewModelContainer;
    if (vmContainer != null)
    {
        vmContainer.PreventViewModelCreation = false;
    }
    
    AbortTransition();