Skip to content

Commit ab44e3b

Browse files
committed
Fix issue (#127
Fix issue (#127
1 parent fd1b84e commit ab44e3b

File tree

8 files changed

+291
-0
lines changed

8 files changed

+291
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<UserControl
2+
x:Class="WPFDevelopers.Samples.ExampleViews.GaugeExample"
3+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:controls="clr-namespace:WPFDevelopers.Samples.Controls"
6+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
7+
xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"
8+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9+
xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
10+
d:DesignHeight="450"
11+
d:DesignWidth="800"
12+
mc:Ignorable="d">
13+
<controls:CodeViewer>
14+
<WrapPanel HorizontalAlignment="Center" VerticalAlignment="Center">
15+
<StackPanel VerticalAlignment="Bottom">
16+
<wd:Gauge
17+
Title="Min"
18+
Width="100"
19+
Height="100"
20+
Margin="10"
21+
HorizontalAlignment="Center"
22+
VerticalAlignment="Center"
23+
Background="Black"
24+
BorderBrush="Red"
25+
FontSize="8"
26+
Maximum="90"
27+
Minimum="30"
28+
Thickness="3"
29+
ValueFormat="{}{0:0}值"
30+
Value="{Binding ElementName=MySlider2, Path=Value}" />
31+
<Slider
32+
Name="MySlider2"
33+
Width="200"
34+
Margin="0,0,0,20"
35+
HorizontalAlignment="Center"
36+
VerticalAlignment="Bottom"
37+
Maximum="90"
38+
Minimum="30" />
39+
</StackPanel>
40+
41+
<StackPanel>
42+
<wd:Gauge
43+
Title="反对率"
44+
Width="200"
45+
Height="200"
46+
Margin="10"
47+
HorizontalAlignment="Center"
48+
VerticalAlignment="Center"
49+
ValueFormat="{}{0:0}%"
50+
Value="{Binding ElementName=MySlider, Path=Value}" />
51+
<Slider
52+
Name="MySlider"
53+
Width="200"
54+
Margin="0,0,0,20"
55+
HorizontalAlignment="Center"
56+
VerticalAlignment="Bottom"
57+
Maximum="100"
58+
Minimum="0" />
59+
</StackPanel>
60+
<StackPanel VerticalAlignment="Bottom">
61+
<wd:Gauge
62+
Title="Max"
63+
Width="100"
64+
Height="100"
65+
Margin="10"
66+
HorizontalAlignment="Center"
67+
VerticalAlignment="Center"
68+
Background="Black"
69+
BorderBrush="DodgerBlue"
70+
FontSize="8"
71+
Maximum="90"
72+
Minimum="30"
73+
Thickness="3"
74+
ValueFormat="{}{0:0}值"
75+
Value="{Binding ElementName=MySlider3, Path=Value}" />
76+
<Slider
77+
Name="MySlider3"
78+
Width="200"
79+
Margin="0,0,0,20"
80+
HorizontalAlignment="Center"
81+
VerticalAlignment="Bottom"
82+
Maximum="90"
83+
Minimum="30" />
84+
</StackPanel>
85+
</WrapPanel>
86+
<controls:CodeViewer.SourceCodes>
87+
<controls:SourceCodeModel CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/GaugeExample.xaml" CodeType="Xaml" />
88+
<controls:SourceCodeModel CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/GaugeExample.xaml.cs" CodeType="CSharp" />
89+
</controls:CodeViewer.SourceCodes>
90+
</controls:CodeViewer>
91+
</UserControl>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Windows.Controls;
2+
3+
namespace WPFDevelopers.Samples.ExampleViews
4+
{
5+
/// <summary>
6+
/// GaugeExample.xaml 的交互逻辑
7+
/// </summary>
8+
public partial class GaugeExample : UserControl
9+
{
10+
public GaugeExample()
11+
{
12+
InitializeComponent();
13+
}
14+
}
15+
}

src/WPFDevelopers.Samples.Shared/Helpers/MenuEnum.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public enum MenuEnum
8989
Spacing,
9090
Drawer,
9191
DateRangePicker,
92+
Gauge,
9293
VirtualizingWrapPanel,
9394
AcrylicBlur,
9495
TaskbarInfo

src/WPFDevelopers.Samples.Shared/ViewModels/MainVM.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,9 @@ void MenuItemSelection(string _menuName)
367367
case MenuEnum.DateRangePicker:
368368
ControlPanel = new DateRangePickerExample();
369369
break;
370+
case MenuEnum.Gauge:
371+
ControlPanel = new GaugeExample();
372+
break;
370373
case MenuEnum.VirtualizingWrapPanel:
371374
ControlPanel = new VirtualizingWrapPanel();
372375
new VirtualizingWrapPanelExample().MaskShowDialog();

src/WPFDevelopers.Samples.Shared/WPFDevelopers.Samples.Shared.projitems

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@
207207
<SubType>Code</SubType>
208208
<DependentUpon>EdgeLightExample.xaml</DependentUpon>
209209
</Compile>
210+
<Compile Include="$(MSBuildThisFileDirectory)ExampleViews\GaugeExample.xaml.cs">
211+
<DependentUpon>GaugeExample.xaml</DependentUpon>
212+
</Compile>
210213
<Compile Include="$(MSBuildThisFileDirectory)ExampleViews\IPEditBoxExample.xaml.cs">
211214
<DependentUpon>IPEditBoxExample.xaml</DependentUpon>
212215
</Compile>
@@ -713,6 +716,10 @@
713716
<Generator>MSBuild:Compile</Generator>
714717
<SubType>Designer</SubType>
715718
</Page>
719+
<Page Include="$(MSBuildThisFileDirectory)ExampleViews\GaugeExample.xaml">
720+
<Generator>MSBuild:Compile</Generator>
721+
<SubType>Designer</SubType>
722+
</Page>
716723
<Page Include="$(MSBuildThisFileDirectory)ExampleViews\IPEditBoxExample.xaml">
717724
<Generator>MSBuild:Compile</Generator>
718725
<SubType>Designer</SubType>

src/WPFDevelopers.SamplesCode/WPFDevelopers.SamplesCode.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
<Resource Include="..\WPFDevelopers.Samples.Shared\ExampleViews\DateRangePickerExample.xaml.cs" Link="ExampleViews\DateRangePickerExample.xaml.cs" DependentUpon="DateRangePickerExample.xaml" />
151151
<Resource Include="..\WPFDevelopers.Samples.Shared\ExampleViews\SpacingExample.xaml.cs" Link="ExampleViews\SpacingExample.xaml.cs" DependentUpon="SpacingExample.xaml" />
152152
<Resource Include="..\WPFDevelopers.Samples.Shared\ExampleViews\NotifyIconExample.xaml.cs" Link="ExampleViews\NotifyIconExample.xaml.cs" DependentUpon="NotifyIconExample.xaml" />
153+
<Resource Include="..\WPFDevelopers.Samples.Shared\ExampleViews\GaugeExample.xaml.cs" Link="ExampleViews\GaugeExample.xaml.cs" DependentUpon="GaugeExample.xaml" />
153154
<Resource Include="..\WPFDevelopers.Samples.Shared\ExampleViews\Window\NormalWindow.xaml.cs" Link="ExampleViews\Window\NormalWindow.xaml.cs" DependentUpon="NormalWindow.xaml" />
154155
<Resource Include="..\WPFDevelopers.Samples.Shared\ExampleViews\Window\HighTitleBarWindow.xaml.cs" Link="ExampleViews\Window\HighTitleBarWindow.xaml.cs" DependentUpon="HighTitleBarWindow.xaml" />
155156
</ItemGroup>
@@ -514,6 +515,9 @@
514515
<Resource Include="..\WPFDevelopers.Samples.Shared\ExampleViews\NotifyIconExample.xaml">
515516
<Link>ExampleViews\NotifyIconExample.xaml</Link>
516517
</Resource>
518+
<Resource Include="..\WPFDevelopers.Samples.Shared\ExampleViews\GaugeExample.xaml">
519+
<Link>ExampleViews\GaugeExample.xaml</Link>
520+
</Resource>
517521
<Resource Include="..\WPFDevelopers.Samples.Shared\ExampleViews\Window\HighTitleBarWindow.xaml">
518522
<Link>ExampleViews\Window\HighTitleBarWindow.xaml</Link>
519523
</Resource>
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
using System;
2+
using System.Windows;
3+
using System.Windows.Controls.Primitives;
4+
using System.Windows.Media;
5+
6+
namespace WPFDevelopers.Controls
7+
{
8+
public class Gauge : RangeBase
9+
{
10+
public string Title
11+
{
12+
get { return (string)GetValue(TitleProperty); }
13+
set { SetValue(TitleProperty, value); }
14+
}
15+
16+
public static readonly DependencyProperty TitleProperty =
17+
DependencyProperty.Register("TitleProperty", typeof(string), typeof(Gauge), new PropertyMetadata("WD"));
18+
19+
public static readonly DependencyProperty ValueFormatProperty =
20+
DependencyProperty.Register("ValueFormat", typeof(string), typeof(Gauge),
21+
new PropertyMetadata("{0:0}%", OnValueFormatChanged));
22+
23+
private static void OnValueFormatChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
24+
{
25+
var gauge = d as Gauge;
26+
gauge?.InvalidateVisual();
27+
}
28+
29+
public string ValueFormat
30+
{
31+
get { return (string)GetValue(ValueFormatProperty); }
32+
set { SetValue(ValueFormatProperty, value); }
33+
}
34+
public double Thickness
35+
{
36+
get { return (double)GetValue(ThicknessProperty); }
37+
set { SetValue(ThicknessProperty, value); }
38+
}
39+
40+
public static readonly DependencyProperty ThicknessProperty =
41+
DependencyProperty.Register("Thickness", typeof(double), typeof(Gauge), new PropertyMetadata(10.0, OnValueFormatChanged));
42+
43+
44+
static Gauge()
45+
{
46+
DefaultStyleKeyProperty.OverrideMetadata(typeof(Gauge), new FrameworkPropertyMetadata(typeof(Gauge)));
47+
}
48+
49+
public Gauge()
50+
{
51+
SetValue(ValueProperty, 0.0);
52+
SetValue(MinimumProperty, 0.0);
53+
SetValue(MaximumProperty, 100.0);
54+
}
55+
56+
protected override void OnValueChanged(double oldValue, double newValue)
57+
{
58+
InvalidateVisual();
59+
}
60+
61+
protected override void OnMinimumChanged(double oldValue, double newValue)
62+
{
63+
InvalidateVisual();
64+
}
65+
66+
protected override void OnMaximumChanged(double oldValue, double newValue)
67+
{
68+
InvalidateVisual();
69+
}
70+
protected override void OnRender(DrawingContext drawingContext)
71+
{
72+
base.OnRender(drawingContext);
73+
if (Background == null)
74+
Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#293950"));
75+
var width = ActualWidth;
76+
var height = ActualHeight;
77+
var radius = Math.Min(width, height) / 2;
78+
drawingContext.DrawEllipse(Background, new Pen(Background, Thickness), new Point(width / 2, height / 2), radius, radius);
79+
var normalizedValue = (Value - Minimum) / (Maximum - Minimum);
80+
var mappedAngle = -220 + normalizedValue * 260;
81+
var angleInRadians = mappedAngle * Math.PI / 180;
82+
var pointerLength = radius * 0.7;
83+
var pointerX = width / 2 + pointerLength * Math.Cos(angleInRadians);
84+
var pointerY = height / 2 + pointerLength * Math.Sin(angleInRadians);
85+
drawingContext.DrawLine(new Pen(Brushes.Red, 2), new Point(width / 2, height / 2), new Point(pointerX, pointerY));
86+
drawingContext.DrawEllipse(Brushes.White, new Pen(Brushes.Red, 2), new Point(width / 2, height / 2), width / 20, width / 20);
87+
var pathGeometry = new PathGeometry();
88+
var startAngle = -220;
89+
angleInRadians = startAngle * Math.PI / 180;
90+
var startX = width / 2 + radius * Math.Cos(angleInRadians);
91+
var startY = height / 2 + radius * Math.Sin(angleInRadians);
92+
93+
var pathFigure = new PathFigure()
94+
{
95+
StartPoint = new Point(startX, startY),
96+
};
97+
98+
var endAngle = 40;
99+
angleInRadians = endAngle * Math.PI / 180;
100+
var endX = width / 2 + radius * Math.Cos(angleInRadians);
101+
var endY = height / 2 + radius * Math.Sin(angleInRadians);
102+
103+
var isLargeArc = (endAngle - startAngle > 180);
104+
var arcSegment = new ArcSegment()
105+
{
106+
Point = new Point(endX, endY),
107+
Size = new Size(radius, radius),
108+
RotationAngle = 0,
109+
SweepDirection = SweepDirection.Clockwise,
110+
IsLargeArc = isLargeArc,
111+
};
112+
113+
pathFigure.Segments.Add(arcSegment);
114+
pathGeometry.Figures.Add(pathFigure);
115+
if (BorderBrush == null)
116+
{
117+
var gradientBrush = new LinearGradientBrush
118+
{
119+
StartPoint = new Point(0, 0),
120+
EndPoint = new Point(1, 0)
121+
};
122+
gradientBrush.GradientStops.Add(new GradientStop((Color)ColorConverter.ConvertFromString("#37D2C2"), 0.0));
123+
gradientBrush.GradientStops.Add(new GradientStop((Color)ColorConverter.ConvertFromString("#5AD2B2"), 0.01));
124+
gradientBrush.GradientStops.Add(new GradientStop((Color)ColorConverter.ConvertFromString("#B77D29"), 0.49));
125+
gradientBrush.GradientStops.Add(new GradientStop(Colors.Red, 1.0));
126+
gradientBrush.Freeze();
127+
BorderBrush = gradientBrush;
128+
}
129+
drawingContext.DrawGeometry(null, new Pen(BorderBrush, Thickness), pathGeometry);
130+
var tickLength = radius * 0.1;
131+
var step = (Maximum - Minimum) / 10;
132+
for (int i = 0; i <= 10; i++)
133+
{
134+
var angle = startAngle + (i * (endAngle - startAngle) / 10);
135+
var tickStartX = width / 2 + (radius - tickLength) * Math.Cos(angle * Math.PI / 180);
136+
var tickStartY = height / 2 + (radius - tickLength) * Math.Sin(angle * Math.PI / 180);
137+
var tickEndX = width / 2 + (radius + Thickness / 2) * Math.Cos(angle * Math.PI / 180);
138+
var tickEndY = height / 2 + (radius + Thickness / 2) * Math.Sin(angle * Math.PI / 180);
139+
drawingContext.DrawLine(new Pen(Brushes.White, 2), new Point(tickStartX, tickStartY), new Point(tickEndX, tickEndY));
140+
141+
var labelValue = Minimum + step * i;
142+
var formattedText = DrawingContextHelper.GetFormattedText(labelValue.ToString(),Brushes.White, FlowDirection.LeftToRight,FontSize);
143+
144+
var labelRadius = radius - tickLength * 2;
145+
var labelX = width / 2 + labelRadius * Math.Cos(angle * Math.PI / 180) - formattedText.Width / 2;
146+
var labelY = height / 2 + labelRadius * Math.Sin(angle * Math.PI / 180) - formattedText.Height / 2;
147+
drawingContext.DrawText(formattedText, new Point(labelX, labelY));
148+
}
149+
var formattedValue = "{0:0}%";
150+
try
151+
{
152+
formattedValue = string.Format(ValueFormat, Value);
153+
}
154+
catch (FormatException ex)
155+
{
156+
throw new InvalidOperationException("Formatting failed ", ex);
157+
}
158+
var currentValueText = DrawingContextHelper.GetFormattedText(formattedValue, Brushes.White, FlowDirection.LeftToRight, FontSize * 2);
159+
var valueX = width / 2 - currentValueText.Width / 2;
160+
var valueY = height / 2 + radius * 0.4;
161+
drawingContext.DrawText(currentValueText, new Point(valueX, valueY));
162+
var titleValue = DrawingContextHelper.GetFormattedText(Title, Brushes.White, FlowDirection.LeftToRight, FontSize);
163+
valueX = width / 2 - titleValue.Width / 2;
164+
valueY = height / 2 + radius * 0.8;
165+
drawingContext.DrawText(titleValue, new Point(valueX, valueY));
166+
}
167+
168+
}
169+
}

src/WPFDevelopers.Shared/WPFDevelopers.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<Compile Include="$(MSBuildThisFileDirectory)Controls\ColorPicker\HSL.cs" />
2323
<Compile Include="$(MSBuildThisFileDirectory)Controls\DateRangePicker\DateRangePicker.cs" />
2424
<Compile Include="$(MSBuildThisFileDirectory)Controls\Drawer\Drawer.cs" />
25+
<Compile Include="$(MSBuildThisFileDirectory)Controls\Gauge\Gauge.cs" />
2526
<Compile Include="$(MSBuildThisFileDirectory)Controls\IPEditBox\IPEditBox.cs" />
2627
<Compile Include="$(MSBuildThisFileDirectory)Controls\Loadings\LoadingBase.cs" />
2728
<Compile Include="$(MSBuildThisFileDirectory)Controls\Loading\LoadingExt.cs" />

0 commit comments

Comments
 (0)