WPF写的时钟组件

写了一个WPF 时钟组件,效果如下,UI没有美化过,所以比较简陋。

 

CS代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace OtherControl
{
    [TemplatePart(Name = Clock.SECOND_RECT, Type = typeof(Rectangle))]
    [TemplatePart(Name = Clock.HOUR_RECT, Type = typeof(Rectangle))]
    [TemplatePart(Name = Clock.MINUTE_RECT, Type = typeof(Rectangle))]
    [TemplatePart(Name = Clock.TXTTIMRSTR, Type = typeof(TextBlock))]
    public class Clock : Control
    {
        public const string SECOND_RECT = "secondRect";
        public const string HOUR_RECT = "hourRect";
        public const string MINUTE_RECT = "miniuteRect";
        public const string TXTTIMRSTR = "txtTimeStr";

        private RotateTransform _rotateSecondTransform = new RotateTransform();
        private RotateTransform _rotateHorTransform = new RotateTransform();
        private RotateTransform _rotateMiniuteTransform = new RotateTransform();
        private DispatcherTimer _timer;
        private TextBlock _textTimeStr;

        public Clock()
        {
            DialAngles = new Int32Collection();
            _timer = new DispatcherTimer();
            _timer.Tick += _timer_Tick; ;
            _timer.Interval = TimeSpan.FromSeconds(1);
        }

        private void _timer_Tick(object sender, EventArgs e)
        {
            var dateTimeNow = DateTime.Now;
            var hour = dateTimeNow.Hour + 1;
            if (hour >= 12) hour -= 12;
            var hourPersent = hour * 1.0 / 12;
            var secondPersent = dateTimeNow.Second * 1.0 / 60;
            _rotateHorTransform.Angle = hourPersent * 360 - 30;
            _rotateSecondTransform.Angle = secondPersent * 360;

            var miniutePresend = dateTimeNow.Minute * 1.0 / 60;
            _rotateMiniuteTransform.Angle = miniutePresend * 360;
            _textTimeStr.Text = dateTimeNow.ToLongTimeString();
        }

        public override void OnApplyTemplate()
        {
            CenterY = Height / 2;
            DrawClockDial();
            ApplyClockHand();
            _timer_Tick(null, null);
            _timer.Start();
        }
        public Int32Collection DialAngles { get; set; }
        public double CenterY { get; set; }
        private void DrawClockDial()
        {
            for (int i = 0; i < 12; i++)
            {
                DialAngles.Add(i * 30);
            }
        }

        private void ApplyClockHand()
        {
            _textTimeStr = GetTemplateChild(TXTTIMRSTR) as TextBlock;

            _rotateHorTransform.CenterX = 0;
            _rotateHorTransform.CenterY = Height / 2;
            _rotateHorTransform.Angle = 10;

            _rotateSecondTransform.CenterX = 0;
            _rotateSecondTransform.CenterY = Height / 2;
            _rotateSecondTransform.Angle = 10;

            _rotateMiniuteTransform.CenterX = 0;
            _rotateMiniuteTransform.CenterY = Height / 2;
            _rotateMiniuteTransform.Angle = 5;

            var hourRectangle = GetTemplateChild(HOUR_RECT) as Rectangle;
            TranslateTransform hourTransform = new TranslateTransform() { Y = Height / 2 - hourRectangle.Height};
            TransformGroup hourTransforms = new TransformGroup();
            hourTransforms.Children.Add(hourTransform);
            hourTransforms.Children.Add(_rotateHorTransform);
            hourRectangle.RenderTransform = hourTransforms;

            var secodRect = GetTemplateChild(SECOND_RECT) as Rectangle;
            secodRect.RenderTransform = _rotateSecondTransform;

            var minituteRect = GetTemplateChild(MINUTE_RECT) as Rectangle;

            TranslateTransform miniuteTransform = new TranslateTransform() { Y = Height / 2 - minituteRect.Height, X = -minituteRect.Width/2 };
            TransformGroup miniuteTransforms = new TransformGroup();
            miniuteTransforms.Children.Add(miniuteTransform);
            miniuteTransforms.Children.Add(_rotateMiniuteTransform);
            minituteRect.RenderTransform = miniuteTransforms;
        }
    }
}

Style代码:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:OtherControl">

    <local:AngleToNumberConvert x:Key="angleToToNumberConvert"/>
    <local:NumberToHalfValueConvert x:Key="numberToHalfValueConvert"/>
    <local:NumberToPersentConvert x:Key="numberToPersentConvert"/>

    <Style TargetType="local:Clock">
        <Setter Property="Width" Value="400"/>
        <Setter Property="Height" Value="400"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:Clock">
                    <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
                        <!--<Ellipse Stroke="Red" Fill="Red" StrokeThickness="1" Margin="0,0,0,0" VerticalAlignment="Top" Width="10" Height="10"/>-->
                        <Ellipse Stroke="Black" StrokeThickness="1"/>

                        <Rectangle HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="secondRect"
                            Height="{TemplateBinding Height, Converter={StaticResource numberToPersentConvert}, ConverterParameter=0.5}" Fill="Red" Width="2"/>

                        <Rectangle HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="hourRect" Opacity=".5"
                            Height="{TemplateBinding Height, Converter={StaticResource numberToPersentConvert}, ConverterParameter=0.2}" Fill="Black" Width="4"/>

                        <Rectangle HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="miniuteRect"
                            Height="{TemplateBinding Height, Converter={StaticResource numberToPersentConvert}, ConverterParameter=0.3}" Fill="Black" Width="4"/>

                        <Ellipse Width="10" Height="10" Fill="Black" HorizontalAlignment="Center" VerticalAlignment="Center"/>

                        <TextBlock HorizontalAlignment="Center" Name="txtTimeStr" VerticalAlignment="Bottom" FontSize="20" Margin="0,0,0,50"/>

                        <!--<Rectangle Height="{TemplateBinding Height, Converter={StaticResource numberToPersentConvert}, ConverterParameter=0.5}"/>-->
                        
                        <ItemsControl Width="{TemplateBinding Width}" Name="itemsControl" Height="{TemplateBinding Height}" 
                                      Tag="{Binding CenterY,RelativeSource={RelativeSource Mode=TemplatedParent}}" 
                                      ItemsSource="{Binding DialAngles,RelativeSource={RelativeSource Mode=TemplatedParent}}">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <Grid/>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Border  Width="16" Height="40" Name="border" VerticalAlignment="Top" HorizontalAlignment="Center">
                                        <Border.RenderTransform>
                                            <RotateTransform Angle="{Binding}" 
                                                             CenterX="{Binding Width, 
                                                ElementName=border,
                                                Converter={StaticResource numberToHalfValueConvert}}" 
                                                             
                                                             CenterY="{Binding Height,
                                                ElementName=itemsControl, 
                                                Converter={StaticResource numberToHalfValueConvert}}" x:Name="rotate"/>
                                        </Border.RenderTransform>
                                        <StackPanel>
                                            <Rectangle Fill="Black" Width="5" Height="20"/>
                                            <TextBlock Text="{Binding Path =Angle, ElementName=rotate, Converter={StaticResource angleToToNumberConvert}}" 
                                                       FontSize="14"/>
                                        </StackPanel>
                                    </Border>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值