WPF-Kreis Fortschrittsbalken
Möchte ich ersetzen den regulären ProgressBar
mit Kreis ein und nach dem Schuß die Suche hier im forum habe ich gefunden, was ich will.
CircularProgressBar.XAML
<Grid>
<Path x:Name="pathRoot" Stroke="{Binding SegmentColor, ElementName=userControl}"
StrokeThickness="{Binding StrokeThickness, ElementName=userControl}" HorizontalAlignment="Left" VerticalAlignment="Top">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure x:Name="pathFigure">
<PathFigure.Segments>
<PathSegmentCollection>
<ArcSegment x:Name="arcSegment" SweepDirection="Clockwise" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
</Grid>
CircularProgressBar.cs:
public partial class CircularProgressBar : UserControl
{
public CircularProgressBar()
{
InitializeComponent();
Angle = (Percentage * 360) / 100;
RenderArc();
}
public int Radius
{
get { return (int)GetValue(RadiusProperty); }
set { SetValue(RadiusProperty, value); }
}
public Brush SegmentColor
{
get { return (Brush)GetValue(SegmentColorProperty); }
set { SetValue(SegmentColorProperty, value); }
}
public int StrokeThickness
{
get { return (int)GetValue(StrokeThicknessProperty); }
set { SetValue(StrokeThicknessProperty, value); }
}
public double Percentage
{
get { return (double)GetValue(PercentageProperty); }
set { SetValue(PercentageProperty, value); }
}
public double Angle
{
get { return (double)GetValue(AngleProperty); }
set { SetValue(AngleProperty, value); }
}
//Using a DependencyProperty as the backing store for Percentage. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PercentageProperty =
DependencyProperty.Register("Percentage", typeof(double), typeof(CircularProgressBar), new PropertyMetadata(65d, new PropertyChangedCallback(OnPercentageChanged)));
//Using a DependencyProperty as the backing store for StrokeThickness. This enables animation, styling, binding, etc...
public static readonly DependencyProperty StrokeThicknessProperty =
DependencyProperty.Register("StrokeThickness", typeof(int), typeof(CircularProgressBar), new PropertyMetadata(5, new PropertyChangedCallback(OnThicknessChanged)));
//Using a DependencyProperty as the backing store for SegmentColor. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SegmentColorProperty =
DependencyProperty.Register("SegmentColor", typeof(Brush), typeof(CircularProgressBar), new PropertyMetadata(new SolidColorBrush(Colors.Red), new PropertyChangedCallback(OnColorChanged)));
//Using a DependencyProperty as the backing store for Radius. This enables animation, styling, binding, etc...
public static readonly DependencyProperty RadiusProperty =
DependencyProperty.Register("Radius", typeof(int), typeof(CircularProgressBar), new PropertyMetadata(25, new PropertyChangedCallback(OnPropertyChanged)));
//Using a DependencyProperty as the backing store for Angle. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AngleProperty =
DependencyProperty.Register("Angle", typeof(double), typeof(CircularProgressBar), new PropertyMetadata(120d, new PropertyChangedCallback(OnPropertyChanged)));
private static void OnColorChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
CircularProgressBar circle = sender as CircularProgressBar;
circle.set_Color((SolidColorBrush)args.NewValue);
}
private static void OnThicknessChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
CircularProgressBar circle = sender as CircularProgressBar;
circle.set_tick((int)args.NewValue);
}
private static void OnPercentageChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
CircularProgressBar circle = sender as CircularProgressBar;
if (circle.Percentage > 100) circle.Percentage = 100;
circle.Angle = (circle.Percentage * 360) / 100;
}
private static void OnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
CircularProgressBar circle = sender as CircularProgressBar;
circle.RenderArc();
}
public void set_tick(int n)
{
pathRoot.StrokeThickness = n;
}
public void set_Color(SolidColorBrush n)
{
pathRoot.Stroke = n;
}
public void RenderArc()
{
Point startPoint = new Point(Radius, 0);
Point endPoint = ComputeCartesianCoordinate(Angle, Radius);
endPoint.X += Radius;
endPoint.Y += Radius;
pathRoot.Width = Radius * 2 + StrokeThickness;
pathRoot.Height = Radius * 2 + StrokeThickness;
pathRoot.Margin = new Thickness(StrokeThickness, StrokeThickness, 0, 0);
bool largeArc = Angle > 180.0;
Size outerArcSize = new Size(Radius, Radius);
pathFigure.StartPoint = startPoint;
if (startPoint.X == Math.Round(endPoint.X) && startPoint.Y == Math.Round(endPoint.Y))
endPoint.X -= 0.01;
arcSegment.Point = endPoint;
arcSegment.Size = outerArcSize;
arcSegment.IsLargeArc = largeArc;
}
private Point ComputeCartesianCoordinate(double angle, double radius)
{
//convert to radians
double angleRad = (Math.PI / 180.0) * (angle - 90);
double x = radius * Math.Cos(angleRad);
double y = radius * Math.Sin(angleRad);
return new Point(x, y);
}
}
MainWindow.xaml:
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center"
SegmentColor="#FF878889" StrokeThickness="25" Percentage="100" />
<DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center"
Percentage="{Binding Value, ElementName=slider}" SegmentColor="#026873" StrokeThickness="25" />
</Grid>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center"/>
</StackPanel>
<Slider x:Name="slider" Grid.Row="1" Maximum="100" Value="60" />
</Grid>
Und das Ergebnis:
http://s21.postimg.org/xymj8k4pz/image.png
Also nach dem kopieren fügen Sie den gleichen code in meiner Lösung und läuft alles was ich sehe ist nur die Slider
ohne die Circle Bar
, das ist mein code:
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="530,303,114,303">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center"
SegmentColor="#FF878889" StrokeThickness="8" Percentage="100" />
<DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center"
Percentage="{Binding Value, ElementName=slider}" SegmentColor="#026873" StrokeThickness="8" />
</Grid>
</StackPanel>
<Slider x:Name="slider" Maximum="100" Value="20" Width="200" Margin="597,185,227,495" />
Mache ich etwas falsch ?
- Pro-Tipp: Wenn Sie möchten, dass der Benutzer Kontrolle zu skalieren, mit seinen übergeordneten container, legen Sie das Raster und den Pfad innerhalb einer Viewbox.
- Toller post! Danke!
InformationsquelleAutor Verint Verint | 2015-05-31
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie wahrscheinlich verpasst
x:Name="userControl"
imUserControl
definition:Diese zeigt auf, wie das animieren der Kreis.
Wenn
AnimateProgressCircle
wahr ist, wird der "busy" - Kreis dreht sich, sonst wird es unsichtbar.Vorteile
<Viewbox>
, es ist immer perfekt, die Größe des übergeordneten Containers.Testen
Getestet auf:
WPF
.NET 4.5
+.NET 4.6.1
Win7 x64
Visual Studio 2015 + Update 2
Zu testen, legen Sie
DataContext="{Binding RelativeSource={RelativeSource Self}}"
im<Window>
tag, dann verwenden Sie diesen code hinter.Sollten Sie sehen, der Kreis pause für 2 Sekunden, dann animieren Sie Sie für 4 Sekunden, dann stoppen.
Links, die half, mit dieser Lösung