我需要在程序加载时启动我的resetTimer() - 这是怎么做的?

时间:2014-07-18 13:23:30

标签: c# wpf timer

我正在学习一些WPF并编写了这个小程序,它读取数据的Excel文件并在保存时更新UI。只有在第一次保存后,我的ResetTimer()函数才能正常工作。但是GetDisplayData()会加载数据,程序会在保存时更新数据。只有他们的计时器才能在第一次保存之前启动..

但我想让计时器立即启动,以防加载时Excel文件上没有保存事件。

我可以做些什么来让它工作,似乎每当我尝试将它放在window_loaded或我试过的其他地方时,我的程序循环或不加载数据。

感谢您的帮助。

using System;
using System.Data;
using System.IO;
using System.Windows;
using System.Windows.Threading;

namespace WPFReadExcel
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
      private const string ExcelPath = @"C:\";
      private const string ExcelPathFile = @"C:\DataSource.xlsx";
      DataTable _dashBoardData = new DataTable();

      public MainWindow()
      {
        InitializeComponent();
      }

      protected void Window_Loaded(object sender, RoutedEventArgs e)
      {
        GetDisplayData();
        StartFileSystemWatcher();
      }

      public void GetDisplayData()
      {
        var excelData = new ExcelData();
        _dashBoardData = excelData.ReadExcelFile("Live", ExcelPathFile);

         Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
         {
           ExcelDataGrid.ItemsSource = _dashBoardData.AsDataView();
           RefreshDateTime.Content = "Refresh at: " + 
                                      DateTime.Now.ToShortTimeString();
          }
          ));
      }

      private void ResetDisplayData()
      {
        if (_dashBoardData != null) _dashBoardData.Dispose();
        GetDisplayData();
        ResetTimer();

      }

      private void ResetTimer()
      {
        while (true)
        {
          System.Threading.Thread.Sleep(20000);
          ResetDisplayData();
        }
      }

      private void StartFileSystemWatcher()
      {
        if (string.IsNullOrWhiteSpace(ExcelPath))
           return;

        FileSystemWatcher watcher = new FileSystemWatcher();

        // set directory to watch
        watcher.Path = ExcelPath;

       // set what to watch for
       watcher.NotifyFilter = NotifyFilters.LastWrite;

       // set event handlers
       watcher.Changed += new FileSystemEventHandler(watcher_Changed);

       // start watching
       watcher.EnableRaisingEvents = true;
      }

      private void watcher_Changed(object sender, FileSystemEventArgs e)
      {
        ResetDisplayData();
      }

      private void Label_Loaded(object sender, RoutedEventArgs e)
      {
        RefreshDateTime.Content = "Refresh at: " + DateTime.Now.ToShortTimeString();
      }
  }

}

1 个答案:

答案 0 :(得分:2)

Window.Loaded事件是您做任何事情的正确位置:

protected void Window_Loaded(object sender, RoutedEventArgs e)
{
    ResetTimer();
    GetDisplayData();
    StartFileSystemWatcher();
}

但是,您似乎无法在任何地方使用Timer,因此您的问题和方法名称不合适。在WPF中,我们使用DispatcherTimer Class。首先,您需要初始化它然后启动它:

private DispatcherTimer timer = new DispatcherTimer();

...

private void ResetTimer()
{
    timer.Interval = TimeSpan.FromSeconds(20);
    timer.Tick += Timer_Tick;
    timer.Start();
}

private void Timer_Tick(object sender, EventArgs e)
{
    ResetDisplayData();
}

为了您的信息,您实际上无法编写比此更糟糕的代码,因为它会阻止您的用户界面并使您的应用无响应:

while (true)
{
    System.Threading.Thread.Sleep(20000);
    ResetDisplayData();
}