写了一个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>

1086

被折叠的 条评论
为什么被折叠?



