c# 實現(xiàn)圓形的進度條(ProgressBar)
在我們實際的工作中可能經(jīng)常使用到圓形的進度條,但是這是怎么實現(xiàn)的呢?其實這只不過是修改了一下ProgressBar的模板,我們在下面的代碼中我們將ProgressBar的Value值綁定到Border的Background上面,并且使用了一個ValueToProcessConverter的轉換器進行相應地轉換,這里重點介紹一下這個轉換器
<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>
下面介紹這部分的源碼,并做簡要的分析:
首先,獲取ProgressBar.Value,然后再獲取ConverterParameter=250這個值,通過這兩個值就能確定畫的圓環(huán)的大小和ProgressBar顯示的值,然后我們再調用DrawBrush(arg, 100, radius, radius, Thickness)這個函數(shù)來進行繪制,具體代碼如下:
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; }
這里需要注意的是絕不能直接實例化 DrawingContext;但可以通過某些方法(例如 DrawingGroup.Open 和 DrawingVisual.RenderOpen)獲取繪圖上下文。我們這里是使用DrawingGroup.Open的方法來進行相應的繪圖,然后在里面調用里DrawingGeometry這個函數(shù),在這個函數(shù)中開始繪制一些DrawEllipse和DrawGeometry,在這個函數(shù)中我們講解一下FormattedText 這個類,使用 FormattedText 對象可以繪制多行文本,且可以單獨對該文本中的每個字符設置格式。
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ù)角度獲取坐標 /// </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個坐標畫出扇形 /// </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ù)當前值和最大值獲取扇形 /// </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> /// 畫扇形 /// </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ù)當前值和最大值畫出進度條 /// </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# 實現(xiàn)圓形的進度條(ProgressBar)的詳細內容,更多關于c# 實現(xiàn)進度條的資料請關注腳本之家其它相關文章!
相關文章
用C#+Selenium+ChromeDriver爬取網(wǎng)頁(模擬真實的用戶瀏覽行為)
這篇文章主要介紹了用C#+Selenium+ChromeDriver爬取網(wǎng)頁,模擬真實的用戶瀏覽行為,需要的小伙伴可以參考一下2022-01-01Entity?Framework映射TPH、TPT、TPC與繼承類
這篇文章介紹了Entity?Framework映射TPH、TPT、TPC與繼承類,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06C#操作數(shù)據(jù)庫總結(vs2005+sql2005)
C#操作數(shù)據(jù)庫總結,每次做項目都會用到數(shù)據(jù)庫,對數(shù)據(jù)庫的操作都是糊里糊涂從書里找代碼用。通過昨天晚上與今天早上的努力,把數(shù)據(jù)庫的操作整理了一下,下面把整理結果做個小結2012-09-09C#使用ILGenerator動態(tài)生成函數(shù)的簡單代碼
這篇文章主要介紹了C#使用ILGenerator動態(tài)生成函數(shù)的簡單代碼,需要的朋友可以參考下2017-08-08