internal void Draw() { if (!IsControlLaoded) return; //No cache for you gauge :( kill and redraw please foreach (var child in Canvas.Children.Cast<UIElement>() .Where(x => !Equals(x, Stick) && !(x is AngularSection) && !(x is PieSlice)).ToArray()) Canvas.Children.Remove(child); Wedge = Wedge > 360 ? 360 : (Wedge < 0 ? 0 : Wedge); var fromAlpha = (360-Wedge)*.5; var toAlpha = 360 - fromAlpha; var d = ActualWidth < ActualHeight ? ActualWidth : ActualHeight; Stick.Height = d*.5*.8; Stick.Width = Stick.Height*.2; Canvas.SetLeft(Stick, ActualWidth*.5 - Stick.Width*.5); Canvas.SetTop(Stick, ActualHeight*.5 - Stick.Height*.9); var ticksHi = d*.5; var ticksHj = d*.47; var labelsHj = d*.44; foreach (var section in Sections) { PieSlice slice; section.Owner = this; if (!Slices.TryGetValue(section, out slice)) { slice = new PieSlice(); Slices[section] = slice; } var p = (Canvas)section.Parent; if (p != null) p.Children.Remove(section); Canvas.Children.Add(section); var ps = (Canvas)slice.Parent; if (ps != null) ps.Children.Remove(slice); Canvas.Children.Add(slice); } UpdateSections(); for (var i = FromValue; i <= ToValue; i += TicksStep) { var alpha = LinearInterpolation(fromAlpha, toAlpha, FromValue, ToValue, i) + 90; var tick = new Line { X1 = ActualWidth*.5 + ticksHi*Math.Cos(alpha*Math.PI/180), X2 = ActualWidth*.5 + ticksHj*Math.Cos(alpha*Math.PI/180), Y1 = ActualHeight*.5 + ticksHi*Math.Sin(alpha*Math.PI/180), Y2 = ActualHeight*.5 + ticksHj*Math.Sin(alpha*Math.PI/180) }; Canvas.Children.Add(tick); tick.SetBinding(Shape.StrokeProperty, new Binding {Path = new PropertyPath(TicksForegroundProperty), Source = this}); tick.SetBinding(Shape.StrokeThicknessProperty, new Binding { Path = new PropertyPath(TicksStrokeThicknessProperty), Source = this }); } for (var i = FromValue; i <= ToValue; i += LabelsStep) { var alpha = LinearInterpolation(fromAlpha, toAlpha, FromValue, ToValue, i) + 90; var tick = new Line { X1 = ActualWidth*.5 + ticksHi*Math.Cos(alpha*Math.PI/180), X2 = ActualWidth*.5 + labelsHj*Math.Cos(alpha*Math.PI/180), Y1 = ActualHeight*.5 + ticksHi*Math.Sin(alpha*Math.PI/180), Y2 = ActualHeight*.5 + labelsHj*Math.Sin(alpha*Math.PI/180) }; Canvas.Children.Add(tick); var label = new TextBlock { Text = LabelFormatter(i) }; label.SetBinding(EffectProperty, new Binding {Path = new PropertyPath(LabelsEffectProperty), Source = this}); Canvas.Children.Add(label); label.UpdateLayout(); Canvas.SetLeft(label, alpha < 270 ? tick.X2 : (Math.Abs(alpha - 270) < 4 ? tick.X2 - label.ActualWidth*.5 : tick.X2 - label.ActualWidth)); Canvas.SetTop(label, tick.Y2); tick.SetBinding(Shape.StrokeProperty, new Binding { Path = new PropertyPath(TicksForegroundProperty), Source = this }); tick.SetBinding(Shape.StrokeThicknessProperty, new Binding { Path = new PropertyPath(TicksStrokeThicknessProperty), Source = this }); } MoveStick(); }
public Gauge() { Canvas = new Canvas {ClipToBounds = true}; Content = Canvas; PieBack = new PieSlice(); Pie = new PieSlice(); TitleTextBlock = new TextBlock(); MeasureTextBlock = new TextBlock(); LeftLabel = new TextBlock(); RightLabel = new TextBlock(); Canvas.Children.Add(PieBack); Canvas.Children.Add(Pie); Canvas.Children.Add(TitleTextBlock); Canvas.Children.Add(MeasureTextBlock); Canvas.Children.Add(RightLabel); Canvas.Children.Add(LeftLabel); Panel.SetZIndex(PieBack, 0); Panel.SetZIndex(Pie, 1); Canvas.SetBinding(WidthProperty, new Binding {Path = new PropertyPath(WidthProperty), Source = this}); Canvas.SetBinding(HeightProperty, new Binding {Path = new PropertyPath(HeightProperty), Source = this}); PieBack.SetBinding(Shape.FillProperty, new Binding {Path = new PropertyPath(GaugeBackgroundProperty), Source = this}); PieBack.SetBinding(Shape.StrokeThicknessProperty, new Binding {Path = new PropertyPath(StrokeThicknessProperty), Source = this}); PieBack.SetBinding(Shape.StrokeProperty, new Binding {Path = new PropertyPath(StrokeProperty), Source = this}); Pie.SetBinding(Shape.StrokeThicknessProperty, new Binding { Path = new PropertyPath(StrokeThicknessProperty), Source = this }); Pie.Stroke = Brushes.Transparent; TitleTextBlock.SetBinding(TextBlock.TextProperty, new Binding { Path = new PropertyPath(TitleProperty), Source = this }); SetValue(GaugeBackgroundProperty, new SolidColorBrush(Color.FromRgb(21, 101, 191)) {Opacity = .1}); SetValue(StrokeThicknessProperty, 0d); SetValue(StrokeProperty, new SolidColorBrush(Color.FromRgb(222, 222, 222))); SetValue(ToColorProperty, Color.FromRgb(100, 180, 245)); SetValue(FromColorProperty, Color.FromRgb(21, 101, 191)); SetValue(MinHeightProperty, 50d); SetValue(MinWidthProperty, 80d); SetValue(AnimationsSpeedProperty, TimeSpan.FromMilliseconds(800)); MeasureTextBlock.FontWeight = FontWeights.Bold; IsNew = true; SizeChanged += (sender, args) => { IsChartInitialized = true; Update(); }; }