답변
두 가지 옵션이 있습니다. 첫 번째 방법은 ProgressBar
템플릿 템플릿입니다. 이것은 조금 까다로운 것으로 판명되었습니다. 나는 use an attached ViewModel to achieve the required effect하는 방법을 설명하는 블로그 게시물을 썼습니다.
다른 방법은 처음부터 직접 컨트롤을 만드는 것입니다. 당신은 다음 작업을 수행 할 수 있습니다 :
- 는
- 이 새로운 가치, 최대 및 최소 종속성 속성을 추가 새 사용자 컨트롤을 만듭니다.
- Angle 속성을 계산하려면 사용자 정의 컨트롤에서 값, 최대 및 최소 속성 변경 이벤트를 처리하십시오.
- 두 개의 '파이 조각'을 코드 뒤에 넣고 (this post 참조) UI에 추가하십시오.
그리고 왜 기존 ProgressBar를 템플릿으로 만들지 않습니까? WPF의 CustomControls는이 목적을 위해 정확하게 보이지 않습니다. 당신이 필요로 할 때 그것을 재사용하지 않을 때 흠 잡을 데없는 컨트롤을 만드는 것의 모든 허점을 UI의 다른 표현으로 가져 왔습니까? – NVM
@NVM, 원칙적으로 동의하지만 일부 코드가 필요할 것입니다. 순수 XAML을 사용하는 WPF의 기본 제공 셰이프를 사용하여 잘라낸 호를 만드는 쉬운 방법은 없습니다. 익스프레션 블렌드 SDK를 사용하고 있다면 아크 셰이프가있어서 쉽게 처리 할 수 있습니다. 그래서 OP는 아마도 파이를 그릴 수있는 일종의 컨트롤을 만들어야 할 것입니다. 그러나 진행 막대의 구현은이 새로운 "파이"컨트롤을 사용하는 템플릿이어야합니다. – Josh
내 수정 된 답변보기 그게 아니라 당신이 당신이 제안하는 방식으로 그것을 할 수 없습니다. 나는 일반적으로 당신이 떠날 수있는 것처럼 작은 코드로 작성하는 것이 더 좋다고 생각한다. – NVM
ValueConverter
님을 보았습니까? TemplateBinding
을 사용하여 템플릿의 Value 속성에 바인딩하고 적절한 값 변환기를 사용하여 Circs 진행률 막대에 유용한 값을 변경할 수 있습니다.
편집 : 템플릿에서
:
이 원 노란색 채우기 추가합니다.
주황색으로 다른 원을 추가하십시오.
- 3에 리턴 지오메트리 2의 원형 클립 2
첨가 원을 위해 (아마도 이용 호 세그먼트)은 클립핑 기하학을 반환하는 값 변환 (또는 다중 값 변환)을 사용한다.
Downvoter가 내 답장을 돌려줍니다.
다소 까다 롭지 만 불가능하지는 않습니다. 다음은 부드러운 애니메이션을 사용하여 구현 한 것입니다. CircularProgressBar를 만들려면 값 변환기를 사용해야합니다.
CircularProgressBar.cs
public partial class CircularProgressBar : ProgressBar
{
public CircularProgressBar()
{
this.ValueChanged += CircularProgressBar_ValueChanged;
}
void CircularProgressBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
CircularProgressBar bar = sender as CircularProgressBar;
double currentAngle = bar.Angle;
double targetAngle = e.NewValue/bar.Maximum * 359.999;
DoubleAnimation anim = new DoubleAnimation(currentAngle, targetAngle, TimeSpan.FromMilliseconds(500));
bar.BeginAnimation(CircularProgressBar.AngleProperty, anim, HandoffBehavior.SnapshotAndReplace);
}
public double Angle
{
get { return (double)GetValue(AngleProperty); }
set { SetValue(AngleProperty, value); }
}
// 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(0.0));
public double StrokeThickness
{
get { return (double)GetValue(StrokeThicknessProperty); }
set { SetValue(StrokeThicknessProperty, value); }
}
// Using a DependencyProperty as the backing store for StrokeThickness. This enables animation, styling, binding, etc...
public static readonly DependencyProperty StrokeThicknessProperty =
DependencyProperty.Register("StrokeThickness", typeof(double), typeof(CircularProgressBar), new PropertyMetadata(10.0));
}
AngleToPointConverter.cs
class AngleToPointConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double angle = (double)value;
double radius = 50;
double piang = angle * Math.PI/180;
double px = Math.Sin(piang) * radius + radius;
double py = -Math.Cos(piang) * radius + radius;
return new Point(px, py);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
AngleToIsLargeConverter.CS
class AngleToIsLargeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double angle = (double)value;
return angle > 180;
}
public object ConvertBack(object value, Type targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
App.xaml
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
xmlns:my="clr-namespace:WpfApplication1">
<Application.Resources>
<my:AngleToPointConverter x:Key="prConverter"/>
<my:AngleToIsLargeConverter x:Key="isLargeConverter"/>
<Style x:Key="circularProgressBar" TargetType="my:CircularProgressBar">
<Setter Property="Value" Value="10"/>
<Setter Property="Maximum" Value="100"/>
<Setter Property="StrokeThickness" Value="10"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="my:CircularProgressBar">
<Canvas Width="100" Height="100">
<Ellipse Width="100" Height="100" Stroke="LightGray"
StrokeThickness="1"/>
<Path Stroke="{TemplateBinding Background}"
StrokeThickness="{TemplateBinding StrokeThickness}">
<Path.Data>
<PathGeometry>
<PathFigure x:Name="fig" StartPoint="50,0">
<ArcSegment RotationAngle="0" SweepDirection="Clockwise"
Size="50,50"
Point="{Binding Path=Angle, Converter={StaticResource prConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType=ProgressBar}}"
IsLargeArc="{Binding Path=Angle, Converter={StaticResource isLargeConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType=ProgressBar}}"
>
</ArcSegment>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
<Border Width="100" Height="100">
<TextBlock Foreground="Gray" HorizontalAlignment="Center" VerticalAlignment="Center"
Text="{Binding Path=Value, StringFormat={}%{0},
RelativeSource={RelativeSource TemplatedParent}}"
FontSize="{TemplateBinding FontSize}"/>
</Border>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
그것은 더 등 InnerRadius, 반경
과 같은 몇 가지 이상의 속성을 추가하여 사용자 정의 할 수 있습니다 내가 아는이 이전 문제이지만 어쨌든 여기 내 해결책이 있습니다 :
윈폼에 대한:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
public class CircularProgressBar : Control
{
/* CREDITS:
* Autor: Sajjad Arif Gul/October 12, 2016/C#, Source Codes
* https://www.csharpens.com/c-sharp/circular-progress-bar-in-c-sharp-windows-form-applications-23/
* Modified by Jhollman Chacon, 2017 */
#region Enums
public enum _ProgressShape
{
Round,
Flat
}
#endregion
#region Variables
private long _Value;
private long _Maximum = 100;
private Color _ProgressColor1 = Color.Orange;
private Color _ProgressColor2 = Color.Orange;
private Color _LineColor = Color.Silver;
private _ProgressShape ProgressShapeVal;
#endregion
#region Custom Properties
public long Value
{
get { return _Value; }
set
{
if (value > _Maximum)
value = _Maximum;
_Value = value;
Invalidate();
}
}
public long Maximum
{
get { return _Maximum; }
set
{
if (value < 1)
value = 1;
_Maximum = value;
Invalidate();
}
}
public Color ProgressColor1
{
get { return _ProgressColor1; }
set
{
_ProgressColor1 = value;
Invalidate();
}
}
public Color ProgressColor2
{
get { return _ProgressColor2; }
set
{
_ProgressColor2 = value;
Invalidate();
}
}
public Color LineColor
{
get { return _LineColor; }
set
{
_LineColor = value;
Invalidate();
}
}
public _ProgressShape ProgressShape
{
get { return ProgressShapeVal; }
set
{
ProgressShapeVal = value;
Invalidate();
}
}
#endregion
#region EventArgs
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
SetStandardSize();
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
SetStandardSize();
}
protected override void OnPaintBackground(PaintEventArgs p)
{
base.OnPaintBackground(p);
}
#endregion
#region Methods
public CircularProgressBar()
{
Size = new Size(130, 130);
Font = new Font("Segoe UI", 15);
MinimumSize = new Size(100, 100);
DoubleBuffered = true;
Value = 57;
ProgressShape = _ProgressShape.Flat;
this.ForeColor = Color.DimGray;
}
private void SetStandardSize()
{
int _Size = Math.Max(Width, Height);
Size = new Size(_Size, _Size);
}
public void Increment(int Val)
{
this._Value += Val;
Invalidate();
}
public void Decrement(int Val)
{
this._Value -= Val;
Invalidate();
}
#endregion
#region Events
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (Bitmap bitmap = new Bitmap(this.Width, this.Height))
{
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.Clear(this.BackColor);
// Dibuja la Linea
using (Pen pen2 = new Pen(LineColor))
{
graphics.DrawEllipse(pen2, 0x18 - 6, 0x18 - 6, (this.Width - 0x30) + 12, (this.Height - 0x30) + 12);
}
//Dibuja la Barra de Progreso
using (LinearGradientBrush brush = new LinearGradientBrush(this.ClientRectangle, this._ProgressColor1, this._ProgressColor2, LinearGradientMode.ForwardDiagonal))
{
using (Pen pen = new Pen(brush, 14f))
{
switch (this.ProgressShapeVal)
{
case _ProgressShape.Round:
pen.StartCap = LineCap.Round;
pen.EndCap = LineCap.Round;
break;
case _ProgressShape.Flat:
pen.StartCap = LineCap.Flat;
pen.EndCap = LineCap.Flat;
break;
}
//Aqui se dibuja el Progreso
graphics.DrawArc(pen, 0x12, 0x12, (this.Width - 0x23) - 2, (this.Height - 0x23) - 2, -90, (int)Math.Round((double)((360.0/((double)this._Maximum)) * this._Value)));
}
}
//Dibuja el Texto de Progreso:
Brush FontColor = new SolidBrush(this.ForeColor);
SizeF MS = graphics.MeasureString(Convert.ToString(Convert.ToInt32((100/_Maximum) * _Value)), Font);
graphics.DrawString(Convert.ToString(Convert.ToInt32((100/_Maximum) * _Value)), Font, FontColor, Convert.ToInt32(Width/2 - MS.Width/2), Convert.ToInt32(Height/2 - MS.Height/2));
e.Graphics.DrawImage(bitmap, 0, 0);
graphics.Dispose();
bitmap.Dispose();
}
}
}
#endregion
}
이행 :
- 장소 어디에서든 윈폼 프로젝트의 새로운 클래스에 소스 코드, 클래스 'CircularProgressBar.cs'를 이름을 지정합니다.
- 프로젝트를 컴파일하십시오.
- 컴파일 한 후 도구 모음에 새 컨트롤 또는 '구성 요소'가 나타납니다.
- 이 새 컨트롤을 폼에 드래그 앤 드롭하고 해당 속성을 사용자 지정합니다.
는 컨트롤과 같습니다
을 즐길 수 있습니다.
- 1. 원형 차트에 숫자 표시
- 2. 원형 그라디언트는 어떻게 그리나요?
- 3. 원형 UIScrollView
- 4. 원형 이미지?
- 5. 메이븐 원형
- 6. WPF에서 원추/원뿔/원형 그라디언트를 구현하는 방법
- 7. 원형 외래 키입니다. 어떻게 처리합니까?
- 8. 원형 배열의 모듈러스 연산을 이해하는 데 도움이됩니다.
- 9. Flex 3.0 : 원형 차트의 범례에 데이터 표시
- 10. OnSelectedIndexChanged 진행률 표시 줄을 어떻게 업데이트합니까?
- 11. 설정의 원형 사각형 버튼
- 12. 원형 배열 클래스 (파이썬에서)
- 13. 어떻게 진행률 표시 줄을 100 %보다 크게 표시 하시겠습니까?
- 14. 방사형 원형 차트는 어떻게 만들 수 있습니까?
- 15. CSS가있는 원형 주입 표시기 만 표시
- 16. 원형 그래프 시각화
- 17. 모노크롬 원형 차트
- 18. 미터 스타일 진행률 표시 줄을 사용하려면 어떻게해야합니까?
- 19. 진행률 표시 줄을 얻는 방법 클래스 실행
- 20. 진행률 표시 줄을 닫는 방법?
- 21. 진행률 표시 줄을 닫는 방법
- 22. jQuery 원형 슬라이더?
- 23. 원형 '인터페이스'종속성과 성 - 윈저
- 24. 원형 JPanel 스윙
- 25. 안드로이드 Andengine 원형 경로
- 26. 무한 긴 원형 사각형
- 27. 원형 객체 감지
- 28. 구글 원형 차트와 라벨
- 29. 플렉스 원형 리플 효과
- 30. 스윙 JFrame의 원형
해당 링크가 끊어졌습니다. 질문에 이미지를 삽입하십시오. –