2011-05-08 2 views
1

저는 아날로그 시계와 디지털 시계 디스플레이가 있습니다. 그러나 MVVM 패턴을 사용하고 싶습니다. 나는 어디에서 시작해야할지 모른다. 이 일을 성취하는 방법? 내가 가지고있는 것을 패턴으로 변환하는 것은 그렇게 어렵지 않아야합니다. 모델 클래스와 뷰 클래스가 필요합니까?MVVM 패턴이 작동합니까?

가능한 한 간단하게 만들고 싶습니다. 나는 패턴을 얻으면 두 명의 타이머가 필요 없다고 확신합니다.

이것은 내가 지금까지 가지고있는 것입니다. 저는 현재 디지털 용 타이머와 아날로그 용 타이머 2 개를 보유하고 있습니다. 이것은 내가 아는 것은 나쁘다. 나는 그것을 필요로하지 않을 것이다. XAML 코드에 대한

public partial class MainWindow : Window 
{ 
    System.Timers.Timer timer = new System.Timers.Timer(1000); //analog clock 
    DispatcherTimer timerdigital;        // digital clock 

    public MainWindow() { 
     this.InitializeComponent(); 

     //analog clock 
     timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); 
     timer.Enabled = true; 

     //digital clock 
     timerdigital = new DispatcherTimer(); 
     timerdigital.Interval = TimeSpan.FromSeconds(1.0); 
     timerdigital.Start(); 
     timerdigital.Tick += new EventHandler(delegate(object s, EventArgs a) 
     { 
      tbDigital.Text = DateTime.Now.ToString("hh:mm:ss tt"); 
     }); 
    } 

    //analog clock 
    void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { 
     this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => 
     { 
      secondHand.Angle = DateTime.Now.Second * 6; 
      minuteHand.Angle = DateTime.Now.Minute * 6; 
      hourHand.Angle = (DateTime.Now.Hour * 30) + (DateTime.Now.Minute * 0.5); 
     })); 
    } 

, 나는 내가 필요하다면이 다른 작업을 수행 기꺼이이

<Rectangle Fill="#FFF21313" Margin="85,28,86,0" Name="rectangleSecond" Opacity="0.8" RadiusX="1" RadiusY="1" RenderTransformOrigin="0.5,1" Stroke="#FFDCDCDC" StrokeDashCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeStartLineCap="Round" StrokeThickness="1" Height="64" VerticalAlignment="Top" Width="5"> 
    <Rectangle.RenderTransform> 
     <TransformGroup> 
      <ScaleTransform ScaleX="1" ScaleY="1" /> 
      <SkewTransform AngleX="0" AngleY="0" /> 
      <RotateTransform x:Name="secondHand" Angle="0" /> 
      <TranslateTransform X="0" Y="0" /> 
     </TransformGroup> 
    </Rectangle.RenderTransform> 
</Rectangle> 
<Rectangle Fill="#FF181818" Margin="85,27,85,88" Name="rectangleMinute" Opacity="0.8" RadiusX="1" RadiusY="1" RenderTransformOrigin="0.5,1" Stroke="#FFDCDCDC" StrokeDashCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeStartLineCap="Round" StrokeThickness="1"> 
    <Rectangle.RenderTransform> 
     <TransformGroup> 
      <ScaleTransform ScaleX="1" ScaleY="1" /> 
      <SkewTransform AngleX="0" AngleY="0" /> 
      <RotateTransform x:Name="minuteHand" Angle="0" /> 
      <TranslateTransform X="0" Y="0" /> 
     </TransformGroup> 
    </Rectangle.RenderTransform> 
</Rectangle> 
<Rectangle Fill="#FF070707" HorizontalAlignment="Left" Margin="86,46,0,89" Name="rectangleHour" Opacity="0.8" RadiusX="1" RadiusY="1" RenderTransformOrigin="0.5,1" Stroke="#FFDCDCDC" StrokeDashCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeStartLineCap="Round" StrokeThickness="1" Width="5"> 
    <Rectangle.RenderTransform> 
     <TransformGroup> 
      <ScaleTransform ScaleX="1" ScaleY="1" /> 
      <SkewTransform AngleX="0" AngleY="0" /> 
      <RotateTransform x:Name="hourHand" Angle="0" /> 
      <TranslateTransform X="0" Y="0" /> 
     </TransformGroup> 
    </Rectangle.RenderTransform> 
</Rectangle> 

처럼 손을 끌었다.

+0

코드없이 코드가 구현 된 것을 보았습니다. 현재 링크를 찾을 수 없지만 애니메이션과 RotateTransform을 사용하여 손을 움직일뿐입니다. 그 일은 꽤 간단합니다. 디지털 시계의 부품 가시성을 살리기 위해 동일한 작업을 수행 할 수 있습니다. – Will

답변

6

두 개의 다른 타이머를 사용하는 이유가 확실하지 않지만 동일한 타이머를 사용할 수 있습니다.

코드를 ViewModel에 넣고 뷰를 ViewModel의 속성에 바인딩하기 만하면됩니다.

는 뷰 모델

public class ClockViewModel : INotifyPropertyChanged 
{ 
    private readonly System.Timers.Timer _timer; 

    public ClockViewModel() 
    { 
     _timer = new System.Timers.Timer(1000); 
     _timer.Elapsed += _timer_Elapsed; 
     _timer.Start(); 
    } 

    private void _timer_Elapsed(object sender, EventArgs e) 
    { 
     DateTime now = DateTime.Now; 
     DigitalTime = now.ToString("hh:mm:ss tt"); 
     SecondAngle = now.Second * 6; 
     MinuteAngle = now.Minute * 6; 
     HourAngle = (now.Hour * 30) + (now.Minute * 0.5); 
    } 

    private string _digitalTime; 
    public string DigitalTime 
    { 
     get { return _digitalTime;} 
     set 
     { 
      _digitalTime = value; 
      OnPropertyChanged("DigitalTime"); 
     } 
    } 


    private double _hourAngle; 
    public double HourAngle 
    { 
     get { return _hourAngle;} 
     set 
     { 
      _hourAngle = value; 
      OnPropertyChanged("HourAngle"); 
     } 
    } 


    private double _minuteAngle; 
    public double MinuteAngle 
    { 
     get { return _minuteAngle;} 
     set 
     { 
      _minuteAngle = value; 
      OnPropertyChanged("MinuteAngle"); 
     } 
    } 

    private double _secondAngle; 
    public double SecondAngle 
    { 
     get { return _secondAngle;} 
     set 
     { 
      _secondAngle = value; 
      OnPropertyChanged("SecondAngle"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

XAML

<Rectangle Fill="#FFF21313" Margin="85,28,86,0" Name="rectangleSecond" Opacity="0.8" RadiusX="1" RadiusY="1" RenderTransformOrigin="0.5,1" Stroke="#FFDCDCDC" StrokeDashCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeStartLineCap="Round" StrokeThickness="1" Height="64" VerticalAlignment="Top" Width="5"> 
    <Rectangle.RenderTransform> 
     <RotateTransform Angle="{Binding SecondAngle}" /> 
    </Rectangle.RenderTransform> 
</Rectangle> 
<Rectangle Fill="#FF181818" Margin="85,27,85,88" Name="rectangleMinute" Opacity="0.8" RadiusX="1" RadiusY="1" RenderTransformOrigin="0.5,1" Stroke="#FFDCDCDC" StrokeDashCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeStartLineCap="Round" StrokeThickness="1"> 
    <Rectangle.RenderTransform> 
     <RotateTransform Angle="{Binding MinuteAngle}" /> 
    </Rectangle.RenderTransform> 
</Rectangle> 
<Rectangle Fill="#FF070707" HorizontalAlignment="Left" Margin="86,46,0,89" Name="rectangleHour" Opacity="0.8" RadiusX="1" RadiusY="1" RenderTransformOrigin="0.5,1" Stroke="#FFDCDCDC" StrokeDashCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeStartLineCap="Round" StrokeThickness="1" Width="5"> 
    <Rectangle.RenderTransform> 
     <RotateTransform Angle="{Binding HourAngle}" /> 
    </Rectangle.RenderTransform> 
</Rectangle> 

단지 인스턴스를 할당 코드 숨김에서

(나는하여 RotateTransforms가 사용 된 경우에만 이후 TransformGroups을 제거) ClockViewModelDataContext.

+1

보기의 생성자 (Window 또는 UserControl)를 의미합니다. [DataContext] (http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.datacontext.aspx) –

+0

에 대한 설명서를 참조하십시오. 나는 많은 연구를 수행했으며 일부 자습서를 따랐습니다. 두 번째 손을 일하게. C++과 WPF를 배우려는 C++ 배경에서 왔습니다. –

+1

"Angle"속성을 개인 집합으로 만들려는 경우가 있습니다. 그들이 현재 시간의 함수이기 때문에 외부 요소가 각도를 수정하는 것은 실제로 이해가되지 않습니다. – cordialgerm