c# 實(shí)現(xiàn)圓形的進(jìn)度條(ProgressBar)
在我們實(shí)際的工作中可能經(jīng)常使用到圓形的進(jìn)度條,但是這是怎么實(shí)現(xiàn)的呢?其實(shí)這只不過(guò)是修改了一下ProgressBar的模板,我們?cè)谙旅娴拇a中我們將ProgressBar的Value值綁定到Border的Background上面,并且使用了一個(gè)ValueToProcessConverter的轉(zhuǎn)換器進(jìn)行相應(yīng)地轉(zhuǎn)換,這里重點(diǎn)介紹一下這個(gè)轉(zhuǎn)換器
<ProgressBar Name="pb" Minimum="0" Maximum="100" > <ProgressBar.Template> <ControlTemplate TargetType="ProgressBar"> <Border Background="{TemplateBinding Value, Converter={StaticResource ValueToProcessConverter}, ConverterParameter=250}"/> </ControlTemplate> </ProgressBar.Template> </ProgressBar>
下面介紹這部分的源碼,并做簡(jiǎn)要的分析:
首先,獲取ProgressBar.Value,然后再獲取ConverterParameter=250這個(gè)值,通過(guò)這兩個(gè)值就能確定畫(huà)的圓環(huán)的大小和ProgressBar顯示的值,然后我們?cè)僬{(diào)用DrawBrush(arg, 100, radius, radius, Thickness)這個(gè)函數(shù)來(lái)進(jìn)行繪制,具體代碼如下:
private Brush DrawBrush(double value, double maxValue, double radiusX, double radiusY, double thickness) { DrawingGroup drawingGroup = new DrawingGroup(); DrawingContext drawingContext = drawingGroup.Open(); DrawingGeometry(drawingContext, value, maxValue, radiusX, radiusY, thickness); DrawingBrush brush = new DrawingBrush(drawingGroup); return brush; }
這里需要注意的是絕不能直接實(shí)例化 DrawingContext;但可以通過(guò)某些方法(例如 DrawingGroup.Open 和 DrawingVisual.RenderOpen)獲取繪圖上下文。我們這里是使用DrawingGroup.Open的方法來(lái)進(jìn)行相應(yīng)的繪圖,然后在里面調(diào)用里DrawingGeometry這個(gè)函數(shù),在這個(gè)函數(shù)中開(kāi)始繪制一些DrawEllipse和DrawGeometry,在這個(gè)函數(shù)中我們講解一下FormattedText 這個(gè)類(lèi),使用 FormattedText 對(duì)象可以繪制多行文本,且可以單獨(dú)對(duì)該文本中的每個(gè)字符設(shè)置格式。
private void DrawingGeometry(DrawingContext drawingContext, double value, double maxValue, double radiusX, double radiusY, double thickness) { drawingContext.DrawEllipse(null, new Pen(EllipseBrush, thickness), centerPoint, radiusX, radiusY); drawingContext.DrawGeometry(NormalBrush, new Pen(), GetGeometry(value, maxValue, radiusX, radiusY, thickness)); FormattedText formatWords = new FormattedText(percentString, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, SuccessRateTypeface, SuccessRateFontSize, NormalBrush); Point startPoint = new Point(centerPoint.X - formatWords.Width / 2, centerPoint.Y - formatWords.Height / 2 - SuccessRateFontCorrectionValue); drawingContext.DrawText(formatWords, startPoint); drawingContext.Close(); }
public class ValueToProcessConverter : IValueConverter { readonly double Thickness = 20; private Point centerPoint; private double radius; readonly SolidColorBrush NormalBrush = new SolidColorBrush(Colors.White); readonly SolidColorBrush EllipseBrush = new SolidColorBrush(Color.FromRgb(107, 132, 165)); string percentString; private static readonly Typeface SuccessRateTypeface; private const int SuccessRateFontSize = 65; readonly double SuccessRateFontCorrectionValue = 12; static ValueToProcessConverter() { SuccessRateTypeface = new Typeface(new FontFamily("MSYH"), new FontStyle(), new FontWeight(), new FontStretch()); } public ValueToProcessConverter() { } public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value is double && !string.IsNullOrEmpty((string)parameter)) { double arg = (double)value; double width = double.Parse((string)parameter); radius = width / 2; centerPoint = new Point(radius, radius); return DrawBrush(arg, 100, radius, radius, Thickness); } else { throw new ArgumentException(); } } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } /// <summary> /// 根據(jù)角度獲取坐標(biāo) /// </summary> /// <param name="CenterPoint"></param> /// <param name="r"></param> /// <param name="angel"></param> /// <returns></returns> private Point GetPointByAngel(Point CenterPoint, double r, double angel) { Point p = new Point(); p.X = Math.Sin(angel * Math.PI / 180) * r + CenterPoint.X; p.Y = CenterPoint.Y - Math.Cos(angel * Math.PI / 180) * r; return p; } /// <summary> /// 根據(jù)4個(gè)坐標(biāo)畫(huà)出扇形 /// </summary> /// <param name="bigFirstPoint"></param> /// <param name="bigSecondPoint"></param> /// <param name="smallFirstPoint"></param> /// <param name="smallSecondPoint"></param> /// <param name="bigRadius"></param> /// <param name="smallRadius"></param> /// <param name="isLargeArc"></param> /// <returns></returns> private Geometry DrawingArcGeometry(Point bigFirstPoint, Point bigSecondPoint, Point smallFirstPoint, Point smallSecondPoint, double bigRadius, double smallRadius, bool isLargeArc) { PathFigure pathFigure = new PathFigure { IsClosed = true }; pathFigure.StartPoint = bigFirstPoint; pathFigure.Segments.Add( new ArcSegment { Point = bigSecondPoint, IsLargeArc = isLargeArc, Size = new Size(bigRadius, bigRadius), SweepDirection = SweepDirection.Clockwise }); pathFigure.Segments.Add(new LineSegment { Point = smallSecondPoint }); pathFigure.Segments.Add( new ArcSegment { Point = smallFirstPoint, IsLargeArc = isLargeArc, Size = new Size(smallRadius, smallRadius), SweepDirection = SweepDirection.Counterclockwise }); PathGeometry pathGeometry = new PathGeometry(); pathGeometry.Figures.Add(pathFigure); return pathGeometry; } /// <summary> /// 根據(jù)當(dāng)前值和最大值獲取扇形 /// </summary> /// <param name="value"></param> /// <param name="maxValue"></param> /// <returns></returns> private Geometry GetGeometry(double value, double maxValue, double radiusX, double radiusY, double thickness) { bool isLargeArc = false; double percent = value / maxValue; percentString = string.Format("{0}%", Math.Round(percent * 100, 2)); double angel = percent * 360D; if (angel > 180) isLargeArc = true; double bigR = radiusX + thickness / 2; double smallR = radiusX - thickness / 2; Point firstpoint = GetPointByAngel(centerPoint, bigR, 0); Point secondpoint = GetPointByAngel(centerPoint, bigR, angel); Point thirdpoint = GetPointByAngel(centerPoint, smallR, 0); Point fourpoint = GetPointByAngel(centerPoint, smallR, angel); return DrawingArcGeometry(firstpoint, secondpoint, thirdpoint, fourpoint, bigR, smallR, isLargeArc); } /// <summary> /// 畫(huà)扇形 /// </summary> /// <param name="drawingContext"></param> /// <param name="value"></param> /// <param name="maxValue"></param> /// <param name="radiusX"></param> /// <param name="radiusY"></param> /// <param name="thickness"></param> private void DrawingGeometry(DrawingContext drawingContext, double value, double maxValue, double radiusX, double radiusY, double thickness) { drawingContext.DrawEllipse(null, new Pen(EllipseBrush, thickness), centerPoint, radiusX, radiusY); drawingContext.DrawGeometry(NormalBrush, new Pen(), GetGeometry(value, maxValue, radiusX, radiusY, thickness)); FormattedText formatWords = new FormattedText(percentString, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, SuccessRateTypeface, SuccessRateFontSize, NormalBrush); Point startPoint = new Point(centerPoint.X - formatWords.Width / 2, centerPoint.Y - formatWords.Height / 2 - SuccessRateFontCorrectionValue); drawingContext.DrawText(formatWords, startPoint); drawingContext.Close(); } /// <summary> /// 根據(jù)當(dāng)前值和最大值畫(huà)出進(jìn)度條 /// </summary> /// <param name="value"></param> /// <param name="maxValue"></param> /// <returns></returns> private Brush DrawBrush(double value, double maxValue, double radiusX, double radiusY, double thickness) { DrawingGroup drawingGroup = new DrawingGroup(); DrawingContext drawingContext = drawingGroup.Open(); DrawingGeometry(drawingContext, value, maxValue, radiusX, radiusY, thickness); DrawingBrush brush = new DrawingBrush(drawingGroup); return brush; } }
以上就是c# 實(shí)現(xiàn)圓形的進(jìn)度條(ProgressBar)的詳細(xì)內(nèi)容,更多關(guān)于c# 實(shí)現(xiàn)進(jìn)度條的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- C#實(shí)現(xiàn)炫酷啟動(dòng)圖-動(dòng)態(tài)進(jìn)度條效果
- C# Oracle批量插入數(shù)據(jù)進(jìn)度條的實(shí)現(xiàn)代碼
- C#自定義音樂(lè)播放器進(jìn)度條
- C#實(shí)現(xiàn)帶百分比的進(jìn)度條功能示例
- C#實(shí)現(xiàn)帶進(jìn)度條的ListView
- C# Winform下載文件并顯示進(jìn)度條的實(shí)現(xiàn)代碼
- c#根據(jù)文件大小顯示文件復(fù)制進(jìn)度條實(shí)例
- c#進(jìn)度條 progressBar 使用方法的小例子
- C#中常使用進(jìn)度條的代碼
- Winform 實(shí)現(xiàn)進(jìn)度條彈窗和任務(wù)控制
- C#使用winform實(shí)現(xiàn)進(jìn)度條效果
相關(guān)文章
用C#+Selenium+ChromeDriver爬取網(wǎng)頁(yè)(模擬真實(shí)的用戶(hù)瀏覽行為)
這篇文章主要介紹了用C#+Selenium+ChromeDriver爬取網(wǎng)頁(yè),模擬真實(shí)的用戶(hù)瀏覽行為,需要的小伙伴可以參考一下2022-01-01Entity?Framework映射TPH、TPT、TPC與繼承類(lèi)
這篇文章介紹了Entity?Framework映射TPH、TPT、TPC與繼承類(lèi),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06C#實(shí)現(xiàn)網(wǎng)頁(yè)畫(huà)圖功能
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)網(wǎng)頁(yè)畫(huà)圖功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03C#操作數(shù)據(jù)庫(kù)總結(jié)(vs2005+sql2005)
C#操作數(shù)據(jù)庫(kù)總結(jié),每次做項(xiàng)目都會(huì)用到數(shù)據(jù)庫(kù),對(duì)數(shù)據(jù)庫(kù)的操作都是糊里糊涂從書(shū)里找代碼用。通過(guò)昨天晚上與今天早上的努力,把數(shù)據(jù)庫(kù)的操作整理了一下,下面把整理結(jié)果做個(gè)小結(jié)2012-09-09C#使用ILGenerator動(dòng)態(tài)生成函數(shù)的簡(jiǎn)單代碼
這篇文章主要介紹了C#使用ILGenerator動(dòng)態(tài)生成函數(shù)的簡(jiǎn)單代碼,需要的朋友可以參考下2017-08-08C#中將DataTable轉(zhuǎn)換成CSV文件的方法
DataTable用于在.net項(xiàng)目中,用于緩存數(shù)據(jù),DataTable表示內(nèi)存中數(shù)據(jù)的一個(gè)表,在.net項(xiàng)目中運(yùn)用C#將DataTable轉(zhuǎn)化為CSV文件,接下來(lái)通過(guò)本文給大家提供一個(gè)通用的方法,感興趣的朋友可以參考下2016-10-10C#實(shí)現(xiàn)線(xiàn)程安全的簡(jiǎn)易日志記錄方法
這篇文章主要介紹了C#實(shí)現(xiàn)線(xiàn)程安全的簡(jiǎn)易日志記錄方法,比較實(shí)用的功能,需要的朋友可以參考下2014-08-08