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 |