WPF径向进度条/仪表(即电池表)

我正在开发适用于Windows 8.1和Windows Phone 8.1的Unified健身应用。 理想情况下,其中一个核心视图将包含每日进度表。 问题是我无法想出实际的仪表或仪表。 我想要的只是一个径向进度条或类似于Windows Phone商店中常见电池应用中的电池电量表/米的东西。 据我所知,WPF / VS 2013不提供开箱即用的这种组件。 我知道Telerik和其他一些第三方提供类似的东西,但我更喜欢使用开源的东西或自己构建它。

有没有人知道与.NET 4.5和WPF一起使用的较新的开源组件,或者有关于如何构建自己的组件的示例?

到目前为止,我发现的与此链接类似: WPF的量表

但我希望使用类似的东西: 在此处输入图像描述

你可以自己建造类似的东西。 首先,你需要一个弧:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Shapes; using System.Windows.Media; using System.Windows; ... public class Arc : Shape { public double StartAngle { get { return (double)GetValue(StartAngleProperty); } set { SetValue(StartAngleProperty, value); } } // Using a DependencyProperty as the backing store for StartAngle. This enables animation, styling, binding, etc... public static readonly DependencyProperty StartAngleProperty = DependencyProperty.Register("StartAngle", typeof(double), typeof(Arc), new UIPropertyMetadata(0.0, new PropertyChangedCallback(UpdateArc))); public double EndAngle { get { return (double)GetValue(EndAngleProperty); } set { SetValue(EndAngleProperty, value); } } // Using a DependencyProperty as the backing store for EndAngle. This enables animation, styling, binding, etc... public static readonly DependencyProperty EndAngleProperty = DependencyProperty.Register("EndAngle", typeof(double), typeof(Arc), new UIPropertyMetadata(90.0, new PropertyChangedCallback(UpdateArc))); //This controls whether or not the progress bar goes clockwise or counterclockwise public SweepDirection Direction { get { return (SweepDirection) GetValue(DirectionProperty); } set { SetValue(DirectionProperty, value);} } public static readonly DependencyProperty DirectionProperty = DependencyProperty.Register("Direction", typeof (SweepDirection), typeof (Arc), new UIPropertyMetadata(SweepDirection.Clockwise)); //rotate the start/endpoint of the arc a certain number of degree in the direction //ie. if you wanted it to be at 12:00 that would be 270 Clockwise or 90 counterclockwise public double OriginRotationDegrees { get { return (double) GetValue(OriginRotationDegreesProperty); } set { SetValue(OriginRotationDegreesProperty, value);} } public static readonly DependencyProperty OriginRotationDegreesProperty = DependencyProperty.Register("OriginRotationDegrees", typeof (double), typeof (Arc), new UIPropertyMetadata(270.0, new PropertyChangedCallback(UpdateArc))); protected static void UpdateArc(DependencyObject d, DependencyPropertyChangedEventArgs e) { Arc arc = d as Arc; arc.InvalidateVisual(); } protected override Geometry DefiningGeometry { get { return GetArcGeometry(); } } protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) { drawingContext.DrawGeometry(null, new Pen(Stroke, StrokeThickness), GetArcGeometry()); } private Geometry GetArcGeometry() { Point startPoint = PointAtAngle(Math.Min(StartAngle, EndAngle), Direction); Point endPoint = PointAtAngle(Math.Max(StartAngle, EndAngle), Direction); Size arcSize = new Size(Math.Max(0, (RenderSize.Width - StrokeThickness) / 2), Math.Max(0, (RenderSize.Height - StrokeThickness) / 2)); bool isLargeArc = Math.Abs(EndAngle - StartAngle) > 180; StreamGeometry geom = new StreamGeometry(); using (StreamGeometryContext context = geom.Open()) { context.BeginFigure(startPoint, false, false); context.ArcTo(endPoint, arcSize, 0, isLargeArc, Direction, true, false); } geom.Transform = new TranslateTransform(StrokeThickness / 2, StrokeThickness / 2); return geom; } private Point PointAtAngle(double angle, SweepDirection sweep) { double translatedAngle = angle + OriginRotationDegrees; double radAngle = translatedAngle * (Math.PI / 180); double xr = (RenderSize.Width - StrokeThickness) / 2; double yr = (RenderSize.Height - StrokeThickness) / 2; double x = xr + xr * Math.Cos(radAngle); double y = yr * Math.Sin(radAngle); if (sweep == SweepDirection.Counterclockwise) { y = yr - y; } else { y = yr + y; } return new Point(x, y); } } 

这个弧有一个StartAngle和一个EndAngle。 要将进度条的进度转换为这些角度,您需要一个转换器:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; ... public class ProgressToAngleConverter : System.Windows.Data.IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { double progress = (double)values[0]; System.Windows.Controls.ProgressBar bar = values[1] as System.Windows.Controls.ProgressBar; return 359.999 * (progress / (bar.Maximum - bar.Minimum)); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } 

好的。 这就是你需要的一切。 现在你可以编写你的XAML了。 那可能是这样的:

                 

现在只需使用ProgressBarStyle ,修改它并将其应用到您喜欢的任何进度条。

最后,你会得到这样的东西。 玩得开心!

编辑:您需要以下参考(我建议您,只需创建一个新的空WPF项目):

  • WindowsBase
  • PresentationCore
  • PresentationFramework

编辑:为了控制旋转方向以及开始进度的位置,我添加了两个依赖属性:Direction OriginRotationDegrees

在此处输入图像描述