2015-07-01 9 views
3

Я делаю программу, которая должна иметь часы висит каждый второй, основной проблемой является то, что я новичок в WPF и MVVM :)Время Ticking в C# WPF MVVM

Но в остальном мои часы работает просто не освежающий , У меня есть специальный класс только для целей времени и даты.

Вот мой код:

TimeDate класс:

public class TimeDate : ViewModelBase 
{ 

    public string SystemTimeHours; 
    string SystemTimeLong; 
    string SystemDateLong; 
    string SystemTimeZoneLong; 

    string SystemTimeShort; 
    string SystemDateShort; 
    string SystemTimeZoneShort; 



    public void InitializeTimer() 
    { 

     DispatcherTimer timer = new DispatcherTimer(); 
     timer.Interval = TimeSpan.FromSeconds(1); 
     timer.Tick += new EventHandler(timer_Tick); 
     timer.Start(); 
    } 

    void timer_Tick(object sender, EventArgs e) 
    { 

     SystemTimeHours = DateTime.Now.ToString("HH:mm tt"); 

    } 
} 

ViewModel:

public class ViewModel : ViewModelBase 
{ 
    public ViewModel() 
    { 
     TimeDate td = new TimeDate(); 
     td.InitializeTimer(); 
     HoursTextBox = td.SystemTimeHours; 

    } 



    private string _hourstextbox; 
    public string HoursTextBox 
    { 
     get 
     { return _hourstextbox; } 
     set 
     { 
      if (value != _hourstextbox) 
      { 
       _hourstextbox = value; 
       NotifyPropertyChanged("HoursTextBox"); 
      } 
     } 
    } 
} 

А также NotifyProperty в ViewModelBase:

public class ViewModelBase : INotifyPropertyChanged, IDisposable 
{ 
    #region Constructor 

    protected ViewModelBase() 
    { 
    } 

    #endregion // Constructor 

    #region DisplayName 


    public virtual string DisplayName { get; protected set; } 

    #endregion // DisplayName 

    #region Debugging Aides 

    [Conditional("DEBUG")] 
    [DebuggerStepThrough] 
    public void VerifyPropertyName(string propertyName) 
    { 
     // Verify that the property name matches a real, 
     // public, instance property on this object. 
     if (TypeDescriptor.GetProperties(this)[propertyName] == null) 
     { 
      string msg = "Invalid property name: " + propertyName; 

      if (this.ThrowOnInvalidPropertyName) 
       throw new Exception(msg); 
      else 
       Debug.Fail(msg); 
     } 
    } 


    protected virtual bool ThrowOnInvalidPropertyName { get; private set; } 

    #endregion // Debugging Aides 

    #region INotifyPropertyChanged Members 


    public event PropertyChangedEventHandler PropertyChanged; 


    /// <param name="propertyName">The property that has a new value.</param> 
    protected virtual void NotifyPropertyChanged(string propertyName) 
    { 
     this.VerifyPropertyName(propertyName); 

     PropertyChangedEventHandler handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      var e = new PropertyChangedEventArgs(propertyName); 
      handler(this, e); 
     } 
    } 

    protected virtual void NotifyPropertyChangedAll(object inOjbect) 
    { 
     foreach (PropertyInfo pi in inOjbect.GetType().GetProperties()) 
     { 
      NotifyPropertyChanged(pi.Name); 
     } 
    } 
    public virtual void Refresh() 
    { 
     NotifyPropertyChangedAll(this); 
    } 
    #endregion // INotifyPropertyChanged Members 

    #region IDisposable Members 

    public void Dispose() 
    { 
     this.OnDispose(); 
    } 

    /// <summary> 
    /// Child classes can override this method to perform 
    /// clean-up logic, such as removing event handlers. 
    /// </summary> 
    protected virtual void OnDispose() 
    { 
    } 


    /// </summary> 
    ~ViewModelBase() 
    { 
     string msg = string.Format("{0} ({1}) ({2}) Finalized", this.GetType().Name, this.DisplayName, this.GetHashCode()); 
     System.Diagnostics.Debug.WriteLine(msg); 
    } 


    #endregion // IDisposable Members 

} 

Что делать, что Часы w плохо обновлять каждую секунду? Пожалуйста, помогите

+0

использовать анимацию для запуска часов. http://www.charlespetzold.com/blog/2006/04/070132.html – Will

ответ

1

В MSDN:

Причины использования DispatcherTimer противоположность System.Timers.Timer в том, что DispatcherTimer работает на том же потоке, что и Dispatcher и DispatcherPriority может быть установлен на DispatcherTimer.

Я делаю короткий пример:

XAML:

<Window x:Class="WpfApplication1.MainWindow" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      Title="MainWindow" Height="98" Width="128" 
      xmlns:local="clr-namespace:WpfApplication1"> 
    <Window.DataContext> 
     <!-- This will auto create an instance of ViewModel --> 
     <local:ViewModel /> 
    </Window.DataContext> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="Auto" /> 
     </Grid.RowDefinitions> 
     <Label Name="lblTimer" Grid.Row="1" Content="{Binding Path=CurrentTime}"></Label> 
    </Grid> 
</Window> 

CS:

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 
    } 

    public class ViewModel : ViewModelBase 
    { 
     private string _currentTime; 

     public DispatcherTimer _timer; 

     public string CurrentTime 
     { 
      get 
      { 
       return this._currentTime; 
      } 
      set 
      { 
       if (_currentTime == value) 
        return; 
       _currentTime = value; 
       OnPropertyChanged("CurrentTime"); 
      } 
     } 

     public ViewModel() 
     { 
      _timer = new DispatcherTimer(DispatcherPriority.Render); 
      _timer.Interval = TimeSpan.FromSeconds(1); 
      _timer.Tick += (sender, args) => 
          { 
           CurrentTime = DateTime.Now.ToLongTimeString(); 
          }; 
      _timer.Start(); 
     } 
    } 

    public class ViewModelBase : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

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

enter image description here

Надежда эта помощь.

+0

Спасибо! Что такое «NotifyPropertyChangedInvocator». Visual Studio не находит его (красная подчеркивание) – Pukaai

+0

Я обновил свой пост. Вы можете свободно удалить [NotifyPropertyChangedInvocator] и [CallerMemberName]. Он по-прежнему работает. – hungndv

+0

Да это я уже пробовал (потому что в моем примере тоже нет), но все равно пустые окна. Не показывать никаких часов. Если я отлаживаю его останавливается в MainWindow: D – Pukaai

0

Вы должны указать DispatcherTimer как поле в классе viewmodel, а не только как локальную переменную в ctor.

Сборщик мусора уничтожит все локальные переменные, когда они выходят за рамки.

Вот моя реализация часы :)

public class MainWindowViewModel : ViewModelBase 
{ 
    private readonly DispatcherTimer _timer; 

    public MainWindowViewModel() 
    { 
     _timer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(1)}; 
     _timer.Start(); 
     _timer.Tick += (o, e) => OnPropertyChanged("CurrentTime"); 
    } 

    public DateTime CurrentTime { get { return DateTime.Now; } } 
} 

<TextBlock Text="{Binding CurrentTime, StringFormat={}{0:HH:mm tt}}" /> 
+0

Спасибо !!!!!!!!! – Pukaai