2015-06-06 2 views
0

Я WPF применение и Circle ProgressBar:WPF, как поставить метку в середине круга

<Grid> 
     <Path x:Name="pathRoot" Stroke="{Binding SegmentColor, ElementName=userControl}" 
       StrokeThickness="{Binding StrokeThickness, ElementName=userControl}" 
       HorizontalAlignment="Left" VerticalAlignment="Top" Height="100" Width="100"> 
      <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> 

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)); 

    // 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))); 

    // 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(60, 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 OnPercentageChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) 
    { 
     CircularProgressBar circle = sender as CircularProgressBar; 
     circle.Angle = (circle.Percentage * 360)/100; 
    } 

    private static void OnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) 
    { 
     CircularProgressBar circle = sender as CircularProgressBar; 
     circle.RenderArc(); 
    } 

    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); 
    } 
} 

Это мой XAML с моим CircleProgressBar:

<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="54,507,54,75" Grid.Column="1" Height="138"> 
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Height="153" Width="155"> 
     <DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center" 
     SegmentColor="#FF878889" StrokeThickness="10" Percentage="100" /> 
     <DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center" 
     Percentage="33" SegmentColor="#FF5591E8" StrokeThickness="10" /> 
    </Grid> 
</StackPanel> 

Внутри этого контроллера я найти Label, которые показывают мой процент ProgressBar, но эта метка не всегда посередине на circle

<Label Name="lblCircleProgress" Content="0%" Margin="116,561,100,127" Foreground="White" VerticalAlignment="Center" Grid.Column="1" /> 

Так что мой вопрос заключается в том, как реализовать этот ярлык, чтобы он стал посередине моего Circle все время после изменения процента?

ответ

1

Упростите свою сетку - и поместите все в нее.

Таким образом, все будет горизонтально и вертикально находиться в одном и том же визуальном контексте.

<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Height="153" Width="155"> 
    <DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center" 
             SegmentColor="#FF878889" StrokeThickness="10" Percentage="100" /> 
    <DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center" 
             SegmentColor="#FF5591E8" StrokeThickness="10" Percentage="33" />    
    <Label Name="lblCircleProgress" Content="0%" Foreground="White" 
            HorizontalAlignment="Center" VerticalAlignment="Center" /> 
</Grid> 
0

Добавьте его в сетку, удалите это поле и установите HorizontalAlignment в центр. Я вижу, что у вас уже установлен набор VerticalAlignment, поэтому он должен работать, и вы должны увидеть его в центре сетки, и учитывая, что ваш CircularProgressBar тоже находится внутри Grid, он должен выглядеть так, как ожидалось.

Смежные вопросы