WPF实现好看可控的温度计

废话不多少,直接上代码

  1 public class Thermometer : System.Windows.Controls.Control
  2 {
  3 
  4    public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(double), typeof(Thermometer), new UIPropertyMetadata(40.0));
  5 
  6     public double MaxValue
  7     {
  8         get { return (double)GetValue(MaxValueProperty); }
  9 
 10         set { SetValue(MaxValueProperty, value); }
 11     }
 12 
 13     public static readonly DependencyProperty MinValueProperty = DependencyProperty.Register("MinValue", typeof(double), typeof(Thermometer), new UIPropertyMetadata(-10.0));
 14 
 15     public double MinValue
 16     {
 17         get { return (double)GetValue(MinValueProperty); }
 18 
 19         set { SetValue(MinValueProperty, value); }
 20     }
 21 
 22     /// <summary>
 23     /// 当前值
 24     /// </summary>
 25     public static readonly DependencyProperty CurrentValueProperty = DependencyProperty.Register("CurrentValue", typeof(double), typeof(Thermometer), new UIPropertyMetadata(0.0));
 26 
 27     public double CurrentValue
 28     {
 29         get { return (double)GetValue(CurrentValueProperty); }
 30 
 31         set
 32         {
 33             SetValue(CurrentValueProperty, value);
 34 
 35             PaintPath();
 36         }
 37     }
 38 
 39     /// <summary>
 40     /// 步长
 41     /// </summary>
 42     public static readonly DependencyProperty IntervalProperty = DependencyProperty.Register("Interval", typeof(double), typeof(Thermometer), new UIPropertyMetadata(10.0));
 43 
 44     public double Interval
 45     {
 46         get { return (double)GetValue(IntervalProperty); }
 47 
 48         set { SetValue(IntervalProperty, value); }
 49     }
 50 
 51     /// <summary>
 52     /// 当前值的图形坐标点
 53     /// </summary>
 54     public static readonly DependencyProperty CurrentGeometryProperty = DependencyProperty.Register("CurrentGeometry", typeof(Geometry), typeof(Thermometer), new PropertyMetadata(Geometry.Parse(@"M 2 132.8 
 55                               a 4 4 0 0 1 4 -4 
 56                               h 18 
 57                               a 4 4 0 0 1 4 4
 58                               v 32.2
 59                               a 4 4 0 0 1 -4 4 
 60                               h -18
 61                               a 4 4 0 0 1 -4 -4 z")));
 62 
 63     public Geometry CurrentGeometry
 64     {
 65         get { return (Geometry)GetValue(CurrentGeometryProperty); }
 66 
 67         set { SetValue(CurrentGeometryProperty, value); }
 68     }
 69 
 70     /// <summary>
 71     /// 构造函数
 72     /// </summary>
 73     static Thermometer()
 74     {
 75         DefaultStyleKeyProperty.OverrideMetadata(typeof(Thermometer), new FrameworkPropertyMetadata(typeof(Thermometer)));
 76     }
 77 
 78     public override void OnApplyTemplate()
 79     {
 80         base.OnApplyTemplate();
 81 
 82         PaintPath();
 83     }
 84 
 85     protected override void OnRender(DrawingContext drawingContext)
 86     {
 87         SolidColorBrush brush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#63E0B4"));
 88 
 89         Rect rect = new Rect();
 90 
 91         rect.Width = 30;
 92 
 93         rect.Height = 169;
 94 
 95         drawingContext.DrawRoundedRectangle(Brushes.Transparent,
 96             new Pen(brush, 4d),
 97             rect, 8d, 8d);
 98 
 99         #region 华氏温度
100 
101         FormattedText text = new FormattedText("",
102             CultureInfo.CurrentUICulture,
103             FlowDirection.RightToLeft,
104             new Typeface("Source Han Sans CN"),
105             12d,
106             new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF")));
107 
108         drawingContext.DrawText(text, new Point(-49, 115));
109 
110         text = new FormattedText("",
111             CultureInfo.CurrentUICulture,
112             FlowDirection.RightToLeft,
113             new Typeface("Source Han Sans CN"),
114             12d,
115             new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF")));
116 
117         drawingContext.DrawText(text, new Point(-49, 115 + 14));
118 
119         text = new FormattedText("",
120            CultureInfo.CurrentUICulture,
121            FlowDirection.RightToLeft,
122            new Typeface("Source Han Sans CN"),
123            12d,
124            new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF")));
125 
126         drawingContext.DrawText(text, new Point(-49, 115 + 28));
127 
128         text = new FormattedText("",
129             CultureInfo.CurrentUICulture,
130             FlowDirection.RightToLeft,
131             new Typeface("Source Han Sans CN"),
132             12d,
133             new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF")));
134 
135         drawingContext.DrawText(text, new Point(-49, 115 + 42));
136 
137         #endregion
138 
139         #region 摄氏温度
140 
141         text = new FormattedText("",
142             CultureInfo.CurrentUICulture,
143             FlowDirection.LeftToRight,
144             new Typeface("Source Han Sans CN"),
145             12d,
146             new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF")));
147 
148         drawingContext.DrawText(text, new Point(75, 115));
149 
150         text = new FormattedText("",
151             CultureInfo.CurrentUICulture,
152             FlowDirection.LeftToRight,
153             new Typeface("Source Han Sans CN"),
154             12d,
155             new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF")));
156 
157         drawingContext.DrawText(text, new Point(75, 115 + 14));
158 
159         text = new FormattedText("",
160            CultureInfo.CurrentUICulture,
161            FlowDirection.LeftToRight,
162            new Typeface("Source Han Sans CN"),
163            12d,
164            new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF")));
165 
166         drawingContext.DrawText(text, new Point(75, 115 + 28));
167 
168         text = new FormattedText("",
169             CultureInfo.CurrentUICulture,
170             FlowDirection.LeftToRight,
171             new Typeface("Source Han Sans CN"),
172             12d,
173             new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF")));
174 
175         drawingContext.DrawText(text, new Point(75, 115 + 42));
176 
177         #endregion
178 
179         #region 画刻度
180 
181         var total_Value = MaxValue - MinValue;
182 
183         var cnt = total_Value / Interval;
184 
185         var one_value = 161d / cnt;
186 
187         for (int i = 0; i <= cnt; i++)
188         {
189             FormattedText formattedText = new FormattedText($"{MaxValue - (i * Interval)}",
190                 CultureInfo.CurrentUICulture,
191                 FlowDirection.LeftToRight,
192                 new Typeface("Source Han Sans CN"),
193                 12d,
194                 new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF")));
195 
196             drawingContext.DrawText(formattedText, new Point(43, i * one_value - (formattedText.Height / 2d)));//减去字体高度的一半
197 
198             formattedText = new FormattedText($"{(MaxValue - (i * Interval)) * 1.8d + 32d}",
199                 CultureInfo.CurrentUICulture,
200                 FlowDirection.RightToLeft,
201                 new Typeface("Source Han Sans CN"),
202                 12d,
203                 new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF")));
204 
205             drawingContext.DrawText(formattedText, new Point(-13, i * one_value - (formattedText.Height / 2d)));
206 
207             if (i != 0 && i != 5)
208             {
209                 drawingContext.DrawLine(new Pen(new SolidColorBrush((Color)ColorConverter.ConvertFromString("#ED538A")), 1d),
210                     new Point(4, i * one_value), new Point(6, i * one_value));
211 
212                 drawingContext.DrawLine(new Pen(new SolidColorBrush((Color)ColorConverter.ConvertFromString("#ED538A")), 1d),
213                     new Point(24, i * one_value), new Point(26, i * one_value));
214             }
215         }
216         
217         #endregion
218     }
219 
220     /// <summary>
221     /// 动态计算当前值图形坐标点
222     /// </summary>
223     private void PaintPath()
224     {
225         var one_value = 161d / ((MaxValue - MinValue) / Interval);
226 
227         var width = 26d;
228 
229         var height = 169d - (MaxValue - CurrentValue) * (one_value / Interval);
230 
231         var x = 2d;
232 
233         var y = 169d - (169d - (MaxValue - CurrentValue) * (one_value / Interval));
234 
235         //画当前值的三角形 
236         CurrentGeometry = Geometry.Parse($@"M 2 {y + 4} 
237                               a 4 4 0 0 1 4 -4 
238                               h {width - 8} 
239                               a 4 4 0 0 1 4 4
240                               v {height - 8}
241                               a 4 4 0 0 1 -4 4 
242                               h -{width - 8}
243                               a 4 4 0 0 1 -4 -4 z");
244     }
245 }
1 <Border Width="280" Height="253" Background="#2E385A" CornerRadius="12" Margin="13,15,0,0">
2  <StackPanel Orientation="Horizontal">
3       <Grid HorizontalAlignment="Left" Margin="86,43,0,0">
4         <Path Stroke="Red" StrokeThickness="0.5" Fill="Red" Data="{Binding ElementName=Layout_Control_Thermometer1, Path=CurrentGeometry,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
5         <control:Thermometer x:Name="Layout_Control_Thermometer1" CurrentValue="10"/>
6       </Grid>
7    <TextBlock Text="{Binding ElementName=Layout_Control_Thermometer1,Path=CurrentValue,StringFormat={}{0}℃}" FontSize="24" Foreground="#ED538A" FontFamily="Bahnschrift" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="100,0,0,0"/>
8  </StackPanel>
9 </Border>

 

posted @ 2021-11-16 15:29  SFlyers  阅读(654)  评论(5编辑  收藏  举报