Я создал в XAML простой Label
под названием TbTimer
Я сделал следующий код:
class Level2
{
public Level2()
{
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
}
public int counter;
public void timer_Tick(object sender, EventArgs e)
{
counter++;
}
public DispatcherTimer timer;
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
lvl2 = new Level2();
}
private void MenuItemMedium_Click(object sender, RoutedEventArgs e)
{
lvl2.timer.Start();
TbTimer.Content = lvl2.counter.ToString();
}
}
Затем у меня есть еще одна кнопка, и я вызываю TimerUpdater
когда эта кнопка нажата.
Когда я запускаю программу, и я нажимаю кнопку, я вижу, что содержимое TextBlock
показывает номер 1... и оно не продолжает запускать числа - когда я снова нажимаю кнопку через 5 секунд, она показывает номер 6.
Поэтому я думаю, что таймер работает отлично за кулисами, но содержимое TextBlock
обновляется только тогда, когда я нажимаю кнопку.
Что делать, чтобы содержимое TextBlock
обновляло секунды, не нажимая кнопку? Надеюсь, мое объяснение и вопрос ясны.
С измененным кодом ответ полностью меняется. Я прошу прощения за резкое изменение содержания. "Самый простой" способ сделать это - добавить событие для обновления счетчика и подписать его пользовательский интерфейс. Что-то вроде:
class Level2
{
public event Action<int> CounterUpdated;
...
public void timer_Tick(object sender, EventArgs e)
{
counter++;
if (CounterUpdated != null)
CounterUpdated(counter);
}
}
public class MainWindow
{
public MainWindow()
{
InitializeComponent();
lvl2 = new Level2();
lvl2.CounterUpdated += UpdateCounterText;
}
private void MenuItemMedium_Click(object sender, RoutedEventArgs e)
{
lvl2.timer.Start();
}
private void UpdateCounterText(int newCounterValue)
{
TbTimer.Content = newCounterValue.ToString();
}
}
Кстати, это в конечном итоге похоже на то, как настроена система привязки. Если вы просто привязали свой текстовый блок к переменной counter
, это было бы намного чище и проще в использовании. Для этого вы измените свой XAML на:
<TextBox Name="TbTimer" Text="{Binding Counter}"/>
и назначьте DataContext:
public class MainWindow
{
public MainWindow()
{
InitializeComponent();
lvl2 = new Level2();
DataContext = lvl2;
}
private void MenuItemMedium_Click(object sender, RoutedEventArgs e)
{
lvl2.timer.Start();
}
}
Level2
теперь должен реализовать INotifyPropertyChanged, и вы должны сделать counter свойством (поэтому он может быть связан):
class Level2 : INotifyPropertyChanged
{
//Notify Property Changed Implementation from MSDN:
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private int counter = 0;
public int Counter
{
get { return counter; }
set
{
counter = value;
NotifyPropertyChanged();
}
}
...
public void timer_Tick(object sender, EventArgs e)
{
Counter++;
}
}
Система привязки теперь обновит текстовое поле автоматически, когда таймер отметит (и увеличит свойство Counter
. Это так, как это должно быть сделано в WPF, поэтому не стесняйтесь задавать любые вопросы, возникающие при его реализации.
Для справки, это реализация INofityPropertyChanged
я использовал: http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx