winrt 上的翻书特效组件 源码分享 请说明

    [TemplatePart(Name = A_PARTNAME, Type = typeof(Border))]

    [TemplatePart(Name = B_PARTNAME, Type = typeof(Border))]

    [TemplatePart(Name = C_PARTNAME, Type = typeof(Border))]

    [TemplatePart(Name = D_PARTNAME, Type = typeof(Border))]

    [TemplatePart(Name = E_PARTNAME, Type = typeof(Border))]

    [TemplatePart(Name = F_PARTNAME, Type = typeof(Border))]

    [TemplatePart(Name = A_RECT_PARTNAME, Type = typeof(RectangleGeometry))]

    [TemplatePart(Name = B_RECT_PARTNAME, Type = typeof(RectangleGeometry))]

    [TemplatePart(Name = C_RECT_PARTNAME, Type = typeof(RectangleGeometry))]

    [TemplatePart(Name = D_RECT_PARTNAME, Type = typeof(RectangleGeometry))]

    [TemplatePart(Name = E_RECT_PARTNAME, Type = typeof(RectangleGeometry))]

    [TemplatePart(Name = F_RECT_PARTNAME, Type = typeof(RectangleGeometry))]

    [TemplatePart(Name = A_TRANS_PARTNAME, Type = typeof(CompositeTransform))]

    [TemplatePart(Name = B_TRANS_PARTNAME, Type = typeof(CompositeTransform))]

    [TemplatePart(Name = C_TRANS_PARTNAME, Type = typeof(CompositeTransform))]

    [TemplatePart(Name = D_TRANS_PARTNAME, Type = typeof(CompositeTransform))]

    [TemplatePart(Name = E_TRANS_PARTNAME, Type = typeof(CompositeTransform))]

    [TemplatePart(Name = F_TRANS_PARTNAME, Type = typeof(CompositeTransform))]

    [TemplatePart(Name = A_PRESENTER_PARTNAME, Type = typeof(ContentPresenter))]

    [TemplatePart(Name = B_PRESENTER_PARTNAME, Type = typeof(ContentPresenter))]

    [TemplatePart(Name = C_PRESENTER_PARTNAME, Type = typeof(ContentPresenter))]

    [TemplatePart(Name = D_PRESENTER_PARTNAME, Type = typeof(ContentPresenter))]

    [TemplatePart(Name = E_PRESENTER_PARTNAME, Type = typeof(ContentPresenter))]

    [TemplatePart(Name = F_PRESENTER_PARTNAME, Type = typeof(ContentPresenter))]

    [TemplatePart(Name = INNER_LEFT_TRANS_PARTNAME, Type = typeof(CompositeTransform))]

    [TemplatePart(Name = OUTER_LEFT_TRANS_PARTNAME, Type = typeof(CompositeTransform))]

    [TemplatePart(Name = INNER_RIGHT_TRANS_PARTNAME, Type = typeof(CompositeTransform))]

    [TemplatePart(Name = OUTER_RIGHT_TRANS_PARTNAME, Type = typeof(CompositeTransform))]

    [TemplatePart(Name = MARGIN_LEFT_TRANS_PARTNAME, Type = typeof(CompositeTransform))]

    [TemplatePart(Name = MARGIN_RIGHT_TRANS_PARTNAME, Type = typeof(CompositeTransform))]

    [TemplatePart(Name = ST_SHADOW_SPLIT_INNER_LEFT_PARTNAME, Type = typeof(StackPanel))]

    [TemplatePart(Name = ST_SHADOW_SPLIT_OUTER_LEFT_PARTNAME, Type = typeof(StackPanel))]

    [TemplatePart(Name = ST_SHADOW_SPLIT_INNER_RIGHT_PARTNAME, Type = typeof(StackPanel))]

    [TemplatePart(Name = ST_SHADOW_SPLIT_OUTER_RIGHT_PARTNAME, Type = typeof(StackPanel))]

    [TemplatePart(Name = ST_SHADOW_MARGIN_LEFT_PARTNAME, Type = typeof(StackPanel))]

    [TemplatePart(Name = ST_SHADOW_MARGIN_RIGHT_PARTNAME, Type = typeof(StackPanel))]

    [TemplatePart(Name = BOOK_CONTAINER_PARTNAME, Type = typeof(Image))]

    [TemplatePart(Name = GRD_CONTENT_PARTNAME, Type = typeof(Grid))]

    /// <summary>

    /// 作者:王韧竹

    /// 版本:1.1

    /// 根据偏移量算法 计算是否为放大 或者翻页 保证两者不冲突。

    /// 18/6/2013 23:06

    /// windows8 翻书特效组件

    /// </summary>

    public sealed class FlipBookControl : ItemsControl

    {

        #region Member Variables

        /// <summary>

        /// 0 初始 翻页状态1 翻页状态2

        /// </summary>

        private int Status = 0;

        /// <summary>

        /// 是否翻下一页

        /// true 下一页 false 上一页

        /// </summary>

        private bool isNext = false;

        /// <summary>

        /// 触发向左翻页动画

        /// true 发生偏移  false 停止偏移

        /// </summary>

        private bool turnLeft = false;

        /// <summary>

        /// 触发向右翻页动画

        /// true 发生偏移  false 停止偏移

        /// </summary>

        private bool turnRight = false;

        /// <summary>

        /// 触发向右翻页还原动画

        /// true 发生偏移  false 停止偏移

        /// </summary>

        private bool rightRestore = false;

        /// <summary>

        /// 触发向左翻页还原动画

        /// true 发生偏移  false 停止偏移

        /// </summary>

        private bool leftRestore = false;

        /// <summary>

        /// 是否多点操作中

        /// true 是 false 否

        /// </summary>

        private bool isManipulating = false;

        /// <summary>

        /// 最近一次偏移量

        /// </summary>

        private double lastDeltaOffset = 0.0;

        /// <summary>

        /// 横向偏移量

        /// </summary>

        private double offsetWidth = 0.0;

        /// <summary>

        /// 竖向偏移量

        /// </summary>

        private double offsetHeight = 0.0;

        /// <summary>

        /// 是否加载

        /// </summary>

        private bool isLoaded = false;

        /// <summary>

        /// 是否初始化

        /// </summary>

        private bool isInit = false;



        /// <summary>

        /// 控制是否翻页

        /// </summary>

        private bool isFlip = true;



        /// <summary>

        /// 是否释放

        /// </summary>

        private bool isRelease = true;

        Border nextPage;

        Border prevPage;

        Border leftPage;

        Border rightPage;

        Border leftTopPage;

        Border rightTopPage;

        CompositeTransform nextTrans;

        CompositeTransform prevTrans;

        Border A;

        Border B;

        Border C;

        Border D;

        Border E;

        Border F;

        ContentPresenter APresenter;

        ContentPresenter BPresenter;

        ContentPresenter CPresenter;

        ContentPresenter DPresenter;

        ContentPresenter EPresenter;

        ContentPresenter FPresenter;

        RectangleGeometry ARect;

        RectangleGeometry BRect;

        RectangleGeometry CRect;

        RectangleGeometry DRect;

        RectangleGeometry ERect;

        RectangleGeometry FRect;

        CompositeTransform transA;

        CompositeTransform transB;

        CompositeTransform transC;

        CompositeTransform transD;

        CompositeTransform transE;

        CompositeTransform transF;

        CompositeTransform innerLeftTrans;

        CompositeTransform outerLeftTrans;

        CompositeTransform innerRightTrans;

        CompositeTransform outerRightTrans;

        CompositeTransform marginLeftTrans;

        CompositeTransform marginRightTrans;

        StackPanel stShadowSplitOuterLeft;

        StackPanel stShadowSplitInnerLeft;

        StackPanel stShadowSplitOuterRight;

        StackPanel stShadowSplitInnerRight;

        StackPanel stShadowMarginLeft;

        StackPanel stShadowMarginRight;

        Grid grdContent;

        Image bookContainer;

        ImageBrush leftBrush;

        ImageBrush rightBrush;

        private TransformGroup _transformGroup;

        private MatrixTransform _previousTransform;

        private CompositeTransform _compositeTransform;

        #endregion



        #region Template Part

        /// <summary>

        /// 矩形

        /// </summary>

        const string A_PARTNAME = "A";

        /// <summary>

        /// 矩形遮掩

        /// </summary>

        const string A_RECT_PARTNAME = "ARect";

        /// <summary>

        /// 矩形偏移

        /// </summary>

        const string A_TRANS_PARTNAME = "transA";

        const string A_PRESENTER_PARTNAME = "APresenter";

        const string B_PARTNAME = "B";

        const string B_RECT_PARTNAME = "BRect";

        const string B_TRANS_PARTNAME = "transB";

        const string B_PRESENTER_PARTNAME = "BPresenter";

        const string C_PARTNAME = "C";

        const string C_RECT_PARTNAME = "CRect";

        const string C_TRANS_PARTNAME = "transC";

        const string C_PRESENTER_PARTNAME = "CPresenter";

        const string D_PARTNAME = "D";

        const string D_RECT_PARTNAME = "DRect";

        const string D_TRANS_PARTNAME = "transD";

        const string D_PRESENTER_PARTNAME = "DPresenter";

        const string E_PARTNAME = "E";

        const string E_RECT_PARTNAME = "ERect";

        const string E_TRANS_PARTNAME = "transE";

        const string E_PRESENTER_PARTNAME = "EPresenter";

        const string F_PARTNAME = "F";

        const string F_RECT_PARTNAME = "FRect";

        const string F_TRANS_PARTNAME = "transF";

        const string F_PRESENTER_PARTNAME = "FPresenter";

        const string ST_SHADOW_SPLIT_OUTER_RIGHT_PARTNAME = "stShadowSplitOuterRight";

        const string ST_SHADOW_SPLIT_INNER_RIGHT_PARTNAME = "stShadowSplitInnerRight";

        const string ST_SHADOW_SPLIT_OUTER_LEFT_PARTNAME = "stShadowSplitOuterLeft";

        const string ST_SHADOW_SPLIT_INNER_LEFT_PARTNAME = "stShadowSplitInnerLeft";

        const string ST_SHADOW_MARGIN_LEFT_PARTNAME = "stShadowMarginLeft";

        const string ST_SHADOW_MARGIN_RIGHT_PARTNAME = "stShadowMarginRight";

        const string OUTER_LEFT_TRANS_PARTNAME = "outerLeftTrans";

        const string INNER_LEFT_TRANS_PARTNAME = "innerLeftTrans";

        const string OUTER_RIGHT_TRANS_PARTNAME = "outerRightTrans";

        const string INNER_RIGHT_TRANS_PARTNAME = "innerRightTrans";

        const string MARGIN_LEFT_TRANS_PARTNAME = "marginLeftTrans";

        const string MARGIN_RIGHT_TRANS_PARTNAME = "marginRightTrans";

        /// <summary>

        /// 书壳

        /// </summary>

        const string BOOK_CONTAINER_PARTNAME = "bookContainer";

        const string GRD_CONTENT_PARTNAME = "grdContent";

        #endregion



        #region DependencyProperties

        #region DelayLoad

        public TimeSpan DelayLoad

        {

            get { return (TimeSpan)GetValue(DelayLoadProperty); }

            set { SetValue(DelayLoadProperty, value); }

        }



        // Using a DependencyProperty as the backing store for DelayLoad.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty DelayLoadProperty =

            DependencyProperty.Register("DelayLoad", typeof(TimeSpan), typeof(FlipBookControl), new PropertyMetadata(TimeSpan.FromSeconds(0)));

        #endregion



        #region BookBackgroundBrush

        public ImageBrush BookBackgroundBrush

        {

            get { return (ImageBrush)GetValue(BookBackgroundBrushProperty); }

            set { SetValue(BookBackgroundBrushProperty, value); }

        }



        // Using a DependencyProperty as the backing store for BookBackgroundBrush.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty BookBackgroundBrushProperty =

            DependencyProperty.Register("BookBackgroundBrush", typeof(ImageBrush), typeof(FlipBookControl), new PropertyMetadata(null, OnBookBackgroundBrushChangedCallBack));



        private static async void OnBookBackgroundBrushChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {



            var ctrl = (d as FlipBookControl);

            if (ctrl.isLoaded)

                await ctrl.GetCropBrush();

        }

        #endregion



        #region Speed

        /// <summary>

        /// 动画速度 默认为30pixel

        /// </summary>

        public int Speed

        {

            get { return (int)GetValue(SpeedProperty); }

            set { SetValue(SpeedProperty, value); }

        }



        // Using a DependencyProperty as the backing store for Speed.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty SpeedProperty =

            DependencyProperty.Register("Speed", typeof(int), typeof(FlipBookControl), new PropertyMetadata(30));

        #endregion



        #region BookContainerSource

        public ImageSource BookContainerSource

        {

            get { return (ImageSource)GetValue(BookContainerSourceProperty); }

            set { SetValue(BookContainerSourceProperty, value); }

        }



        // Using a DependencyProperty as the backing store for BookContainerSource.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty BookContainerSourceProperty =

            DependencyProperty.Register("BookContainerSource", typeof(ImageSource), typeof(FlipBookControl), new PropertyMetadata(null, OnBookContainerSourceChangedCallBack));



        private static void OnBookContainerSourceChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            var ctrl = (d as FlipBookControl);

            if (null != ctrl.BookContainerSource && ctrl.bookContainer != null && ctrl.isLoaded)

                ctrl.bookContainer.Source = ctrl.BookContainerSource;

        }



        #endregion



        #region PageIndex

        public int PageIndex

        {

            get { return (int)GetValue(PageIndexProperty); }

            set { SetValue(PageIndexProperty, value); }

        }



        // Using a DependencyProperty as the backing store for PageIndex.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty PageIndexProperty =

            DependencyProperty.Register("PageIndex", typeof(int), typeof(FlipBookControl), new PropertyMetadata(0, OnPageIndexChangedCallBack));



        private static void OnPageIndexChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            var ctrl = (d as FlipBookControl);

            if (ctrl.isLoaded)

            {

                var isNext = Convert.ToInt32(e.NewValue) > Convert.ToInt32(e.OldValue);

                var presenters = ctrl.GetPresentersByPageIndex(isNext);

                if (null != presenters)

                    ctrl.LoadPageContentByPageIndex(Convert.ToInt32(e.NewValue), isNext, presenters[0], presenters[1]);

            }

        }

        #endregion



        #region DisposeAction

        public Action<object> DisposeAction

        {

            get { return (Action<object>)GetValue(DisposeActionProperty); }

            set { SetValue(DisposeActionProperty, value); }

        }



        // Using a DependencyProperty as the backing store for DisposeAction.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty DisposeActionProperty =

            DependencyProperty.Register("DisposeAction", typeof(Action<object>), typeof(FlipBookControl), new PropertyMetadata(null));

        #endregion



        #region RestoreItemAction

        public Action<object> RestoreItemAction

        {

            get { return (Action<object>)GetValue(RestoreItemActionProperty); }

            set { SetValue(RestoreItemActionProperty, value); }

        }



        // Using a DependencyProperty as the backing store for RestoreItemAction.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty RestoreItemActionProperty =

            DependencyProperty.Register("RestoreItemAction", typeof(Action<object>), typeof(FlipBookControl), new PropertyMetadata(null));

        #endregion



        #region CanScale

        public bool CanScale

        {

            get { return (bool)GetValue(CanScaleProperty); }

            set { SetValue(CanScaleProperty, value); }

        }



        // 能否进行放大缩小

        public static readonly DependencyProperty CanScaleProperty =

            DependencyProperty.Register("CanScale", typeof(bool), typeof(FlipBookControl), new PropertyMetadata(false));

        #endregion

        #endregion



        #region Event

        /// <summary>

        /// 翻书结束事件

        /// </summary>

        private delegate void Fliped(object sender, FlipEventArgs args);



        private event Fliped Fliping;

        /// <summary>

        /// 加载事件

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="args"></param>

        public delegate void NeedLoadItems(object sender, FlipLoadArgs args);



        public event NeedLoadItems NeedLoadingItem;

        #endregion



        #region Constructor

        public FlipBookControl()

        {

            this.DefaultStyleKey = typeof(FlipBookControl);

            this.Loaded += FlipBookControlLoaded;

            this.Unloaded += FlipBookControlUnLoaded;

            CompositionTarget.Rendering += RenderAnimation;

            this.Fliping += FlipEnded;

        }



        /// <summary>

        /// 初始化完毕开始载入数据

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private async void FlipBookControlLoaded(object sender, RoutedEventArgs e)

        {

            grdContent.ManipulationMode =

              ManipulationModes.TranslateInertia |

              ManipulationModes.TranslateX |

              ManipulationModes.Scale |

              ManipulationModes.ScaleInertia |

              ManipulationModes.TranslateY;

            grdContent.ManipulationDelta += FlipManipulationDelta;

            grdContent.ManipulationCompleted += FlipManipulationCompleted;

            grdContent.ManipulationStarting += FlipManipulationStarting;

            grdContent.ManipulationInertiaStarting += FlipManipulationInertiaStarting;

            A.PointerPressed += PointerPressed;

            B.PointerPressed += PointerPressed;

            C.PointerPressed += PointerPressed;

            D.PointerPressed += PointerPressed;

            E.PointerPressed += PointerPressed;

            F.PointerPressed += PointerPressed;

            offsetWidth = A.ActualWidth;

            offsetHeight = A.ActualHeight;

            await GetCropBrush();

            bookContainer.Source = BookContainerSource;

            RefreshPageByStatus();

            InitPages();

            isLoaded = true;

        }



        private void FlipBookControlUnLoaded(object sender, RoutedEventArgs e)

        {

            CompositionTarget.Rendering -= RenderAnimation;

            grdContent.ManipulationDelta -= FlipManipulationDelta;

            grdContent.ManipulationCompleted -= FlipManipulationCompleted;

            grdContent.ManipulationStarting -= FlipManipulationStarting;

            grdContent.ManipulationInertiaStarting -= FlipManipulationInertiaStarting;

            this.Fliping -= FlipEnded;

            A.PointerPressed -= PointerPressed;

            B.PointerPressed -= PointerPressed;

            C.PointerPressed -= PointerPressed;

            D.PointerPressed -= PointerPressed;

            E.PointerPressed -= PointerPressed;

            F.PointerPressed -= PointerPressed;

        }



        public void InitPosition()

        {

            _compositeTransform = new CompositeTransform();

            _previousTransform = new MatrixTransform() { Matrix = Matrix.Identity };

            _transformGroup = new TransformGroup();

            _transformGroup.Children.Add(_previousTransform);

            _transformGroup.Children.Add(_compositeTransform);

            this.RenderTransform = _transformGroup;

        }



        public async void InitPages()

        {

            if (!isInit && PageIndex == 0 && this.Items.Count > 0)

            {

                await Task.Delay(DelayLoad);

                List<object> needLoadItems = new List<object>();

                //第一次加载 载入4页

                CPresenter.DataContext = this.Items[0];

                needLoadItems.Add(Items[0]);

                if (this.Items.Count > 1)

                {

                    DPresenter.DataContext = this.Items[1];

                    needLoadItems.Add(Items[1]);

                }

                if (this.Items.Count > 2)

                {

                    EPresenter.DataContext = this.Items[2];

                    needLoadItems.Add(Items[2]);

                }

                if (this.Items.Count > 3)

                {

                    FPresenter.DataContext = this.Items[3];

                    needLoadItems.Add(Items[3]);

                }

                if (null != NeedLoadingItem)

                    NeedLoadingItem(this, new FlipLoadArgs(needLoadItems, false));

                isInit = true;

            }

            else

            {

                Status = 0;

                this.PageIndex = 0;

                if (null != APresenter)

                {

                    APresenter.DataContext = null;

                    BPresenter.DataContext = null;

                    CPresenter.DataContext = null;

                    DPresenter.DataContext = null;

                    EPresenter.DataContext = null;

                    FPresenter.DataContext = null;

                }

            }

            InitPosition();

        }

        #endregion



        #region EventMethod

        #region OnApplyTemplate

        protected override void OnApplyTemplate()

        {

            bookContainer = GetTemplateChild(BOOK_CONTAINER_PARTNAME) as Image;

            A = GetTemplateChild(A_PARTNAME) as Border;

            B = GetTemplateChild(B_PARTNAME) as Border;

            C = GetTemplateChild(C_PARTNAME) as Border;

            D = GetTemplateChild(D_PARTNAME) as Border;

            E = GetTemplateChild(E_PARTNAME) as Border;

            F = GetTemplateChild(F_PARTNAME) as Border;

            APresenter = GetTemplateChild(A_PRESENTER_PARTNAME) as ContentPresenter;

            BPresenter = GetTemplateChild(B_PRESENTER_PARTNAME) as ContentPresenter;

            CPresenter = GetTemplateChild(C_PRESENTER_PARTNAME) as ContentPresenter;

            DPresenter = GetTemplateChild(D_PRESENTER_PARTNAME) as ContentPresenter;

            EPresenter = GetTemplateChild(E_PRESENTER_PARTNAME) as ContentPresenter;

            FPresenter = GetTemplateChild(F_PRESENTER_PARTNAME) as ContentPresenter;

            ARect = GetTemplateChild(A_RECT_PARTNAME) as RectangleGeometry;

            BRect = GetTemplateChild(B_RECT_PARTNAME) as RectangleGeometry;

            CRect = GetTemplateChild(C_RECT_PARTNAME) as RectangleGeometry;

            DRect = GetTemplateChild(D_RECT_PARTNAME) as RectangleGeometry;

            ERect = GetTemplateChild(E_RECT_PARTNAME) as RectangleGeometry;

            FRect = GetTemplateChild(F_RECT_PARTNAME) as RectangleGeometry;

            transA = GetTemplateChild(A_TRANS_PARTNAME) as CompositeTransform;

            transB = GetTemplateChild(B_TRANS_PARTNAME) as CompositeTransform;

            transC = GetTemplateChild(C_TRANS_PARTNAME) as CompositeTransform;

            transD = GetTemplateChild(D_TRANS_PARTNAME) as CompositeTransform;

            transE = GetTemplateChild(E_TRANS_PARTNAME) as CompositeTransform;

            transF = GetTemplateChild(F_TRANS_PARTNAME) as CompositeTransform;

            grdContent = GetTemplateChild(GRD_CONTENT_PARTNAME) as Grid;

            innerLeftTrans = GetTemplateChild(INNER_LEFT_TRANS_PARTNAME) as CompositeTransform;

            outerLeftTrans = GetTemplateChild(OUTER_LEFT_TRANS_PARTNAME) as CompositeTransform;

            innerRightTrans = GetTemplateChild(INNER_RIGHT_TRANS_PARTNAME) as CompositeTransform;

            outerRightTrans = GetTemplateChild(OUTER_RIGHT_TRANS_PARTNAME) as CompositeTransform;

            marginLeftTrans = GetTemplateChild(MARGIN_LEFT_TRANS_PARTNAME) as CompositeTransform;

            marginRightTrans = GetTemplateChild(MARGIN_RIGHT_TRANS_PARTNAME) as CompositeTransform;

            stShadowSplitInnerLeft = GetTemplateChild(ST_SHADOW_SPLIT_INNER_LEFT_PARTNAME) as StackPanel;

            stShadowSplitOuterLeft = GetTemplateChild(ST_SHADOW_SPLIT_OUTER_LEFT_PARTNAME) as StackPanel;

            stShadowSplitInnerRight = GetTemplateChild(ST_SHADOW_SPLIT_INNER_RIGHT_PARTNAME) as StackPanel;

            stShadowSplitOuterRight = GetTemplateChild(ST_SHADOW_SPLIT_OUTER_RIGHT_PARTNAME) as StackPanel;

            stShadowMarginLeft = GetTemplateChild(ST_SHADOW_MARGIN_LEFT_PARTNAME) as StackPanel;

            stShadowMarginRight = GetTemplateChild(ST_SHADOW_MARGIN_RIGHT_PARTNAME) as StackPanel;

            base.OnApplyTemplate();

        }

        #endregion



        #region PointerPressed

        /// <summary>

        /// 确定翻页方向

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void PointerPressed(object sender, PointerRoutedEventArgs e)

        {

            if (!isManipulating)

            {

                if (sender.Equals(leftPage))

                    isNext = false;

                else if (sender.Equals(rightPage))

                    isNext = true;

                else

                    RefreshPageByStatus();

                Debug.WriteLine("按下:" + isNext);

                Debug.WriteLine("点击的壳:" + (sender as Border).Name + " 左页壳:" + (sender as Border).Name);

            }

        }

        #endregion



        #region OnPointerReleased

        protected override void OnPointerReleased(PointerRoutedEventArgs e)

        {

            base.OnPointerReleased(e);

        }

        #endregion



        #region FlipEnded

        /// <summary>

        /// 翻页完毕

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="args"></param>

        private async void FlipEnded(object sender, FlipEventArgs args)

        {

            Debug.WriteLine("翻页完毕:" + args.isNext);

            if (args.isNext) PageIndex += 2;

            else PageIndex -= 2;

            await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>

            RefreshPageByStatus());

        }

        #endregion



        #region Manipulation  多点触控操作翻书特效

        #region FlipManipulationStarting

        private void FlipManipulationStarting(object sender, ManipulationStartingRoutedEventArgs e)

        {

            isManipulating = true;

            e.Handled = true;

            if (isNext)

            {

                if (PageIndex >= this.Items.Count - 2)

                {

                    isFlip = false;

                    isManipulating = false;

                }

            }

            else

            {

                if (this.PageIndex == 0)

                {

                    isFlip = false;

                    isManipulating = false;

                }

            }

        }

        #endregion



        #region FlipManipulationInertiaStarting

        private void FlipManipulationInertiaStarting(object sender, ManipulationInertiaStartingRoutedEventArgs e)

        {

            e.TranslationBehavior.DesiredDeceleration = 5 * 96.0 / (1000.0 * 1000.0);

            e.ExpansionBehavior.DesiredDeceleration = 100 * 96 / 1000.0 * 1000.0;

        }

        #endregion



        #region FlipManipulationCompleted

        private async void FlipManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)

        {

            isManipulating = false;

            if (isFlip)

            {

                IsHitVisible(false);

                var leftTopOffset = leftTopPage.Clip.Rect.X;

                var rightTopOffset = rightTopPage.Clip.Rect.X;

                await Task.Run(() =>

                {

                    if (isNext)

                    {

                        if (lastDeltaOffset < 0)

                        {

                            Status = Status < 2 ? Status + 1 : 0;

                            turnRight = true;

                        }

                        else if (rightTopOffset != 0.0)

                            rightRestore = true;

                        else IsHitVisible(true);

                        Debug.WriteLine("下一页:" + turnRight);

                    }

                    else

                    {

                        if (lastDeltaOffset > 0)

                        {

                            Status = Status > 0 ? Status - 1 : 2;

                            turnLeft = true;

                        }

                        else if (leftTopOffset != 0.0)

                            leftRestore = true;

                        else IsHitVisible(true);

                        Debug.WriteLine("上一页" + turnLeft);

                    }

                });



                Debug.WriteLine("翻页状态:" + Status);

            }

            isFlip = true;

            CanScale = false;

        }

        #endregion



        #region FlipManipulationDelta

        private void FlipManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)

        {

            var scale = e.Delta.Scale;

            var translateX = e.Delta.Translation.X;

            var translateY = e.Delta.Translation.Y;

            var nTtranX = nextTrans.TranslateX;

            var nTtranY = nextTrans.TranslateY;

            var ctranlateX = e.Cumulative.Translation.X;

            var ctranlateY = e.Cumulative.Translation.Y;

            CanScale = Task.Run(() =>

            {

                if (scale != 1.0 || (Math.Abs(ctranlateX * 1.15) < Math.Abs(ctranlateY))) return true;

                else return false;

            }).Result;

            if (isManipulating && !CanScale)

            {

                if (isNext)

                {

                    #region 下一页

                    var rightTopNect = rightTopPage.Clip.Rect;

                    var nextRect = nextPage.Clip.Rect;

                    var nextTransOffset = nTtranX + translateX * 2;



                    SetShadowOperacity(Math.Abs(nextTransOffset), offsetWidth, false);

                    var nextRectXOffset = nextRect.X - e.Delta.Translation.X;

                    lastDeltaOffset = e.Delta.Translation.X;

                    if (nextRectXOffset < 0 && nextRectXOffset > -offsetWidth)

                    {

                        outerRightTrans.TranslateX += e.Delta.Translation.X;

                        innerRightTrans.TranslateX += e.Delta.Translation.X;

                        marginRightTrans.TranslateX += e.Delta.Translation.X * 2;



                        nextTrans.TranslateX = nextTransOffset;

                        if (nextRectXOffset < 0)

                            nextRect.X = nextRectXOffset;

                        rightTopNect.X += e.Delta.Translation.X;

                        nextPage.Clip.Rect = nextRect;

                        rightTopPage.Clip.Rect = rightTopNect;

                    }

                    else

                    {

                        e.Complete();

                        if (nextTransOffset < 0)

                        {

                            nextTrans.TranslateX = -offsetWidth;

                            nextRect.X = 0;

                            rightTopNect.X = 0;

                            nextPage.Clip.Rect = nextRect;

                            rightTopPage.Clip.Rect = rightTopNect;

                        }

                        else

                        {

                            nextTrans.TranslateX = offsetWidth;

                            nextRect.X = -offsetWidth;

                            rightTopNect.X = offsetWidth;

                            nextPage.Clip.Rect = nextRect;

                            rightTopPage.Clip.Rect = rightTopNect;

                        }

                    }

                    #endregion

                }

                else

                {

                    #region 上一页

                    var leftTopNect = leftTopPage.Clip.Rect;

                    var prevRect = prevPage.Clip.Rect;

                    var prevTransOffset = prevTrans.TranslateX + e.Delta.Translation.X * 2;

                    var prevRectXOffset = prevRect.X - e.Delta.Translation.X;

                    SetShadowOperacity(Math.Abs(prevTransOffset), offsetWidth, true);

                    lastDeltaOffset = e.Delta.Translation.X;

                    if (prevRectXOffset > 0 && prevRectXOffset < offsetWidth)

                    {

                        innerLeftTrans.TranslateX += translateX;

                        outerLeftTrans.TranslateX += translateX;

                        marginLeftTrans.TranslateX += translateX * 2;



                        prevTrans.TranslateX = prevTransOffset;

                        if (prevRectXOffset > 0)

                            prevRect.X = prevRectXOffset;

                        leftTopNect.X += e.Delta.Translation.X;

                        prevPage.Clip.Rect = prevRect;

                        leftTopPage.Clip.Rect = leftTopNect;

                    }

                    else

                    {

                        e.Complete();

                        if (prevTransOffset < 0)

                        {

                            prevTrans.TranslateX = -offsetWidth;

                            prevRect.X = offsetWidth;

                            leftTopNect.X = -offsetWidth;

                            prevPage.Clip.Rect = prevRect;

                            leftTopPage.Clip.Rect = leftTopNect;



                        }

                        else

                        {

                            prevTrans.TranslateX = offsetWidth;

                            prevRect.X = 0;

                            leftTopNect.X = 0;

                            prevPage.Clip.Rect = prevRect;

                            leftTopPage.Clip.Rect = leftTopNect;

                        }

                    }

                    #endregion

                }

            }

            if (CanScale)

            {

                _previousTransform.Matrix = _transformGroup.Value;

                Point center = _previousTransform.TransformPoint(new Point(e.Position.X, e.Position.Y));

                _compositeTransform.CenterX = center.X;

                _compositeTransform.CenterY = center.Y;

                _compositeTransform.ScaleX = e.Delta.Scale;

                _compositeTransform.ScaleY = e.Delta.Scale;

                _compositeTransform.TranslateX = e.Delta.Translation.X;

                _compositeTransform.TranslateY = e.Delta.Translation.Y;

            }

        }

        #endregion

        #endregion



        #region RenderAnimation 绘制翻页动画

        private void RenderAnimation(object sender, object e)

        {

            if (turnLeft)

            {

                rightRestore = false;

                turnRight = false;

                var prevRect = prevPage.Clip.Rect;

                var leftTopRect = leftTopPage.Clip.Rect;

                var prevOffset = prevRect.X - Speed / 2;

                if (prevOffset > 0)

                {

                    prevRect.X = prevOffset;

                    prevTrans.TranslateX += Speed;

                    leftTopRect.X += Speed / 2;

                    innerLeftTrans.TranslateX += Speed / 2;

                    outerLeftTrans.TranslateX += Speed / 2;

                    marginLeftTrans.TranslateX += Speed;

                    SetShadowOperacity(Math.Abs(prevTrans.TranslateX), offsetWidth, true);

                }

                else

                {

                    prevRect.X = 0;

                    leftTopRect.X = 0;

                    turnLeft = false;

                    prevTrans.TranslateX = offsetWidth;

                    Fliping(sender, new FlipEventArgs(false));



                }

                prevPage.Clip.Rect = prevRect;

                leftTopPage.Clip.Rect = leftTopRect;

                IsHitVisible(true);

            }

            else if (leftRestore)

            {

                turnLeft = false;

                turnRight = false;

                rightRestore = false;

                var prevRect = prevPage.Clip.Rect;

                var leftTopRect = leftTopPage.Clip.Rect;

                var prevOffset = prevRect.X + Speed / 2;

                if (prevOffset < offsetWidth)

                {

                    prevRect.X = prevOffset;

                    prevTrans.TranslateX -= Speed;

                    leftTopRect.X -= Speed / 2;

                    innerLeftTrans.TranslateX -= Speed / 2;

                    outerLeftTrans.TranslateX -= Speed / 2;

                    marginLeftTrans.TranslateX -= Speed;

                    SetShadowOperacity(Math.Abs(prevTrans.TranslateX), offsetWidth, true);

                }

                else

                {

                    prevRect.X = offsetWidth;

                    leftTopRect.X = -offsetWidth;

                    prevTrans.TranslateX = -offsetWidth;

                    innerLeftTrans.TranslateX = 0;

                    outerLeftTrans.TranslateX = 0;

                    marginLeftTrans.TranslateX = 0;

                    leftRestore = false;



                }

                prevPage.Clip.Rect = prevRect;

                leftTopPage.Clip.Rect = leftTopRect;

                IsHitVisible(true);

            }

            else if (turnRight)

            {



                rightRestore = false;

                turnLeft = false;

                var nextRect = nextPage.Clip.Rect;

                var rightTopRect = rightTopPage.Clip.Rect;

                var nextOffset = nextRect.X + Speed / 2;

                if (nextOffset < 0)

                {

                    nextRect.X = nextOffset;

                    nextTrans.TranslateX -= Speed;

                    rightTopRect.X -= Speed / 2;

                    innerRightTrans.TranslateX -= Speed / 2;

                    outerRightTrans.TranslateX -= Speed / 2;

                    marginRightTrans.TranslateX -= Speed;

                    SetShadowOperacity(Math.Abs(nextTrans.TranslateX), offsetWidth, false);

                }

                else

                {

                    nextRect.X = 0;

                    nextTrans.TranslateX = -offsetWidth;

                    turnRight = false;

                    rightTopRect.X = 0;

                    Fliping(sender, new FlipEventArgs(true));

                }

                nextPage.Clip.Rect = nextRect;

                rightTopPage.Clip.Rect = rightTopRect;

                IsHitVisible(true);

            }

            else if (rightRestore)

            {



                turnRight = false;

                turnLeft = false;

                leftRestore = false;

                var nextRect = nextPage.Clip.Rect;

                var rightTopRect = rightTopPage.Clip.Rect;

                var nextOffset = nextRect.X - Speed / 2;

                if (nextRect.X - Speed / 2 > -offsetWidth)

                {

                    nextRect.X = nextOffset;

                    nextTrans.TranslateX += Speed;

                    rightTopRect.X += Speed / 2;

                    innerRightTrans.TranslateX += Speed / 2;

                    outerRightTrans.TranslateX += Speed / 2;

                    marginRightTrans.TranslateX += Speed;

                    SetShadowOperacity(Math.Abs(nextTrans.TranslateX), offsetWidth, false);

                }

                else

                {

                    nextRect.X = -offsetWidth;

                    rightTopRect.X = offsetWidth;

                    nextTrans.TranslateX = offsetWidth;

                    innerRightTrans.TranslateX = 0;

                    outerRightTrans.TranslateX = 0;

                    marginRightTrans.TranslateX = 0;

                    rightRestore = false;

                }

                rightTopPage.Clip.Rect = rightTopRect;

                nextPage.Clip.Rect = nextRect;

                IsHitVisible(true);

            }

        }

        #endregion

        #endregion



        #region Method

        #region LoadPageContentByPageIndex

        private void LoadPageContentByPageIndex(int PageIndex, bool isNextOrPrev, ContentPresenter firstPresenter, ContentPresenter secondPresenter)

        {

            List<object> needLoadItems = new List<object>();

            if (isNextOrPrev)

            {

                //加载下一页模板

                if (PageIndex + 2 < this.Items.Count)

                {

                    firstPresenter.Content = null;

                    firstPresenter.DataContext = null;

                    object item = null;

                    if (this.Items.Count > PageIndex + 2)

                    {

                        item = this.Items[PageIndex + 2];

                        needLoadItems.Add(item);

                        firstPresenter.DataContext = item;

                    }

                }

                else firstPresenter.DataContext = null;

                if (PageIndex + 3 < this.Items.Count)

                {

                    object item = null;

                    secondPresenter.Content = null;

                    secondPresenter.DataContext = null;

                    if (this.Items.Count > PageIndex + 3)

                    {

                        item = this.Items[PageIndex + 3];

                        needLoadItems.Add(item);

                        secondPresenter.DataContext = item;

                    }

                }

                else secondPresenter.DataContext = null;

                if (null != NeedLoadingItem)

                    NeedLoadingItem(this, new FlipLoadArgs(needLoadItems, true));

                RecycleData(true, needLoadItems);

            }

            else

            {

                if (PageIndex - 2 >= 0 && Items.Count > PageIndex - 2)

                {

                    needLoadItems.Add(this.Items[PageIndex - 2]);

                    secondPresenter.Content = null;

                    secondPresenter.DataContext = null;

                    secondPresenter.DataContext = this.Items[PageIndex - 2];

                }

                if (PageIndex - 1 >= 0 && Items.Count > PageIndex - 1)

                {

                    firstPresenter.Content = null;

                    firstPresenter.DataContext = null;

                    firstPresenter.DataContext = this.Items[PageIndex - 1];

                    needLoadItems.Add(this.Items[PageIndex - 1]);

                }

                //加载上一页模板

                if (null != NeedLoadingItem)

                    NeedLoadingItem(this, new FlipLoadArgs(needLoadItems, false));

                RecycleData(false, needLoadItems);

            }

        }

        #endregion



        #region RecycleData

        private async void RecycleData(bool isNext, List<object> needItems)

        {

            await Task.Run(async () =>

            {

                foreach (var o in needItems)

                {

                    await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>

                    {

                        if (null != this.RestoreItemAction)

                            this.RestoreItemAction.Invoke(o);

                    });

                }

                if (isNext)

                {

                    var index = -1;

                    try

                    {

                        index = this.Items.IndexOf(needItems[0]);



                    }

                    catch

                    {

                        index = -1;

                    }

                    if (index != -1 && index - 8 > 0)

                    {

                        for (int i = index - 8; i < index - 6; i++)

                            await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () =>

                            {

                                if (null != this.DisposeAction)

                                    DisposeAction.Invoke(this.Items[i]);

                            });

                    }

                }

                else

                {

                    var index = -1;

                    try

                    {

                        index = this.Items.IndexOf(needItems.Last());



                    }

                    catch (Exception ex)

                    {

                        index = -1;

                    }

                    if (index != -1 && this.Items.Count > index + 7)

                    {

                        for (int i = index + 5; i < index + 7; i++)

                            await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () =>

                            {

                                if (null != this.DisposeAction)

                                    DisposeAction.Invoke(this.Items[i]);

                            });

                    }

                }

            });

        }

        #endregion



        #region OnItemsChanged

        /// <summary>

        /// 刷新数据 

        /// </summary>

        /// <param name="e"></param>

        protected override void OnItemsChanged(object e)

        {

            isInit = false;

            InitPages();

            base.OnItemsChanged(e);

        }

        #endregion



        #region GetPresentersByPageIndex

        private List<ContentPresenter> GetPresentersByPageIndex(bool isNext)

        {

            List<ContentPresenter> presenters = new List<ContentPresenter>();

            if (isNext)

            {

                presenters.Add(leftTopPage.Child as ContentPresenter);

                presenters.Add(prevPage.Child as ContentPresenter);

            }

            else

            {

                presenters.Add(rightTopPage.Child as ContentPresenter);

                presenters.Add(nextPage.Child as ContentPresenter);

            }

            Debug.WriteLine("presenter0Name:" + presenters[0].Name);

            Debug.WriteLine("presenter1Name:" + presenters[1].Name);

            return presenters;

        }

        #endregion



        #region Crop

        /// <summary>

        /// 图形切割

        /// </summary>

        /// <param name="source"></param>

        /// <param name="x1"></param>

        /// <param name="y1"></param>

        /// <param name="x2"></param>

        /// <param name="y2"></param>

        /// <returns></returns>

        public WriteableBitmap Crop(WriteableBitmap source, int x1, int y1, int x2, int y2)

        {

            if (x1 >= x2 ||

                y1 >= y2 ||

                x1 < 0 ||

                y1 < 0 ||

                x2 < 0 ||

                y2 < 0 ||

                x1 > source.PixelWidth ||

                y1 > source.PixelHeight ||

                x2 > source.PixelWidth ||

                y2 > source.PixelHeight)

            {

                throw new ArgumentException();

            }



            //var buffer = source.PixelBuffer.GetPixels();

            var cw = x2 - x1;

            var ch = y2 - y1;

            var target = new WriteableBitmap(cw, ch);



            var croppedBytes =

                new byte[4 * cw * ch];

            var inputStream = source.PixelBuffer.AsStream();

            inputStream.Seek(4 * (source.PixelWidth * y1 + x1), SeekOrigin.Current);

            for (int i = 0; i < ch; i++)

            {

                inputStream.Read(croppedBytes, 4 * cw * i, 4 * cw);

                inputStream.Seek(4 * (source.PixelWidth - cw), SeekOrigin.Current);

            }



            var outputStream = target.PixelBuffer.AsStream();

            outputStream.Seek(0, SeekOrigin.Begin);

            outputStream.Write(croppedBytes, 0, croppedBytes.Length);

            target.Invalidate();



            return target;

        }

        #endregion



        #region IsHitVisible

        /// <summary>

        /// 禁止点击

        /// </summary>

        /// <param name="o"></param>

        private async void IsHitVisible(bool o)

        {

            await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () =>

            {

                this.grdContent.IsHitTestVisible = o;

                this.leftPage.IsHitTestVisible = o;

                this.rightPage.IsHitTestVisible = o;

                this.nextPage.IsHitTestVisible = o;

                this.prevPage.IsHitTestVisible = o;

                this.leftTopPage.IsHitTestVisible = o;

                this.rightTopPage.IsHitTestVisible = o;

            });

        }

        #endregion



        #region RefreshPageByStatus

        /// <summary>

        /// 翻页成功后刷新控件状态

        /// </summary>

        private void RefreshPageByStatus()

        {



            switch (Status)

            {

                case 0:

                    Canvas.SetZIndex(A, 2);

                    Canvas.SetZIndex(B, 2);

                    Canvas.SetZIndex(C, 0);

                    Canvas.SetZIndex(D, 0);

                    Canvas.SetZIndex(E, 2);

                    Canvas.SetZIndex(F, 2);

                    Grid.SetColumn(A, 1);

                    Grid.SetColumn(B, 1);

                    Grid.SetColumn(C, 1);

                    Grid.SetColumn(D, 2);

                    Grid.SetColumn(E, 2);

                    Grid.SetColumn(F, 2);

                    transA.TranslateX = 0;

                    transB.TranslateX = -offsetWidth;

                    transC.TranslateX = 0;

                    transD.TranslateX = 0;

                    transE.TranslateX = offsetWidth;

                    transF.TranslateX = 0;

                    ARect.Rect = new Rect(-this.A.ActualWidth, 0, this.A.ActualWidth, this.A.ActualHeight);

                    CRect.Rect = new Rect(0, 0, this.C.ActualWidth, this.C.ActualHeight);

                    DRect.Rect = new Rect(0, 0, this.D.ActualWidth, this.D.ActualHeight);

                    FRect.Rect = new Rect(this.F.ActualWidth, 0, this.F.ActualWidth, this.F.ActualHeight);

                    BRect.Rect = new Rect(this.B.ActualWidth, 0, this.B.ActualWidth, this.B.ActualHeight);

                    ERect.Rect = new Rect(-this.E.ActualWidth, 0, this.E.ActualWidth, this.E.ActualHeight);

                    nextPage = E;

                    prevPage = B;

                    leftPage = C;

                    rightPage = D;

                    leftTopPage = A;

                    rightTopPage = F;

                    nextTrans = transE;

                    prevTrans = transB;

                    //A.PointerPressed -= this.PointerPressed;

                    //B.PointerPressed -= this.PointerPressed;

                    //C.PointerPressed += this.PointerPressed;

                    //D.PointerPressed += this.PointerPressed;

                    break;

                case 1:

                    Canvas.SetZIndex(A, 2);

                    Canvas.SetZIndex(B, 2);

                    Canvas.SetZIndex(C, 2);

                    Canvas.SetZIndex(D, 2);

                    Canvas.SetZIndex(E, 0);

                    Canvas.SetZIndex(F, 0);

                    Grid.SetColumn(A, 2);

                    Grid.SetColumn(B, 2);

                    Grid.SetColumn(C, 1);

                    Grid.SetColumn(D, 1);

                    Grid.SetColumn(E, 1);

                    Grid.SetColumn(F, 2);

                    transA.TranslateX = offsetWidth;

                    transB.TranslateX = 0;

                    transC.TranslateX = 0;

                    transD.TranslateX = -offsetWidth;

                    transE.TranslateX = 0;

                    transF.TranslateX = 0;

                    ARect.Rect = new Rect(-this.A.ActualWidth, 0, this.A.ActualWidth, this.A.ActualHeight);

                    CRect.Rect = new Rect(-this.C.ActualWidth, 0, this.C.ActualWidth, this.C.ActualHeight);

                    DRect.Rect = new Rect(this.D.ActualWidth, 0, this.D.ActualWidth, this.D.ActualHeight);

                    FRect.Rect = new Rect(0, 0, this.F.ActualWidth, this.F.ActualHeight);

                    BRect.Rect = new Rect(this.B.ActualWidth, 0, this.B.ActualWidth, this.B.ActualHeight);

                    ERect.Rect = new Rect(0, 0, this.E.ActualWidth, this.E.ActualHeight);

                    nextPage = A;

                    prevPage = D;

                    leftPage = E;

                    rightPage = F;

                    leftTopPage = C;

                    rightTopPage = B;

                    nextTrans = transA;

                    prevTrans = transD;

                    //C.PointerPressed -= this.PointerPressed;

                    //D.PointerPressed -= this.PointerPressed;

                    //E.PointerPressed += this.PointerPressed;

                    //F.PointerPressed += this.PointerPressed;

                    break;

                case 2:

                    Canvas.SetZIndex(A, 0);

                    Canvas.SetZIndex(B, 0);

                    Canvas.SetZIndex(C, 2);

                    Canvas.SetZIndex(D, 2);

                    Canvas.SetZIndex(E, 2);

                    Canvas.SetZIndex(F, 2);

                    Grid.SetColumn(A, 1);

                    Grid.SetColumn(B, 2);

                    Grid.SetColumn(C, 2);

                    Grid.SetColumn(D, 2);

                    Grid.SetColumn(E, 1);

                    Grid.SetColumn(F, 1);

                    transA.TranslateX = 0;

                    transB.TranslateX = 0;

                    transC.TranslateX = offsetWidth;

                    transD.TranslateX = 0;

                    transE.TranslateX = 0;

                    transF.TranslateX = -offsetWidth;

                    ARect.Rect = new Rect(0, 0, this.A.ActualWidth, this.A.ActualHeight);

                    CRect.Rect = new Rect(-this.C.ActualWidth, 0, this.C.ActualWidth, this.C.ActualHeight);

                    DRect.Rect = new Rect(this.D.ActualWidth, 0, this.D.ActualWidth, this.D.ActualHeight);

                    FRect.Rect = new Rect(this.F.ActualWidth, 0, this.F.ActualWidth, this.F.ActualHeight);

                    BRect.Rect = new Rect(0, 0, this.B.ActualWidth, this.B.ActualHeight);

                    ERect.Rect = new Rect(-this.E.ActualWidth, 0, this.E.ActualWidth, this.E.ActualHeight);

                    nextPage = C;

                    prevPage = F;

                    leftPage = A;

                    rightPage = B;

                    leftTopPage = E;

                    rightTopPage = D;

                    nextTrans = transC;

                    prevTrans = transF;

                    //E.PointerPressed -= this.PointerPressed;

                    //F.PointerPressed -= this.PointerPressed;

                    //A.PointerPressed += this.PointerPressed;

                    //B.PointerPressed += this.PointerPressed;

                    break;

                default:

                    break;

            }

            stShadowSplitInnerLeft.Opacity = 0;

            stShadowSplitInnerRight.Opacity = 0;

            stShadowSplitOuterLeft.Opacity = 0;

            stShadowSplitOuterRight.Opacity = 0;

            outerRightTrans.TranslateX = 0;

            innerRightTrans.TranslateX = 0;

            outerLeftTrans.TranslateX = 0;

            innerLeftTrans.TranslateX = 0;

            marginLeftTrans.TranslateX = 0;

            marginRightTrans.TranslateX = 0;

            leftTopPage.Background = leftBrush;

            prevPage.Background = rightBrush;

            leftPage.Background = leftBrush;

            rightPage.Background = rightBrush;

            nextPage.Background = leftBrush;

            rightTopPage.Background = rightBrush;

        }

        #endregion



        #region GetCropBookBrush

        private async Task GetCropBrush()

        {

            if (null != this.BookBackgroundBrush)

            {

                var orginSource = this.BookBackgroundBrush.ImageSource as BitmapImage;

                if (!orginSource.UriSource.AbsolutePath.Equals(string.Empty))

                {

                    var uri = new Uri("ms-appx://" + orginSource.UriSource.AbsolutePath);

                    try

                    {

                        var file = await StorageFile.GetFileFromApplicationUriAsync(uri);

                        WriteableBitmap leftSource = new WriteableBitmap(Convert.ToInt32(offsetWidth * 2), Convert.ToInt32(offsetHeight));

                        await LoadAsync(leftSource, file);

                        WriteableBitmap rightSource = new WriteableBitmap(Convert.ToInt32(offsetWidth * 2), Convert.ToInt32(offsetHeight));

                        await LoadAsync(rightSource, file);

                        leftBrush = new ImageBrush();

                        rightBrush = new ImageBrush();

                        rightBrush.Stretch = Stretch.Fill;

                        leftBrush.Stretch = Stretch.Fill;

                        leftSource = Crop(leftSource, 0, 0, Convert.ToInt32(offsetWidth), Convert.ToInt32(offsetHeight));

                        leftBrush.ImageSource = leftSource;

                        rightSource = Crop(rightSource, Convert.ToInt32(offsetWidth), 0, Convert.ToInt32(offsetWidth * 2), Convert.ToInt32(offsetHeight));

                        rightBrush.ImageSource = rightSource;

                    }

                    catch

                    {

                    }

                }

            }

        }

        #endregion



        #region LoadWriteableBitmap

        public async Task<WriteableBitmap> LoadAsync(

            WriteableBitmap writeableBitmap,

           StorageFile storageFile)

        {

            using (var stream = await storageFile.OpenReadAsync())

            {

                await writeableBitmap.SetSourceAsync(

                    stream);

            }

            return writeableBitmap;

        }



        #endregion



        #region SetShadowOperacity

        private async void SetShadowOperacity(double pos, double pageWidth, bool direction)

        {

            var opacity = await Task.Run(() =>

            {

                double num = (pageWidth - pos) / 2.0;

                double num2 = Math.Abs((double)((pageWidth / 2.0) - num));

                return (1.0 * (1.0 - (num2 / (pageWidth / 2.0))));

            });

            if (direction)

            {

                this.stShadowSplitOuterLeft.Opacity = opacity;

                this.stShadowSplitInnerLeft.Opacity = opacity;

                this.stShadowMarginLeft.Opacity = opacity;

            }

            else

            {

                this.stShadowSplitOuterRight.Opacity = opacity;

                this.stShadowSplitInnerRight.Opacity = opacity;

                this.stShadowMarginRight.Opacity = opacity;

            }

        }

        #endregion

        #endregion

    }



    /// <summary>

    /// 抛出需要加载的项数据

    /// </summary>

    public class FlipLoadArgs : EventArgs

    {

        public readonly List<object> needItems;

        public readonly bool isNext;



        public FlipLoadArgs(List<object> _needItems, bool _isNext)

        {

            this.needItems = _needItems;

            this.isNext = _isNext;

        }

    }



    public class FlipEventArgs : EventArgs

    {

        public readonly bool isNext;



        public FlipEventArgs(bool _isNext)

        {

            this.isNext = _isNext;

        }

    }

}
<ResourceDictionary

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:WinRTXamlToolkit.Controls">



    <Style TargetType="local:FlipBookControl">

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="local:FlipBookControl">

                    <Grid 

                        x:Name="grdContent" 

                        Background="{TemplateBinding Background}">

                        <Grid.RowDefinitions>

                            <RowDefinition Height="30*"/>

                            <RowDefinition Height="750*"/>

                            <RowDefinition Height="30*"/>

                        </Grid.RowDefinitions>

                        <Grid.ColumnDefinitions>

                            <ColumnDefinition Width="50*"/>

                            <ColumnDefinition Width="600*"/>

                            <ColumnDefinition Width="600*"/>

                            <ColumnDefinition Width="50*"/>

                        </Grid.ColumnDefinitions>

                        <Image 

                            x:Name="bookContainer" 

                            Stretch="Fill" 

                            Canvas.ZIndex="2" 

                            Grid.ColumnSpan="4" 

                            IsHitTestVisible="False" 

                            Grid.RowSpan="3"/>

                        <Border 

                            Grid.Row="1" 

                            Grid.Column="1" 

                            BorderThickness="0"

                            x:Name="C">

                            <Border.Clip>

                                <RectangleGeometry x:Name="CRect">

                                </RectangleGeometry>

                            </Border.Clip>

                            <Border.RenderTransform>

                                <CompositeTransform x:Name="transC"></CompositeTransform>

                            </Border.RenderTransform>

                            <ContentPresenter x:Name="CPresenter" Style="{TemplateBinding ItemContainerStyle}"

                                              ContentTemplate="{TemplateBinding ItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"></ContentPresenter>

                        </Border>

                        <Border Grid.Row="1" Grid.Column="1" BorderThickness="0"

                            x:Name="D">

                            <Border.Clip>

                                <RectangleGeometry x:Name="DRect">

                                </RectangleGeometry>

                            </Border.Clip>

                            <Border.RenderTransform>

                                <CompositeTransform x:Name="transD"></CompositeTransform>

                            </Border.RenderTransform>

                            <ContentPresenter x:Name="DPresenter" Style="{TemplateBinding ItemContainerStyle}"

                                              ContentTemplate="{TemplateBinding ItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"></ContentPresenter>

                        </Border>

                        <Border Grid.Row="1" Grid.Column="1" BorderThickness="0"

                            x:Name="E">

                            <Border.Clip>

                                <RectangleGeometry x:Name="ERect">

                                </RectangleGeometry>

                            </Border.Clip>

                            <Border.RenderTransform>

                                <CompositeTransform x:Name="transE"/>

                            </Border.RenderTransform>

                            <ContentPresenter x:Name="EPresenter" Style="{TemplateBinding ItemContainerStyle}"

                                              ContentTemplate="{TemplateBinding ItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"></ContentPresenter>

                        </Border>

                        <Border Grid.Row="1" Grid.Column="1" BorderThickness="0"

                            x:Name="F">

                            <Border.Clip>

                                <RectangleGeometry x:Name="FRect">

                                </RectangleGeometry>

                            </Border.Clip>

                            <Border.RenderTransform>

                                <CompositeTransform x:Name="transF"></CompositeTransform>

                            </Border.RenderTransform>

                            <ContentPresenter x:Name="FPresenter" Style="{TemplateBinding ItemContainerStyle}"

                                              ContentTemplate="{TemplateBinding ItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"></ContentPresenter>

                        </Border>

                        <Border Grid.Row="1" Grid.Column="1" BorderThickness="0"

                            x:Name="A">

                            <Border.Clip>

                                <RectangleGeometry x:Name="ARect">

                                </RectangleGeometry>

                            </Border.Clip>

                            <Border.RenderTransform>

                                <CompositeTransform x:Name="transA"></CompositeTransform>

                            </Border.RenderTransform>

                            <ContentPresenter x:Name="APresenter" Style="{TemplateBinding ItemContainerStyle}"

                                              ContentTemplate="{TemplateBinding ItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"></ContentPresenter>

                        </Border>

                        <Border Grid.Row="1" Grid.Column="1"  BorderThickness="0"

                                x:Name="B">

                            <Border.Clip>

                                <RectangleGeometry x:Name="BRect">

                                </RectangleGeometry>

                            </Border.Clip>

                            <Border.RenderTransform>

                                <CompositeTransform x:Name="transB"/>

                            </Border.RenderTransform>

                            <ContentPresenter x:Name="BPresenter" Style="{TemplateBinding ItemContainerStyle}"

                                              ContentTemplate="{TemplateBinding ItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"></ContentPresenter>

                        </Border>

                        <StackPanel  Canvas.ZIndex="3"

                            x:Name="stShadowSplitOuterLeft" 

                            Width="43" 

                            Opacity="0"

                            Grid.Row="1"  

                            Grid.Column="1"

                            HorizontalAlignment="Left" Margin="-43,0,0,0" RenderTransformOrigin="0.5,0.5">

                            <StackPanel.RenderTransform>

                                <CompositeTransform x:Name="outerLeftTrans" TranslateX="0"/>

                            </StackPanel.RenderTransform>

                            <StackPanel.Background>

                                <LinearGradientBrush EndPoint="0,0" StartPoint="1,0">

                                    <GradientStop Color="#99000000"/>

                                    <GradientStop Color="Transparent" Offset="1"/>

                                </LinearGradientBrush>

                            </StackPanel.Background>

                        </StackPanel>

                        <StackPanel Canvas.ZIndex="3"

                            x:Name="stShadowSplitInnerLeft" 

                            Width="51" 

                            Opacity="0"

                            Grid.Row="1"  

                            Grid.Column="1"

                            HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5">

                            <StackPanel.RenderTransform>

                                <CompositeTransform x:Name="innerLeftTrans" TranslateX="0"/>

                            </StackPanel.RenderTransform>

                            <StackPanel.Background>

                                <LinearGradientBrush EndPoint="1,1" StartPoint="0,1">

                                    <GradientStop Color="#99000000"/>

                                    <GradientStop Color="#01FFFFFF" Offset="1"/>

                                </LinearGradientBrush>

                            </StackPanel.Background>

                        </StackPanel>

                        <StackPanel Canvas.ZIndex="3"

                            x:Name="stShadowSplitOuterRight" 

                            Width="43"

                            Opacity="0"

                            Grid.Row="1"  

                            Grid.Column="2"

                            HorizontalAlignment="Right" Margin="0,0,-43,0" RenderTransformOrigin="0.5,0.5">

                            <StackPanel.RenderTransform>

                                <CompositeTransform x:Name="outerRightTrans" TranslateX="0"/>

                            </StackPanel.RenderTransform>

                            <StackPanel.Background>

                                <LinearGradientBrush EndPoint="1,1" StartPoint="0,1">

                                    <GradientStop Color="#99000000"/>

                                    <GradientStop Color="Transparent" Offset="1"/>

                                </LinearGradientBrush>

                            </StackPanel.Background>

                        </StackPanel>

                        <StackPanel  Canvas.ZIndex="3"

                            x:Name="stShadowSplitInnerRight" 

                            Width="51" 

                            Opacity="0"

                            Grid.Row="1"  

                            Grid.Column="2"

                            HorizontalAlignment="Right" RenderTransformOrigin="0.5,0.5">

                            <StackPanel.RenderTransform>

                                <CompositeTransform x:Name="innerRightTrans" TranslateX="0"/>

                            </StackPanel.RenderTransform>

                            <StackPanel.Background>

                                <LinearGradientBrush EndPoint="0,0" StartPoint="1,0">

                                    <GradientStop Color="#99000000"/>

                                    <GradientStop Color="#01FFFFFF" Offset="1"/>

                                </LinearGradientBrush>

                            </StackPanel.Background>

                        </StackPanel>

                        <StackPanel x:Name="stShadowMarginLeft" Width="30" HorizontalAlignment="Left"

                    Opacity="0" Grid.Row="1" Grid.Column="1" Canvas.ZIndex="3">

                            <StackPanel.RenderTransform>

                                <CompositeTransform x:Name="marginLeftTrans" TranslateX="0"/>

                            </StackPanel.RenderTransform>

                            <StackPanel.Background>

                                <LinearGradientBrush EndPoint="1,1" StartPoint="0,1">

                                    <GradientStop Color="#99000000"/>

                                    <GradientStop Color="Transparent" Offset="1"/>

                                </LinearGradientBrush>

                            </StackPanel.Background>

                        </StackPanel>

                        <StackPanel x:Name="stShadowMarginRight" Width="30" HorizontalAlignment="Right"

                    Opacity="0" Grid.Row="1" Grid.Column="2" Canvas.ZIndex="3">

                            <StackPanel.RenderTransform>

                                <CompositeTransform x:Name="marginRightTrans" TranslateX="0"/>

                            </StackPanel.RenderTransform>

                            <StackPanel.Background>

                                <LinearGradientBrush EndPoint="0,0" StartPoint="1,0">

                                    <GradientStop Color="#99000000"/>

                                    <GradientStop Color="Transparent" Offset="1"/>

                                </LinearGradientBrush>

                            </StackPanel.Background>

                        </StackPanel>

                    </Grid>

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>

</ResourceDictionary>


 

 

Sample: 使用方法

  <local:FlipBookControl x:Name="fbc"  Speed="10"
                                            ItemTemplate="{StaticResource BookTemplate}">
            <local:FlipBookControl.Background>
                <ImageBrush ImageSource="ms-appx:///Assets/bookbox-hori.png"/>
            </local:FlipBookControl.Background>
            <local:FlipBookControl.BookBackgroundBrush>
                <ImageBrush ImageSource="ms-appx:///Assets/bg-7.jpg"/>
            </local:FlipBookControl.BookBackgroundBrush>
        </local:FlipBookControl>

支持ItemsSource 数据源 以及ItemTemplate Binding

 

DisposeAction  和RestoreItem 2个依赖项 请在使用前填写。用于释放图片流 以及恢复 源

 

欢迎讨论,分享经验,以及更优的方法。


 

 

你可能感兴趣的:(源码)