/// <summary> /// Start from scratch. This will repair any animation positioning errors. /// </summary> private void RedrawCollection() { if (_canvas == null) { return; } _list_of_visuals.Clear(); _canvas.Children.Clear(); if (this.PageStack == null) { return; } // Create the SingleCrumb classes for (int i = 0; i < this.PageStack.Count; i++) { SmartPage page = this.PageStack[i]; bool isfirst = (i == 0); var control = new SingleCrumb { FirstItem = isfirst, Text = page.PageCaption }; // First Add to the visual tree _canvas.Children.Add(control); // Second create the the Visual BreadCrumbVisual item = new BreadCrumbVisual(control); // Third, add to the collection of visuals _list_of_visuals.Add(item); } float offset = CalculateOffset(); foreach (var bcv in _list_of_visuals) { bcv.Offset = (float)offset; bcv.CalculatedOffset = (float)offset; offset += (float)bcv.Width; } }
/// <summary> /// The calculated offset for the first child element inside the Canvas. /// </summary> //private float _canvas_offset = 0.0f; private void PageStack_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Add) { if (e.NewItems.Count != 1) { return; } SmartPage page = e.NewItems[0] as SmartPage; bool isfirst = (_canvas.Children.Count == 0); var control = new SingleCrumb { FirstItem = isfirst, Text = page.PageCaption }; // First, add to the visual tree _canvas.Children.Add(control); // Add the Element to the visual tree // Second, create the visual BreadCrumbVisual bcv = new BreadCrumbVisual(control); float new_offset = CalculateOffset((float)bcv.Width); ShiftAllElementsToOffset(new_offset, miliseconds_delay: 0); // was 0 // The total width before adding the new element. double total_width = CalcTotalWidth(); // Third, add to the visuals collection _list_of_visuals.Add(bcv); bcv.Offset = new_offset + (float)total_width; bcv.CalculatedOffset = new_offset + (float)total_width; var anim = bcv.Compositor.CreateSpringScalarAnimation(); anim.Period = TimeSpan.FromMilliseconds(200); // was 50 anim.DelayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay; anim.DelayTime = TimeSpan.FromMilliseconds(200); anim.DampingRatio = 0.88f; // 0.2f anim.StopBehavior = AnimationStopBehavior.SetToFinalValue; anim.InitialValue = (float)_canvas.ActualWidth; anim.FinalValue = new_offset + (float)total_width; //var scopedBatch = bcv.Compositor.CreateScopedBatch(CompositionBatchTypes.Animation); //scopedBatch.Completed += ScopedBatch_Completed; bcv.Visual.StartAnimation("Offset.X", anim); //scopedBatch.End(); //bcv.Offset = (float)total_width - (overflow+(float)bcv.Width); } else if (e.Action == NotifyCollectionChangedAction.Remove) { if (e.OldItems.Count != 1) { return; } SmartPage page_data = e.OldItems[0] as SmartPage; BreadCrumbVisual bcv = _list_of_visuals[_list_of_visuals.Count - 1]; var anim = bcv.Compositor.CreateSpringScalarAnimation(); anim.Period = TimeSpan.FromSeconds(0.50); // was 0.05 //anim.DelayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay; //anim.DelayTime = TimeSpan.FromMilliseconds(100); anim.DampingRatio = 0.88f; // 0.2f anim.StopBehavior = AnimationStopBehavior.SetToFinalValue; anim.InitialValue = bcv.CalculatedOffset; anim.FinalValue = (float)_canvas.ActualWidth; Action action = () => { _canvas.Children.Remove(bcv.Element); // remove from Visual Tree }; _list_of_visuals.Remove(bcv); CompositionScopedBatch scopedBatch = bcv.Compositor.CreateScopedBatch(CompositionBatchTypes.Animation); scopedBatch.Comment = _counter.ToString(); _counter++; _dictionary.Add(scopedBatch.Comment, action); scopedBatch.Completed += ScopedBatch_Completed; bcv.Visual.StartAnimation("Offset.X", anim); scopedBatch.End(); //bcv.Offset = (float)total_width - (overflow+(float)bcv.Width); float new_offset = CalculateOffset(); // The offset might have changed as we removed the last item. ShiftAllElementsToOffset(new_offset, miliseconds_delay: 1200); // was 300 } else { RedrawCollection(); } }