我在 XAML 中创建了一个名为 TbTimer
的简单 Label
我编写了以下代码:
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
内容更新秒数而不点击按钮?希望我的解释和问题很清楚。
最佳答案
通过修改代码,答案完全改变。对于内容的巨大变化,我深表歉意。实现此目的的“最简单”方法是添加一个计数器更新事件并让您的 UI 订阅它。像这样的东西:
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();
}
}
顺便说一句,这最终与绑定(bind)系统的设置方式类似。如果您只是将文本框绑定(bind)到 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 设置为属性(以便可以将其绑定(bind)到):
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++;
}
}
绑定(bind)系统现在将在计时器计时时自动更新文本框(并递增 Counter
属性。这是在 WPF 中应该完成的方式,因此请随意提出实现过程中出现的任何问题。
作为引用,这是我使用的 INofityPropertyChanged
的实现:http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx
关于C# WPF - 如何在运行后自动刷新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24210046/