C# WPF - 如何在运行后自动刷新 UI

标签 c# wpf refresh

我在 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/

相关文章:

c# - 从静态类调用方法,传递带有泛型的动态变量类型

c# - Caliburn.Micro-OnDeactivate不触发

c# - 尝试更改 DataGrid 中的单元格颜色时出现 WPF 表单中的 InvalidOperationException

c# - 从 DetailsView 中检索数据

c# - "a@bbb..com"是有效的电子邮件地址吗?根据 MailAddress 类,它是

c# - 取消订阅 observableCollection 中的事件

wpf - 触发器 "Checked/Unchecked"未在三态复选框中触发

android - Android ListView 如何刷新?

Swift:如何让 webview 重新加载它的 url

Android RecyclerView 绘图问题(闪烁)