WPF 控制項庫——仿製Windows10的進度條

来源:https://www.cnblogs.com/nabian/archive/2018/07/10/9288576.html
-Advertisement-
Play Games

一、其實有現成的 先來看看Windows10進度條的兩種模式: 網上有不少介紹仿製Windows10進度條的文章,也都實現了不錯的效果。而我再開一文的原因是覺得如果在這基礎上添加一些功能,比如圓點的數量,圓點的大小等等,效果可能會更好一些。接觸過UWP的朋友應該知道,其框架中自帶了進度條控制項,以 P ...


一、其實有現成的

  先來看看Windows10進度條的兩種模式:

 

 

  網上有不少介紹仿製Windows10進度條的文章,也都實現了不錯的效果。而我再開一文的原因是覺得如果在這基礎上添加一些功能,比如圓點的數量,圓點的大小等等,效果可能會更好一些。接觸過UWP的朋友應該知道,其框架中自帶了進度條控制項,以 ProgressRing 為例,通過Blend,我們可以獲取到控制項的XAML,以下是部分截圖:

 

  粗略一看,只要稍作修改便能用到WPF中——我們幾乎可以什麼都不做!

 

二、添加功能

  如果要更改圓點的數量,圓點的大小或者圓點的移動速度,我們該如何實現呢?繼承章節一中的XAML,並根據所需調整模板就顯得太麻煩了,這會讓我們的樣式文件顯得臃腫不堪,所以採用純粹的C#代碼來實現它或許比較明智。不過之前的XAML也不是一無是處,至少它給出了環形進度條的關鍵幀動畫的構成,這些信息對我們來說很重要,免去了我們自己去分析的步驟。

  現在我們的主要工作就是讓寫死的關鍵幀能夠通過屬性靈活配置,所以我們可能需要先編碼一份進度條的基類( LoadingBase ),以提取兩種類型進度條的共性。基類中定義8個屬性,分別是 IsRunning 、 DotCount 、 DotInterval 、 DotBorderBrush 、 DotBorderThickness 、 DotDiameter 、 DotSpeed 、 DotDelayTime ,它們的含義已經是自註釋的,不必贅述。而在環形進度條中,還有另外兩個屬性: DotOffSet 和 NeedHidden ,分別表示圓點整體的位置偏移和在運動中是否需要隱藏圓點。

 

三、關鍵幀動畫

  最後一步就是用C#代碼實現關鍵幀動畫,不過得先有米才能做飯,故而需要先創建圓點:

 1 protected Ellipse CreateEllipse(int index)
 2         {
 3             var ellipse = new Ellipse();
 4             ellipse.SetBinding(WidthProperty, new Binding("DotDiameter") {Source = this});
 5             ellipse.SetBinding(HeightProperty, new Binding("DotDiameter") {Source = this});
 6             ellipse.SetBinding(Shape.FillProperty, new Binding("Foreground") {Source = this});
 7             ellipse.SetBinding(Shape.StrokeThicknessProperty, new Binding("DotBorderThickness") {Source = this});
 8             ellipse.SetBinding(Shape.StrokeProperty, new Binding("DotBorderBrush") {Source = this});
 9             return ellipse;
10         }

  上面的方法在進度條基類中實現,僅僅是用相關的屬性初始化了我們的原材料:圓點。由於環形進度條在X、Y軸方向都有移動,所以為了方便,我們可以考慮在圓點外面再包一層 Border 作為看不見的殼,我們將圓點與殼底部對齊,現在只要讓殼繞中心旋轉就基本實現了目標,下麵是環形進度條1個點到5個點帶殼的示意圖:

  想一想,如果沒有這層殼,我們又有什麼替代方法,這些方法是否都是極為方便的?可能沒有這層殼,就需要去琢磨怎麼改變圓點的 RenderTransformOrigin ,好讓它們看起來都是圍繞一個點旋轉的,即使改變了進度條整體的尺寸。套殼的代碼如下:

 1 private Border CreateBorder(int index)
 2         {
 3             var ellipse = CreateEllipse(index);
 4             ellipse.HorizontalAlignment = HorizontalAlignment.Center;
 5             ellipse.VerticalAlignment = VerticalAlignment.Bottom;
 6             var rt = new RotateTransform
 7             {
 8                 Angle = -DotInterval * index
 9             };
10             var myTransGroup = new TransformGroup();
11             myTransGroup.Children.Add(rt);
12             var border = new Border
13             {
14                 RenderTransformOrigin = new Point(0.5, 0.5),
15                 RenderTransform = myTransGroup,
16                 Child = ellipse,
17                 Visibility = NeedHidden ? Visibility.Collapsed : Visibility.Visible
18             };
19             border.SetBinding(WidthProperty, new Binding("Width") { Source = this });
20             border.SetBinding(HeightProperty, new Binding("Height") { Source = this });
21 
22             return border;
23         }

  套殼代碼除了套殼和相關的初始化,最重要的是19和20行的寬高綁定,這是讓圓點旋轉中心始終唯一的關鍵。有了以上的準備,我們終於可以開始for迴圈了:

 1 //定義動畫
 2 Storyboard = new Storyboard
 3 {
 4     RepeatBehavior = RepeatBehavior.Forever
 5 };
 6 
 7 for (var i = 0; i < DotCount; i++)
 8 {
 9     //在這裡創建圓點  
10 }

  下麵就是最核心的關鍵幀動畫,通過之前用Blend提取出來的XAML,我們可以看到它使用了 SplineDoubleKeyFrame ,這會涉及三次貝塞爾曲線的控制點,考慮到易用性,我們會用 LinearDoubleKeyFrame 和 EasingDoubleKeyFrame 代替。在XAML中我們最關心的關鍵字應該是角度,在時間片的哪部分,圓點應該在哪兒,而又在什麼時候,圓點應該會消失,我們只要隨意截取兩個點的關鍵幀就能獲得以上所有信息:

 

  上面兩張分別是圓點1和2透明度和位置的關鍵幀截圖,通過兩個點我們完全可以推斷所有點。出於個人喜好,我將透明度替換成了 Visibility 的切換,所以還會引入 DiscreteObjectKeyFrame 。篇幅原因,我們直接總結分析結果:

  • 一開始所有點都是顯示的,但是位置不同,從點1的-110度開始,角度逐個減6;
  • 點1開始運動後,0.167秒(1/6秒)後點2開始運動,所以各點動畫延遲時間為1/6秒(這裡不太能確定是否和圓點數量有關);
  • 以點1為例,旋轉角度隨時間變化圖如下:

  從上面7張圖中可以看出,在一次迴圈中點1是這樣運動的:減速、勻速、加速、減速、勻速、加速,而且與之對應的角度位置也給出了,最後水到渠成,環形進度條就完成了。

 

四、截圖

  通過設置不同的屬性,可以實現不同的效果:

  

 

五、源碼

  本文所討論的進度條源碼已經在github開源:https://github.com/NaBian/HandyControl


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 編程語言Python語法簡單,代碼可讀性高,不僅適合初學者學習,而且崗位需求大,薪資一路也是水漲船高,即使是剛畢業的應屆畢業生,薪資也在12500元每月。 因此,很多程式員很樂意去研究這門編程語言,那麼有哪些值得收藏的Python書單呢? Python入門 《“笨辦法”學Python(第3版)》 本 ...
  • 關於死鎖,估計很多程式員都碰到過,並且有時候這種情況出現之後的問題也不是非常好排查,下麵整理的就是自己對死鎖的認識,以及通過一個簡單的例子來來接死鎖的發生,自己是做python開發的,但是對於死鎖的理解一直是一種模糊的概念,也是想過這次的整理更加清晰的認識這個概念。 用來理解的例子是一個簡單的生產者 ...
  • 用過手機QQ就知道,點擊一個圖片會彈出一個小功能,那就是提取圖片中的文字。非常方便實用,那麼很難實現嗎? 利用Python提取圖片中的文字信息,只需要一行代碼就能搞定! 當然,這是吹牛皮的,但是真正的Python代碼也就第4行,說是一行代碼搞定也沒錯。 示例: 效果 儘管運行Python代碼後也有幾 ...
  • `System.IO.Pipelines`是一個新的庫,旨在簡化在.NET中執行高性能IO的過程。它是一個依賴.NET Standard的庫, 適用於所有.NET實現 。 Pipelines誕生於.NET Core團隊,為使Kestrel成為業界最快的Web伺服器之一。最初從作為Kestrel內部的 ...
  • 在上一篇net core的文章中已經講過如何從零開始搭建WebSocket。 今天聊聊ASP.NET的文件結構,如何用自己的目錄結構組織項目里的文件。 如果用Visual Studio(VS)嚮導或dotnet嚮導,會為我們生成一套MVC通用框架。不過,對於一個要求更特殊或更小的項目,它可能並不如我 ...
  • 三、查詢集合 1.找出List<Product>列表中符合特定條件的所有元素 C#1.1 查詢步驟:迴圈,if判斷,列印 product類 1 using System.Collections; 2 using System.ComponentModel; 3 4 namespace Chapter ...
  • 二、排序Product 1.按名稱對產品進行排序,以特定順序顯示一個列表的最簡單方式就是先將列表排序,再遍歷並顯示其中的項。 C#1.1 使用IComparer對ArrayList進行排序 product類 1 using System.Collections; 2 using System.Com ...
  • 之前由於一個項目的需要(簡單說一下,一個網頁游戲,裁判的頁面點擊開始按鈕,玩家便可以開始游戲),研究了很久,最終一個同事跟我推薦了SignalR。距離項目結束已經有一段時間了,再來回顧一下SignalR的簡單實現吧。 1.什麼 SignalR? ASP.NET SignalR 是為.NET 開發者提 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...