Transition Presenter in a MVVM Prism application

Dec 24, 2011 at 10:32 PM

Hi, I'm trying to use a transition presenter in a MVVM application based on Prism.

I have a navigator module wich I use to switch between different modules (3). I created a region adapter to manage the transition presenter as a region.

I successfully succeded in switching with cube transition between modules, but as soon as I completed the tour between modules, I'm no more able to swith them again.

I tried with 2 modules and I cannot go over 2 swithches.

After a while maybe I understood there is some problem with the region adapter, but cannot understand what.

Here bwlow the code:

 

using System;
using System.Windows;
using Microsoft.Practices.Prism.Regions;
using NavigationTransition;

namespace Test_04
{
    
    public class TransitionElementAdapter : RegionAdapterBase<NavigationPresenter>
    {
        
        public TransitionElementAdapter(IRegionBehaviorFactory behaviorFactory) :
            base(behaviorFactory)
        {
        }

        protected override void Adapt(IRegion region, NavigationPresenter regionTarget)
        {
           
            region.Views.CollectionChanged += (s, e) =>
            {/**/
                //Add
                if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                    foreach (FrameworkElement element in e.NewItems)
                    {
                        regionTarget.Content = element;
                    }
                        
 
                //Removal
                
                if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
                    foreach (FrameworkElement element in e.OldItems)
                    {
                        //regionTarget.Content = null;
                        //GC.Collect();
                        if (regionTarget.Content==element)

                            regionTarget.Content = null;
                    }
                 

            };
          
        }

        protected override IRegion CreateRegion()
        {
            return new AllActiveRegion();
        }

    }
}


Here the presenter code

using System;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Controls;
using System.Windows.Media;
using FluidKit.Controls;

namespace NavigationTransition
{
    /// <summary>
    /// ControlPresenter that animates its content every time the Content property changes
    /// </summary>
    public class NavigationPresenter : ContentPresenter
    {
        private readonly ContentPresenter oldContentPresenter;
        private readonly ContentPresenter newContentPresenter;
        private readonly TransitionPresenter transitionPresenter;
        private bool loaded;

        #region GoForward
        /// <summary>
        /// GoForward Dependency Property
        /// </summary>
        public static readonly DependencyProperty GoForwardProperty;

        /// <summary>
        /// Gets or sets the GoForward property
        /// </summary>
        public bool GoForward
        {
            get { return (bool)GetValue(GoForwardProperty); }
            set { SetValue(GoForwardProperty, value); }
        }
        #endregion

        #region Transition
        /// <summary>
        /// Transition Dependency Property
        /// </summary>
        public static readonly DependencyProperty TransitionProperty;

        /// <summary>
        /// Gets or sets the Transition property
        /// </summary>
        public Transition Transition
        {
            get { return (Transition)GetValue(TransitionProperty); }
            set { SetValue(TransitionProperty, value); }
        }
        #endregion

        internal UIElementCollection Children
        {
            get;
            private set;
        }

        static NavigationPresenter()
        {
            GoForwardProperty = DependencyProperty.Register(
                "GoForward", 
                typeof(bool), 
                typeof(NavigationPresenter),
                new FrameworkPropertyMetadata(false));

            TransitionProperty = DependencyProperty.Register(
                "Transition",
                typeof(Transition), 
                typeof(NavigationPresenter),
                new FrameworkPropertyMetadata(new NavigationFlipTransition(), new PropertyChangedCallback(OnTransitionChanged)));

            ContentProperty.OverrideMetadata(
                typeof(NavigationPresenter), 
                new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnContentValueChanged)));
        }

        public NavigationPresenter()
        {
            this.oldContentPresenter = new ContentPresenter();
            this.newContentPresenter = new ContentPresenter();

            this.transitionPresenter = new TransitionPresenter();
            this.transitionPresenter.Items.Add(this.oldContentPresenter);
            this.transitionPresenter.Items.Add(this.newContentPresenter);

            this.Children = new UIElementCollection(this, null);
            this.Children.Add(this.transitionPresenter);

            this.Loaded += (s, e) => this.loaded = true;
        }

        private static void OnTransitionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((NavigationPresenter)d).OnTransitionChanged(e);
        }

        private static void OnContentValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((NavigationPresenter)d).OnContentValueChanged(e);
        }

        private void OnContentValueChanged(DependencyPropertyChangedEventArgs e)
        {
            // switch ContentPresenters
            this.oldContentPresenter.Content = e.OldValue;
            this.newContentPresenter.Content = e.NewValue;

            if (this.loaded)
            {
                // if the transition supports the INavigationAware interface
                // prepare it using the GoForward/GoBackward methods
                if(this.transitionPresenter.Transition is INavigationAware)
                {
                    if(this.GoForward)
                        ((INavigationAware)this.transitionPresenter.Transition).GoForward();
                    else
                        ((INavigationAware)this.transitionPresenter.Transition).GoBackward();
                }

                // run the transition
                this.transitionPresenter.ApplyTransition(this.oldContentPresenter, this.newContentPresenter);
            }
        }

        private void OnTransitionChanged(DependencyPropertyChangedEventArgs e)
        {
            this.transitionPresenter.Transition = e.NewValue as Transition;
        }

        protected override Visual GetVisualChild(int index)
        {
            if ((index < 0) || (index >= this.Children.Count))
                throw new ArgumentOutOfRangeException("index");

            return this.Children[index];
        }


        protected override int VisualChildrenCount
        {
            get
            {
                if (this.Children != null)
                    return this.Children.Count;
                else
                    return 0;
            }
        }
    }
}

Mosto probably this will be not enough to understand, but don't know where to post the full project.

Thanks for helping in advance.

Regards
 

 

 

Mar 9, 2013 at 11:45 AM
Hi

Did you ever manage to find the solution to this issue?