我是靠谱客的博主 潇洒御姐,最近开发中收集的这篇文章主要介绍WPF 做的天干地支 乾坤八卦时钟表盘 可以设置24小时制WPF 做的天干地支 可以设置24小时制,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
WPF 做的天干地支 可以设置24小时制
一次偶然朋友看见别人卖一个有天干地支的时钟,2000大洋,就觉得这东西自己做一个不就行了,然后刚好最近研究WPF,就做了这个,先上效果图
主要分了几步,
第一步画个背景圆形,让指针动起来
第二步刻画表盘,刻画天干地支,乾坤八卦盘
第三步,实现24小时制度的表盘(因为聊到天干地支是一天24小时的)
第四步引入了Quartz Regular.ttf字体
第五步做了托盘模式的
直接上代码吧
<Window xmlns:my="clr-namespace:WpfClock" x:Class="WpfClock.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" x:Name="myWindow" Margin="2" Height="387" Width="327" AllowsTransparency="True"
WindowStyle="None" Background="Transparent" WindowStartupLocation="CenterScreen" ShowInTaskbar="False"
ResizeMode="NoResize" Topmost="False" Opacity="1" Icon="/WpfClock;component/weather_clock.ico">
<Window.Resources>
<Style x:Key="QuartzRegular">
<Setter Property="TextElement.FontFamily" Value="/WpfClock;component/Resources/#Quartz Regular"/>
</Style>
</Window.Resources>
<Border Width="300" Height="360" BorderThickness="2" CornerRadius="20" MouseLeftButtonDown="Grid_MouseLeftButtonDown">
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFD9E5EF" Offset="0.846"/>
<GradientStop Color="#FF5498DB" Offset="0.342"/>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<ImageBrush ImageSource="Back.png"></ImageBrush>
</Border.Background>
<Grid Width="300" Height="360">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
</Grid.RowDefinitions>
<Grid Width="300" Height="300" Grid.Row="0">
<!--背景-->
<Ellipse x:Name="PointerCap" Width="280" Height="280" StrokeThickness="4" Opacity=".5" >
<Ellipse.Stroke>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF000000" Offset="0.675"/>
<GradientStop Color="#FFC1B5B5" Offset="0.031"/>
</LinearGradientBrush>
</Ellipse.Stroke>
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF152029" Offset="0.846"/>
<GradientStop Color="#FF140204" Offset="0.342"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<!--外圈1-->
<Ellipse Width="287" Height="287" StrokeThickness="3" Grid.Row="0" Grid.Column="0">
<Ellipse.Stroke>
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStop Color="LightBlue" Offset="0" />
<GradientStop Color="DarkBlue" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Ellipse.Stroke>
</Ellipse>
<!--外圈2-->
<Ellipse x:Name="OuterFrame" StrokeThickness="16"
Width="280" Height="280">
<Ellipse.Stroke>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF636060" Offset="1"/>
<GradientStop Color="#FF5F5C5C" Offset="0"/>
<GradientStop Color="#FFEEDEDE" Offset="0.35"/>
<GradientStop Color="#FFA09595" Offset="0.705"/>
</LinearGradientBrush>
</Ellipse.Stroke>
</Ellipse>
<Grid Width="300" Height="300" x:Name="rootGrid"></Grid>
<Label Name="lab1" Foreground="White" Margin="0,0,0,190" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="Auto" Width="Auto" FontSize="10" >中国制造</Label>
<Label Name="lab2" Foreground="White" Margin="0,100,0,0" HorizontalAlignment="Center" VerticalAlignment="Top" Height="Auto" Width="Auto" FontSize="10">Made In China</Label>
<!-- 时针定义 -->
<Rectangle Margin="147,80,147,150" Name="rectangleHour" Stroke="LightYellow" Fill="Red" Height="80" VerticalAlignment="Bottom">
<Rectangle.RenderTransform>
<RotateTransform x:Name="hourPointer" CenterX="3" CenterY="80" Angle="{Binding ElementName=myWindow,Path=DataContext.Hour}" />
</Rectangle.RenderTransform>
</Rectangle>
<!-- -->
<!-- 分钟定义 -->
<Rectangle Margin="148,60,148,150" Name="rectangleMinute" Stroke="LightGreen" Fill="DarkOrange" Height="100" VerticalAlignment="Bottom">
<Rectangle.RenderTransform>
<RotateTransform x:Name="minutePointer" CenterX="2" CenterY="100" Angle="{Binding ElementName=myWindow,Path=DataContext.Minute}"/>
</Rectangle.RenderTransform>
</Rectangle>
<!-- -->
<!-- 秒针定义 -->
<Rectangle Margin="149,50,149,150" Name="rectangleSecond" Stroke="White" Fill="Black" Height="120" VerticalAlignment="Bottom">
<Rectangle.RenderTransform>
<RotateTransform x:Name="secondPointer" CenterX="1" CenterY="120" Angle="{Binding ElementName=myWindow,Path=DataContext.Second}" />
</Rectangle.RenderTransform>
</Rectangle>
<!-- -->
<!--圆心-->
<Ellipse Width="8" Height="8" Fill="Black" />
<!---->
<Label Background="Blue" FontSize="14" FontWeight="ExtraBold" Foreground="Yellow"
Content="{Binding ElementName=myWindow,Path=DataContext.TimeTxt}" Style="{DynamicResource QuartzRegular}" Height="Auto" HorizontalAlignment="Center" Margin="114,0,113,96" Name="labTime" VerticalAlignment="Bottom" Width="Auto">
</Label>
<!--<Label Content="" FontSize="16" Foreground="White" Height="Auto" HorizontalAlignment="Center" Margin="114,0,113,96" Name="labTime" VerticalAlignment="Bottom" Width="Auto" />-->
</Grid>
<Grid Grid.Row="1" Width="300" Height="60">
<my:SwitchButton CheckedText="24小时制" Text="12小时制" IsChecked="{Binding ElementName=myWindow,Path=DataContext.IsChecked12_24}"/>
</Grid>
</Grid>
</Border>
</Window>
public sealed class AngleService : INotifyPropertyChanged
{
public double Hour
{
get { return _hour; }
set
{
_hour = value;
OnPropertyChanged("Hour");
}
}
public double Minute
{
get { return _minute; }
set
{
_minute = value;
OnPropertyChanged("Minute");
}
}
public double Second
{
get { return _second; }
set
{
_second = value;
OnPropertyChanged("Second");
}
}
public string TimeTxt
{
get { return _timetxt; }
set
{
_timetxt = value;
OnPropertyChanged("TimeTxt");
}
}
public Boolean IsChecked12_24
{
get { return _ischecked12_24; }
set
{
_ischecked12_24 = value;
OnPropertyChanged("IsChecked12_24");
initialDateTime();
//值更改后触发事件重绘表盘
}
}
public event PropertyChangedEventHandler PropertyChanged;
public AngleService()
{
initialDateTime();
_tiemr = new Timer(1000);
_tiemr.Elapsed += _tiemr_Elapsed;
_tiemr.Start();
}
void _tiemr_Elapsed(object sender, ElapsedEventArgs e)
{
initialDateTime();
}
void initialDateTime()
{
DateTime dt = DateTime.Now;
if (_ischecked12_24)
{
if (dt.Minute % 2 == 0)
{
//秒针转动,秒针绕一圈360度,共120秒,所以1秒转动3度
Second = (dt.Second * 3) + 180;
}
else
{
//秒针转动,秒针绕一圈360度,共120秒,所以1秒转动3度
Second = dt.Second * 3;
}
if (dt.Hour % 2 == 0)
{
//分针转动,分针绕一圈360度,共1200分,所以1分转动3度
Minute = (dt.Minute * 3) + 180;
}
else
{
//分针转动,分针绕一圈360度,共1200分,所以1分转动3度
Minute = dt.Minute * 3;
}
//时针转动,时针绕一圈360度,共24时,所以1时转动15度。
//另外同一个小时内,随着分钟数的变化(绕一圈120分钟2小时),时针也在缓慢变化(转动15度,15/(120/2)=0.25)
if (int.Parse(DateTime.Now.ToString("HH")) > 12)
{
Hour = ((dt.Hour * 15) + (dt.Minute * 0.25));
}
else
{
Hour = (dt.Hour * 15) + (dt.Minute * 0.25);
}
}
else
{
//秒针转动,秒针绕一圈360度,共60秒,所以1秒转动6度
Second = dt.Second * 6;
//分针转动,分针绕一圈360度,共60分,所以1分转动6度
Minute = dt.Minute * 6;
//时针转动,时针绕一圈360度,共12时,所以1时转动30度。
//另外同一个小时内,随着分钟数的变化(绕一圈60分钟),时针也在缓慢变化(转动30度,30/60=0.5)
Hour = (dt.Hour * 30) + (dt.Minute * 0.5);
}
TimeTxt = DateTime.Now.ToString("HH:mm:ss");
}
private void OnPropertyChanged(string info)
{
if (this.PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
private double _hour, _minute, _second;
private string _timetxt;
private Boolean _ischecked12_24 = false;
private Timer _tiemr;
}
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
//托盘
System.Windows.Forms.NotifyIcon notifyIcon;
//计时器
public MainWindow()
{
InitializeComponent();
#region 托盘
this.notifyIcon = new System.Windows.Forms.NotifyIcon();
this.notifyIcon.BalloonTipText = "天干地支";
this.notifyIcon.ShowBalloonTip(2000);
this.notifyIcon.Text = "乾坤八卦";
//this.notifyIcon.Icon = new System.Drawing.Icon(@"weather_clock.ico");
this.notifyIcon.Icon = System.Drawing.Icon.ExtractAssociatedIcon(System.Windows.Forms.Application.ExecutablePath);
this.notifyIcon.Visible = true;
//打开菜单项
System.Windows.Forms.MenuItem open = new System.Windows.Forms.MenuItem("Open");
open.Click += new EventHandler(Show);
//隐藏菜单项
System.Windows.Forms.MenuItem hide = new System.Windows.Forms.MenuItem("Hide");
hide.Click += new EventHandler(Hide);
//退出菜单项
System.Windows.Forms.MenuItem exit = new System.Windows.Forms.MenuItem("Exit");
exit.Click += new EventHandler(Close);
//关联托盘控件
System.Windows.Forms.MenuItem[] childen = new System.Windows.Forms.MenuItem[] { open, hide, exit };
notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(childen);
this.notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler((o, e) =>
{
if (e.Button == System.Windows.Forms.MouseButtons.Left) this.Show(o, e);
});
#endregion
AngleService dt2as = new AngleService ();
dt2as.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(dt2as_PropertyChanged);
this.DataContext = dt2as;
DrawScale(dt2as.IsChecked12_24);
}
void dt2as_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsChecked12_24")
{
//重绘刻度表盘
DrawScale((sender as DateTime2AngleService).IsChecked12_24);
}
}
private void Show(object sender, EventArgs e)
{
this.Visibility = System.Windows.Visibility.Visible;
//this.ShowInTaskbar = true;
this.Activate();
}
private void Hide(object sender, EventArgs e)
{
//this.ShowInTaskbar = false;
this.Visibility = System.Windows.Visibility.Hidden;
}
private void Close(object sender, EventArgs e)
{
System.Windows.Application.Current.Shutdown();
}
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
//进行拖放移动
this.DragMove();
}
/// <summary>
/// 画刻度
/// </summary>
private void DrawScale(Boolean IsChecked12_24)
{
rootGrid.Children.Clear();
double ScaleStartAngle = 270;
double ScaleSweepAngle = 360;
double MajorDivisionsCount = 12;
double MinorDivisionsCount = 5;
double MaxValue = 12;
if (IsChecked12_24)
{
MaxValue = 24;
MajorDivisionsCount = 24;
}
double MinValue = 0;
int ScaleValuePrecision = 0;
Size MajorTickSize = new Size(10, 3);
Size ScaleLabelSize = new Size(40, 20);
Color MajorTickColor = Colors.LightGray;
double ScaleLabelFontSize = 8;
Color ScaleLabelForeground = Colors.LightGray;
Color MinorTickColor = Colors.LightGray;
Size MinorTickSize = new Size(3, 1);
double ScaleRadius = 100;
double ScaleLabelRadius = 80;
//大刻度角度
Double majorTickUnitAngle = ScaleSweepAngle / MajorDivisionsCount;
//小刻度角度
Double minorTickUnitAngle = ScaleSweepAngle / MinorDivisionsCount;
//刻度单位值
Double majorTicksUnitValue = (MaxValue - MinValue) / MajorDivisionsCount;
majorTicksUnitValue = Math.Round(majorTicksUnitValue, ScaleValuePrecision);
Double minvalue = MinValue; ;
for (Double i = ScaleStartAngle; i <= (ScaleStartAngle + ScaleSweepAngle); i = i + majorTickUnitAngle)
{
//大刻度、刻度值角度
Double i_radian = (i * Math.PI) / 180;
#region 大刻度
Rectangle majortickrect = new Rectangle();
majortickrect.Height = MajorTickSize.Height;
majortickrect.Width = MajorTickSize.Width;
majortickrect.Fill = new SolidColorBrush(MajorTickColor);
Point p = new Point(0.5, 0.5);
majortickrect.RenderTransformOrigin = p;
majortickrect.HorizontalAlignment = HorizontalAlignment.Center;
majortickrect.VerticalAlignment = VerticalAlignment.Center;
TransformGroup majortickgp = new TransformGroup();
RotateTransform majortickrt = new RotateTransform();
majortickrt.Angle = i;
majortickgp.Children.Add(majortickrt);
TranslateTransform majorticktt = new TranslateTransform();
//在这里画点中心为(0,0)
majorticktt.X = (int)((ScaleRadius) * Math.Cos(i_radian));
majorticktt.Y = (int)((ScaleRadius) * Math.Sin(i_radian));
majortickgp.Children.Add(majorticktt);
majortickrect.RenderTransform = majortickgp;
rootGrid.Children.Add(majortickrect);
#endregion
#region 刻度值
TranslateTransform majorscalevaluett = new TranslateTransform();
//在这里画点中心为(0,0)
majorscalevaluett.X = (int)((ScaleLabelRadius) * Math.Cos(i_radian));
majorscalevaluett.Y = (int)((ScaleLabelRadius) * Math.Sin(i_radian));
//刻度值显示
TextBlock tb = new TextBlock();
tb.Height = ScaleLabelSize.Height;
tb.Width = ScaleLabelSize.Width;
tb.FontSize = ScaleLabelFontSize;
tb.Foreground = new SolidColorBrush(ScaleLabelForeground);
tb.TextAlignment = TextAlignment.Center;
tb.VerticalAlignment = VerticalAlignment.Center;
tb.HorizontalAlignment = HorizontalAlignment.Center;
if (Math.Round(minvalue, ScaleValuePrecision) <= Math.Round(MaxValue, ScaleValuePrecision))
{
minvalue = Math.Round(minvalue, ScaleValuePrecision);
if (minvalue > 0)
{
tb.Text = minvalue.ToString();
}
minvalue = minvalue + majorTicksUnitValue;
}
else
{
break;
}
tb.RenderTransform = majorscalevaluett;
rootGrid.Children.Add(tb);
#endregion
#region 小刻度
Double onedegree = ((i + majorTickUnitAngle) - i) / (MinorDivisionsCount);
if ((i < (ScaleStartAngle + ScaleSweepAngle)) && (Math.Round(minvalue, ScaleValuePrecision) <= Math.Round(MaxValue, ScaleValuePrecision)))
{
//绘制小刻度
for (Double mi = i + onedegree; mi < (i + majorTickUnitAngle); mi = mi + onedegree)
{
Rectangle mr = new Rectangle();
mr.Height = MinorTickSize.Height;
mr.Width = MinorTickSize.Width;
mr.Fill = new SolidColorBrush(MinorTickColor);
mr.HorizontalAlignment = HorizontalAlignment.Center;
mr.VerticalAlignment = VerticalAlignment.Center;
Point p1 = new Point(0.5, 0.5);
mr.RenderTransformOrigin = p1;
TransformGroup minortickgp = new TransformGroup();
RotateTransform minortickrt = new RotateTransform();
minortickrt.Angle = mi;
minortickgp.Children.Add(minortickrt);
TranslateTransform minorticktt = new TranslateTransform();
//计算角度
Double mi_radian = (mi * Math.PI) / 180;
//刻度点
minorticktt.X = (int)((ScaleRadius) * Math.Cos(mi_radian));
minorticktt.Y = (int)((ScaleRadius) * Math.Sin(mi_radian));
minortickgp.Children.Add(minorticktt);
mr.RenderTransform = minortickgp;
rootGrid.Children.Add(mr);
}
}
#endregion
#region 天干地支[子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥]
TranslateTransform majorscalevaluett_tgdz = new TranslateTransform();
//在这里画点中心为(0,0)
majorscalevaluett_tgdz.X = (int)((ScaleLabelRadius_Tgdz) * Math.Cos(i_radian));
majorscalevaluett_tgdz.Y = (int)((ScaleLabelRadius_Tgdz) * Math.Sin(i_radian));
//刻度值显示
TextBlock tb_tgdz = new TextBlock();
tb_tgdz.Height = ScaleLabelSize.Height;
tb_tgdz.Width = ScaleLabelSize.Width;
tb_tgdz.FontSize = ScaleLabelFontSize;
tb_tgdz.Foreground = new SolidColorBrush(ScaleLabelForeground);
tb_tgdz.TextAlignment = TextAlignment.Center;
tb_tgdz.VerticalAlignment = VerticalAlignment.Center;
tb_tgdz.HorizontalAlignment = HorizontalAlignment.Center;
if (int.Parse((minvalue - majorTicksUnitValue).ToString()) < tgdz.Length)
{
tb_tgdz.Text = tgdz[int.Parse((minvalue - majorTicksUnitValue).ToString())];
}
tb_tgdz.RenderTransform = majorscalevaluett_tgdz;
rootGrid.Children.Add(tb_tgdz);
#endregion
}
#region 八卦
string[] bg = new string[] { "乾", "巽", "坎", "艮", "坤", "震", "离", "兑" };
string[] bg_tag = new string[] { "离", "坤", "兑", "乾", "坎", "艮", "震", "巽" };
Color ScaleLabelForeground_bg = Colors.Red;
Color ScaleLabelForeground_bg_tag = Colors.LightGray;
Size ScaleLabelSize_bg = new Size(40, 20);
double ScaleLabelFontSize_bg = 12;
double ScaleLabelFontSize_bg_tag = 8;
double MajorDivisionsCount_bg = 8;
double MaxValue_bg = 8;
double ScaleLabelRadius_bg = 113;
//刻度角度
Double majorTickUnitAngle_bg = ScaleSweepAngle / MajorDivisionsCount_bg;
//刻度单位值
Double majorTicksUnitValue_bg = (MaxValue_bg - MinValue) / MajorDivisionsCount_bg;
majorTicksUnitValue_bg = Math.Round(majorTicksUnitValue_bg, ScaleValuePrecision);
Double minvalue_bg = MinValue;
for (Double i = ScaleStartAngle; i <= (ScaleStartAngle + ScaleSweepAngle); i = i + majorTickUnitAngle_bg)
{
Double i_radian = (i * Math.PI) / 180;
Double i_radian_ta = ((i+8) * Math.PI) / 180;
TranslateTransform majorscalevaluett = new TranslateTransform();
//在这里画点中心为(0,0)
majorscalevaluett.X = (int)((ScaleLabelRadius_bg) * Math.Cos(i_radian));
majorscalevaluett.Y = (int)((ScaleLabelRadius_bg) * Math.Sin(i_radian));
TranslateTransform majorscalevaluett_tag = new TranslateTransform();
//在这里画点中心为(0,0)
majorscalevaluett_tag.X = (int)((ScaleLabelRadius_bg) * Math.Cos(i_radian_ta));
majorscalevaluett_tag.Y = (int)((ScaleLabelRadius_bg) * Math.Sin(i_radian_ta));
//刻度值显示
TextBlock tb = new TextBlock();
tb.Height = ScaleLabelSize_bg.Height;
tb.Width = ScaleLabelSize_bg.Width;
tb.FontSize = ScaleLabelFontSize_bg;
tb.Foreground = new SolidColorBrush(ScaleLabelForeground_bg);
tb.TextAlignment = TextAlignment.Center;
tb.VerticalAlignment = VerticalAlignment.Center;
tb.HorizontalAlignment = HorizontalAlignment.Center;
TextBlock tb_tag = new TextBlock();
tb_tag.Height = ScaleLabelSize_bg.Height;
tb_tag.Width = ScaleLabelSize_bg.Width;
tb_tag.FontSize = ScaleLabelFontSize_bg_tag;
tb_tag.Foreground = new SolidColorBrush(ScaleLabelForeground_bg_tag);
tb_tag.TextAlignment = TextAlignment.Center;
tb_tag.VerticalAlignment = VerticalAlignment.Center;
tb_tag.HorizontalAlignment = HorizontalAlignment.Center;
if (Math.Round(minvalue_bg, ScaleValuePrecision) <= Math.Round(MaxValue_bg, ScaleValuePrecision))
{
minvalue_bg = Math.Round(minvalue_bg, ScaleValuePrecision);
if (int.Parse((minvalue_bg).ToString()) < bg.Length)
{
tb.Text = bg[int.Parse((minvalue_bg).ToString())];
tb_tag.Text = bg_tag[int.Parse((minvalue_bg).ToString())];
}
minvalue_bg = minvalue_bg + majorTicksUnitValue_bg;
}
else
{
break;
}
tb.RenderTransform = majorscalevaluett;
tb_tag.RenderTransform = majorscalevaluett_tag;
rootGrid.Children.Add(tb);
rootGrid.Children.Add(tb_tag);
}
#endregion
}
}
源码
https://download.csdn.net/download/shishuwei111/10581246
https://gitee.com/shi2015/WpfClock
感觉不错的给个star吧
最后
以上就是潇洒御姐为你收集整理的WPF 做的天干地支 乾坤八卦时钟表盘 可以设置24小时制WPF 做的天干地支 可以设置24小时制的全部内容,希望文章能够帮你解决WPF 做的天干地支 乾坤八卦时钟表盘 可以设置24小时制WPF 做的天干地支 可以设置24小时制所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复