Window/WPF2010. 1. 26. 17:42

DispatcherTimer, DependencyProperty, IValueConverter 이용해

위젯 형식의 간단한 시계 컨트롤을 만드는 방법에 대해 포스팅 하겠습니다.

 

결과물은 다음과 같습니다.

하나의 클래스를 통해 2개의 시계를 만들어 마우스 오른쪽 버튼을 누를 때마다 변경되도록 하였습니다.

드래그 :  마우스 왼쪽 버튼

종료 : ESC 버튼

 

         

           < 아날로그 >                                  < 디지털 >

 

 

우선 시계 모양으로 쓰일 이미지가 필요하겠죠.

위의 이미지는 배드걸 님의 블로그에서 얻을 수 있었습니다. 감사합니다.^^

 

이제 소스를 살펴보겠습니다.

코드가 짧기 때문에 이해가 쉬우실 겁니다.

 

우선 DateTime형식의 DependencyProperty를 생성 후 ClockTimer가 초기화가 될 때 타이머를 발생시킵니다.

타이머가 발생할 때마다 현재 DateTime 값으로 프로퍼티 값을 변경 시켜줍니다.

 

   10 class ClockTimer : FrameworkElement

   11 {

   12     private DispatcherTimer timer;

   13 

   14     private static DependencyProperty DateTimeProperty =

   15         DependencyProperty.Register("DateTime", typeof(DateTime), typeof(ClockTimer),

   16         new PropertyMetadata(DateTime.Now));

   17 

   18     protected override void OnInitialized(EventArgs e)

   19     {

   20         base.OnInitialized(e);

   21 

   22         timer = new DispatcherTimer();

   23         timer.Interval = TimeSpan.FromMilliseconds(1000);

   24         timer.Tick += new EventHandler(Timer_Tick);

   25         timer.Start();

   26     }

   27 

   28     private void Timer_Tick(object sender, EventArgs e)

   29     {

   30         SetValue(DateTimeProperty, DateTime.Now);

   31     }

   32 }

 

이제 이를 바인딩 용도에 맞게 IValueConverter를 사용 해 클래스들을 작성합니다.

다음은 초침을 위한 Converter입니다. 간단한 산수를 활용해(-_-;) 현재 각도를 구합니다.

   34 [ValueConversion(typeof(DateTime), typeof(int))]

   35 public class SecondsConverter : IValueConverter

   36 {

   37     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

   38     {

   39         DateTime date = (DateTime)value;

   40         return ((DateTime)value).Second * 6;

   41     }

   42 

   43     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

   44     {

   45         return null;

   46     }

   47 }

 

이제 이를 사용할 객체의 Resorces로 등록합니다.

<Grid.Resources>
   <clock:SecondsConverter x:Key="SecondsConverter"/>
   <clock:MinutesConverter x:Key="MinutesConverter"/>
   <clock:HoursConverter x:Key="HoursConverter"/>
   <clock:TimeStringConverter x:Key="TimeStringConverter"/>
    <clock:DateConverter x:Key="DateConverter"/>
</Grid.Resources>

 

마지막으로 ClockTimer 클래스 추가 후 알맞게 바인딩 합니다.

xmlns:clock="clr-namespace:WPFClock"

 

<clock:ClockTimer x:Name="Clock"/>

 

<RotateTransform Angle="{Binding Path=DateTime, Converter={StaticResource SecondsConverter}, ElementName=Clock}"/>

 

Text="{Binding Path=DateTime, Converter={StaticResource DateConverter}, ElementName=Clock}"

 

시계의 바늘들의 회전 중심을 맞추기가 약간 까다로웠지만

Height 값 만큼 Margin 값을 변경 시킨 후 RenderTransformOrigin 의 값을 변경하여 맞출 수 있었습니다.

 

 Height="42" Margin="0,0,0,42" RenderTransformOrigin="0.5,1"

 

자신이 원하는 이미지로 간단한 시계를 만들어 사용하는 것도 괜찮겠네요.

 

'Window > WPF' 카테고리의 다른 글

[ WPF ] Window 사이즈 변경 시 컨트롤 크기 변경하기  (3) 2010.02.08
[WPF] Object Capture  (0) 2010.01.29
[WPF] Image Pixel  (0) 2010.01.24
[WPF] Drag, Scale, Rotate  (1) 2010.01.24
[ WPF ] Drag  (0) 2009.09.27
Posted by 열ㅇl