/// <summary> /// 筛选出没有在当前 RectanglesCanvas 面板中显示的、日期更久远的记录, /// 然后根据这些记录在 StackCanvas 面板中生成新的方块面板,接着在这些 /// 新生成的面板中着色日期更久远的记录。 /// </summary> private void ExtendStackCanvasByFilterOldRecorders(List <StatistTotalByDateTime> oldRecorders, Rectangle earliestRectangle, int canvasOrdinal = 1) { if (oldRecorders != null && oldRecorders.Count > 0) { Canvas oldRectanglesCanvas = new Canvas() { Name = $"OldRectanglesCanvas_{canvasOrdinal}" }; Rectangle oldRect = this.RectanglesLayout(oldRectanglesCanvas, DatetimeParser.ParseExpressToDateTime(earliestRectangle.Name, DateMode.DateWithSlash).AddDays(-1)); oldRectanglesCanvas.Loaded += (object sender, RoutedEventArgs e) => { Canvas canvas = sender as Canvas; foreach (var item in canvas.Children) { if (item is TextBlock tag) { Debug.WriteLine($"tag.ActualWidth: {tag.ActualWidth}"); } } }; this.StackCanvas.Children.Insert(0, oldRectanglesCanvas); List <StatistTotalByDateTime> newOldRecorders = EarlierThanEarliestRectangle(oldRecorders, oldRect); ExtendStackCanvasByFilterOldRecorders(newOldRecorders, oldRect, canvasOrdinal + 1); } // 扩展结束后,给每个 RectanglesCanvas 附加进度条 else { foreach (Canvas canvas in this.StackCanvas.Children) { ProgressBoard.SlideOn(canvas, new ProgressBoard()); } } }
/// <summary> /// 重置方块的颜色和闪烁状态,以及所有的 RectanglesCanvas 面板布局。 /// </summary> private void ResetRectangleAndCanvasLayout() { if (_rectangleRegisteTable.Count > 0) { foreach (var rect in _rectangleRegisteTable) { rect.Fill = new SolidColorBrush(LightGray); } // 重置方块颜色之后要紧接着清空该表 _rectangleRegisteTable.Clear(); // 停止所有闪烁状态的方块 foreach (var rect in Blink.BlinkedRectangles) { Blink.StopBlink(rect.Value.rectangle); } // 对 StackCanvas 重新洗牌 this.StackCanvas.Children.Clear(); this.CurrentRectanglesCanvas = new Canvas() { Name = "CurrentRectanglesCanvas" }; this.CurrentRectanglesCanvas.Loaded += (object sender, RoutedEventArgs e) => ProgressBoard.SlideOn(CurrentRectanglesCanvas, new ProgressBoard()); this.StackCanvas.Children.Add(this.CurrentRectanglesCanvas); this._earliestRectangle = this.RectanglesLayout(this.CurrentRectanglesCanvas, new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day)); } else { ProgressBoard.SlideOn(CurrentRectanglesCanvas, new ProgressBoard()); } }
/// <summary> /// 根据记录给每个方块面板中的方块绘制颜色。 /// </summary> /// <param name="entries">分级后条目列表</param> /// <param name="haveProgressBoard">是否开启进度条面板,true 为开启,反之不开启</param> private void DrawRectangleColor(TioSalamanca[] entries, bool haveProgressBoard) { IDictionary <int, SolidColorBrush> colorDic = ClassifyColorByLevelScore(entries.Length); Windows.Foundation.IAsyncAction action = Windows.System.Threading.ThreadPool.RunAsync( async(asyncAction) => { GusFring gusFring = new GusFring(entries, colorDic); await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync( priority: Windows.UI.Core.CoreDispatcherPriority.Normal, agileCallback: () => { foreach (Canvas canvas in this.StackCanvas.Children) { if (haveProgressBoard) { ProgressBoard.SlideOn(canvas, new ProgressBoard()); } foreach (var item in canvas.Children) // 过滤掉非 Rectangle 的元素(比如 ProgressBoard 和 DateTag) { if (item is Rectangle rect) { #if DEBUG (int Level, BigInteger Total, SolidColorBrush Color) = gusFring[rect.Name]; rect.Fill = Color; ToolTip toolTip = new ToolTip { Content = rect.Name + $" Level:{Level} Total:{Total} Color:{Color}" }; ToolTipService.SetToolTip(rect, toolTip); #endif #if DEBUG == false rect.Fill = gusFring[rect.Name]; ToolTip toolTip = new ToolTip { Content = rect.Name }; ToolTipService.SetToolTip(rect, toolTip); #endif _rectangleRegisteTable.Add(rect); } } } }); }); }
/// <summary> /// 播放进度条模块动画 /// </summary> /// <param name="parentCanvas">承载进度条模块的容器</param> /// <param name="progressBoard">进度条模块</param> public static void SlideOn(Canvas parentCanvas, ProgressBoard progressBoard) { progressBoard._progressBoard = progressBoard.CreateProgressBoard("ProgressBoard"); if (parentCanvas.Children.Contains(progressBoard._progressBoard) == false) { parentCanvas.Children.Add(progressBoard._progressBoard); } HorizontalCenterOnCanvas(progressBoard._progressBoard, parentCanvas); progressBoard._startStoryboard = new Storyboard(); KeyTime startTime = KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 0)); KeyTime endTime = KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 300)); DoubleAnimationUsingKeyFrames slideAnimationUsingKeyFrames = new DoubleAnimationUsingKeyFrames(); slideAnimationUsingKeyFrames.KeyFrames.Add(new LinearDoubleKeyFrame() { Value = Canvas.GetTop(progressBoard._progressBoard), KeyTime = startTime }); slideAnimationUsingKeyFrames.KeyFrames.Add(new LinearDoubleKeyFrame() { Value = (parentCanvas.Height - progressBoard._progressBoard.Height) / 2, KeyTime = endTime }); /* * 把 startStoryboard.Completed 事件的 Handler 作为局部函数能让它的作用域捕获 ProgressBoard._progressBoard, * 从而使得 Completed 事件能够在动画播放结束时为 parentCanvas 移除 ProgressBoard._progressBoard */ void StartStoryboard_Completed(object sender, object e) { parentCanvas.Children.Remove(progressBoard._progressBoard); } progressBoard._startStoryboard.Completed += StartStoryboard_Completed; progressBoard._startStoryboard.Children.Add(slideAnimationUsingKeyFrames); Storyboard.SetTarget(slideAnimationUsingKeyFrames, progressBoard._progressBoard); Storyboard.SetTargetName(slideAnimationUsingKeyFrames, progressBoard._progressBoard.Name); Storyboard.SetTargetProperty(slideAnimationUsingKeyFrames, "(Canvas.Top)"); progressBoard._startStoryboard.Begin(); }
/// <summary> /// 取消进度条模块 /// </summary> /// <param name="parentCanvas">承载进度条模块的容器</param> /// <param name="progressBoard">进度条模块</param> public static void CancelOn(Canvas parentCanvas, ProgressBoard progressBoard) { parentCanvas.Children.Remove(progressBoard._progressBoard); }