制作简单的WPF时钟

本文介绍如何在WPF中制作一个时钟,包括在Expression Blend中设计样式,创建时钟程序辅助类,以及利用DispatcherTimer更新时间。通过转换器类SecondsConverter、MinutesConverter、HoursConverter计算指针角度,并在XAML中展示。示例代码详细展示了时钟的实现过程。
摘要由CSDN通过智能技术生成

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

在很早之前,我曾经写过一个GDI+的时钟,见“C#时钟控件 (C# Clock Control)” http://blog.csdn.net/johnsuna/archive/2006/02/13/597746.aspx及“使用C#编写LED样式时钟控件”(http://blog.csdn.net/johnsuna/archive/2006/02/14/598867.aspx),进入WPF时代了,如何用WPF绘制一个时钟呢?

先看效果:

WPF时钟

上面显示的是时间值,下面是图形版的时钟。

制作要点:
1. 首先在Expression Blend中画出时钟的样式;
2. 建立时钟的程序辅助类;
3. 将此时钟样式需要动态换掉的部分改成相应的绑定值。

由于具体步骤很多,这里只说说技术难点和要点,着重说明上述第2点部分。
// 时钟控件类:Clock.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Timers;
using System.Windows.Threading;

namespace BrawDraw.Com.WPF.Clock.ControlLibrary
{
    /// <summary>Clock Control
 /// </summary>

 public class Clock : Control
 {
  private DispatcherTimer timer;

  static Clock()
  {
   DefaultStyleKeyProperty.OverrideMetadata(typeof(Clock), new FrameworkPropertyMetadata(typeof(Clock)));
  }

  protected override void OnInitialized(EventArgs e)
  {
   base.OnInitialized(e);
   timer = new DispatcherTimer();
   timer.Tick += new EventHandler(Timer_Tick);
   timer.Start();
  }

  private void Timer_Tick(object sender, EventArgs e)
  {
   UpdateDateTime();
   timer.Interval = TimeSpan.FromMilliseconds(1000 - DateTime.Now.Millisecond);
  }

  private void UpdateDateTime()
  {
   this.DateTime = System.DateTime.Now;
  }

  #region DateTime property
  public DateTime DateTime
  {
   get
   {
    return (DateTime)GetValue(DateTimeProperty);
   }
   private set
   {
    SetValue(DateTimeProperty, value);
   }
  }

  public static DependencyProperty DateTimeProperty = DependencyProperty.Register(
    "DateTime",
    typeof(DateTime),
    typeof(Clock),
    new PropertyMetadata(DateTime.Now, new PropertyChangedCallback(OnDateTimeInvalidated)));

  public static readonly RoutedEvent DateTimeChangedEvent =
   EventManager.RegisterRoutedEvent("DateTimeChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<DateTime>), typeof(Clock));

  protected virtual void OnDateTimeChanged(DateTime oldValue, DateTime newValue)
  {
   RoutedPropertyChangedEventArgs<DateTime> args = new RoutedPropertyChangedEventArgs<DateTime>(oldValue, newValue);
   args.RoutedEvent = Clock.DateTimeChangedEvent;
   RaiseEvent(args);
  }

  private static void OnDateTimeInvalidated(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
   Clock clock = (Clock)d;

   DateTime oldValue = (DateTime)e.OldValue;
   DateTime newValue = (DateTime)e.NewValue;

   clock.OnDateTimeChanged(oldValue, newValue);
  }
  #endregion
 }
}

// 时钟内部时针、分针、秒针角度计算及星期显示的类: ClockConverters.cs
// 由于WPF中旋转角度是以度单位,计算为绕一个圆周时,为360度。所以,计算时以360度来计算。
using System;
using System.Globalization;
using System.Windows.Data;

namespace BrawDraw.Com.WPF.Clock
{
    // 一分钟60秒,一周为360度,所以,一秒钟就占6度,所以是:秒数×6。
    [ValueConversion(typeof(DateTime), typeof(int))]
    public class SecondsConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            DateTime date = (DateTime)value;
            return date.Second * 6;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }

// 一小时是60分钟,一周为360度,所以,一分钟就占6度,所以是:分钟数×6。
    [ValueConversion(typeof(DateTime), typeof(int))]
    public class MinutesConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            DateTime date = (DateTime)value;
            return date.Minute * 6;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }

// 时钟上显示12小时,一周为360度,这样,每小时占30度,考虑分钟所占角度是分钟数/2,所以结果是:小时数×30 + 分钟数/2。
    [ValueConversion(typeof(DateTime), typeof(int))]
    public class HoursConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            DateTime date = (DateTime)value;
            return (date.Hour * 30) + (date.Minute / 2);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }

    [ValueConversion(typeof(DateTime), typeof(string))]
    public class WeekdayConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            DateTime date = (DateTime)value;
            return date.DayOfWeek.ToString().Substring(0,3);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }
}

剩下的就十分简单,程序的显示部分(XAML代码)
// MainWindow.xaml
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:customControl="clr-namespace:BrawDraw.Com.WPF.Clock.ControlLibrary;assembly=CustomControlLibrary"
 xmlns:local="clr-namespace:BrawDraw.Com.WPF.Clock"
    x:Class="BrawDraw.Com.WPF.Clock.Window1"
    Title="WPF Clock" Height="394" Width="332"
    >
 <StackPanel HorizontalAlignment="Center">
  <StackPanel.Resources>
   <local:SecondsConverter x:Key="secondsConverter"/>
   <local:MinutesConverter x:Key="minutesConverter"/>
   <local:HoursConverter x:Key="hoursConverter"/>
   <local:WeekdayConverter x:Key="weekdayConverter"/>
   <Style x:Key=

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的 C# WPF 时钟的示例代码: XAML 部分: ```xml <Window x:Class="WpfClock.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WPF Clock" Height="200" Width="200"> <Grid> <Ellipse Width="100" Height="100" Fill="White"/> <Canvas Margin="50"> <Line X1="50" Y1="50" X2="50" Y2="10" Stroke="Black" StrokeThickness="2"/> <Line X1="50" Y1="50" X2="90" Y2="50" Stroke="Black" StrokeThickness="2"/> <Line X1="50" Y1="50" X2="45" Y2="85" Stroke="Black" StrokeThickness="2"/> <Line X1="50" Y1="50" X2="55" Y2="85" Stroke="Black" StrokeThickness="2"/> <Line X1="50" Y1="50" X2="10" Y2="50" Stroke="Red" StrokeThickness="1"/> <Line X1="50" Y1="50" X2="50" Y2="90" Stroke="Red" StrokeThickness="1"/> </Canvas> <TextBlock x:Name="txtTime" Margin="70,100,0,0" FontSize="20"/> </Grid> </Window> ``` C# 部分: ```cs using System; using System.Windows; using System.Windows.Threading; namespace WpfClock { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DispatcherTimer timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromSeconds(1); timer.Tick += Timer_Tick; timer.Start(); } private void Timer_Tick(object sender, EventArgs e) { txtTime.Text = DateTime.Now.ToString("hh:mm:ss tt"); } } } ``` 这个时钟使用了一个 `Ellipse` 控件来表示时钟的外形,使用 `Canvas` 控件来添加时钟的刻度和指针,使用 `TextBlock` 控件来显示当前时间。`DispatcherTimer` 用于每秒更新一次当前时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值