简体   繁体   中英

C# WPF - How to auto refresh the UI after run it

I created in the XAML a simple Label called TbTimer

I made the following code:

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();
    }
}

Then I have another button, and I call TimerUpdater when that button is clicked.

When I run the program and I click the button, I can see that the content of the TextBlock shows the number 1... and it does not continue to run the numbers - when I click the button again after 5 seconds it shows the number 6.

So I guess the timer is running fine behind the scenes, but the content of the TextBlock is updated only when I click the button.

What should I do to make the TextBlock content update the seconds without clicking the button? Hope my explanation and question is clear.

With your modified code, the answer changes completely. I apologize for the dramatic change in content. The "simplest" way to accomplish this would be to add an event for the counter updating and have your UI subscribe to it. Something like:

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();
    }
}

Incidentally, this ends up being similar to how the binding system is set up. If you just bound your textbox to the counter variable, it would be much cleaner and easier to use. To do that, you would change your XAML to:

<TextBox Name="TbTimer" Text="{Binding Counter}"/>

and assign the DataContext:

public class MainWindow
{
    public MainWindow()
    {
       InitializeComponent();

       lvl2 = new Level2();
       DataContext = lvl2;
    }

    private void MenuItemMedium_Click(object sender, RoutedEventArgs e)
    {
        lvl2.timer.Start();
    }
}

Level2 now needs to implement INotifyPropertyChanged, and you have to make counter a property (so it can be bound to):

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++;
    }
}

The binding system will now update the text box automatically when the timer ticks (and increments the Counter property. This is the way it should be done in WPF, so feel free to ask any questions that come up when implementing it.

For reference, this is the implemenation of INofityPropertyChanged I used: http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM