private static Storyboard CreateStoryboard( FrameworkElement target, DependencyProperty animatingDependencyProperty, string propertyPath, ref object toValue, TimeSpan durationTimeSpan, IEasingFunction easingFunction) { object fromValue = target.GetValue(animatingDependencyProperty); double fromDoubleValue; double toDoubleValue; DateTime fromDateTime; DateTime toDateTime; Storyboard storyBoard = new Storyboard(); Storyboard.SetTarget(storyBoard, target); Storyboard.SetTargetProperty(storyBoard, new PropertyPath(propertyPath)); if ((fromValue != null && toValue != null)) { if (ValueHelper.TryConvert(fromValue, out fromDoubleValue) && ValueHelper.TryConvert(toValue, out toDoubleValue)) { DoubleAnimation doubleAnimation = new DoubleAnimation(); #if SILVERLIGHT doubleAnimation.EasingFunction = easingFunction; #endif doubleAnimation.Duration = durationTimeSpan; doubleAnimation.To = ValueHelper.ToDouble(toValue); toValue = doubleAnimation.To; storyBoard.Children.Add(doubleAnimation); } else if (ValueHelper.TryConvert(fromValue, out fromDateTime) && ValueHelper.TryConvert(toValue, out toDateTime)) { ObjectAnimationUsingKeyFrames keyFrameAnimation = new ObjectAnimationUsingKeyFrames(); keyFrameAnimation.Duration = durationTimeSpan; long intervals = (long)(durationTimeSpan.TotalSeconds * KeyFramesPerSecond); if (intervals < 2L) { intervals = 2L; } IEnumerable <TimeSpan> timeSpanIntervals = ValueHelper.GetTimeSpanIntervalsInclusive(durationTimeSpan, intervals); IEnumerable <DateTime> dateTimeIntervals = ValueHelper.GetDateTimesBetweenInclusive(fromDateTime, toDateTime, intervals); IEnumerable <DiscreteObjectKeyFrame> keyFrames = EnumerableFunctions.Zip( dateTimeIntervals, timeSpanIntervals, (dateTime, timeSpan) => new DiscreteObjectKeyFrame() { Value = dateTime, KeyTime = timeSpan }); foreach (DiscreteObjectKeyFrame keyFrame in keyFrames) { keyFrameAnimation.KeyFrames.Add(keyFrame); toValue = keyFrame.Value; } storyBoard.Children.Add(keyFrameAnimation); } } if (storyBoard.Children.Count == 0) { ObjectAnimationUsingKeyFrames keyFrameAnimation = new ObjectAnimationUsingKeyFrames(); DiscreteObjectKeyFrame endFrame = new DiscreteObjectKeyFrame() { Value = toValue, KeyTime = new TimeSpan(0, 0, 0) }; keyFrameAnimation.KeyFrames.Add(endFrame); storyBoard.Children.Add(keyFrameAnimation); } return(storyBoard); }
protected override Size MeasureOverride(Size availableSize) { double offset = 0.0; if (Children.Count > 0) { Size totalSize = new Size(double.PositiveInfinity, double.PositiveInfinity); foreach (UIElement child in this.Children) { child.Measure(totalSize); } Func <UIElement, double> lengthSelector = null; Func <UIElement, double> offsetSelector = null; if (Orientation == Orientation.Horizontal) { lengthSelector = child => GetCorrectedDesiredSize(child).Width; offsetSelector = child => GetCorrectedDesiredSize(child).Height; } else { lengthSelector = child => GetCorrectedDesiredSize(child).Height; offsetSelector = child => GetCorrectedDesiredSize(child).Width; } IEnumerable <IGrouping <int, UIElement> > priorityGroups = from child in Children.CastWrapper <UIElement>() group child by GetPriority(child) into priorityGroup select priorityGroup; ActualMinimumDistanceBetweenChildren = (from priorityGroup in priorityGroups let orderedElements = (from element in priorityGroup orderby GetCenterCoordinate(element) ascending select element).ToList() where orderedElements.Count >= 2 select (EnumerableFunctions.Zip( orderedElements, orderedElements.Skip(1), (leftElement, rightElement) => { double halfLeftLength = lengthSelector(leftElement) / 2; double leftCenterCoordinate = GetCenterCoordinate(leftElement); double halfRightLength = lengthSelector(rightElement) / 2; double rightCenterCoordinate = GetCenterCoordinate(rightElement); return((rightCenterCoordinate - halfRightLength) - (leftCenterCoordinate + halfLeftLength)); })) .Min()) .MinOrNullable() ?? MinimumDistanceBetweenChildren; IEnumerable <int> priorities = Children .CastWrapper <UIElement>() .Select(GetPriority).Distinct().OrderBy(priority => priority).ToList(); PriorityOffsets = new Dictionary <int, double>(); foreach (int priority in priorities) { PriorityOffsets[priority] = 0.0; } IEnumerable <(int Previous, int Next)> priorityPairs = EnumerableFunctions.Zip(priorities, priorities.Skip(1), (previous, next) => (previous, next)); foreach (var(Previous, Next) in priorityPairs) { IEnumerable <UIElement> currentPriorityChildren = Children.CastWrapper <UIElement>().Where(child => GetPriority(child) == Previous).ToList(); IEnumerable <Range <double> > currentPriorityRanges = GetRanges(currentPriorityChildren, lengthSelector); IEnumerable <UIElement> nextPriorityChildren = Children.CastWrapper <UIElement>().Where(child => GetPriority(child) == Next).ToList(); IEnumerable <Range <double> > nextPriorityRanges = GetRanges(nextPriorityChildren, lengthSelector); bool intersects = (from currentPriorityRange in currentPriorityRanges from nextPriorityRange in nextPriorityRanges select currentPriorityRange.IntersectsWith(nextPriorityRange)) .Any(value => value); if (intersects) { double maxCurrentPriorityChildOffset = currentPriorityChildren .Select(child => offsetSelector(child)) .MaxOrNullable() ?? 0.0; offset += maxCurrentPriorityChildOffset + OffsetPadding; } PriorityOffsets[Next] = offset; } offset = (Children .CastWrapper <UIElement>() .GroupBy(GetPriority) .Select( group => group .Select(child => PriorityOffsets[group.Key] + offsetSelector(child)) .MaxOrNullable())) .Where(num => num.HasValue) .Select(num => num.Value) .MaxOrNullable() ?? 0.0; } if (Orientation == Orientation.Horizontal) { return(new Size(0, offset)); } else { return(new Size(offset, 0)); } }