0

I have a timer object:

class GameTimer
{
    private CancellationTokenSource cancellation;
    BindingClass bindingClass;
    public GameTimer(BindingClass bindingClass)
    {
        this.bindingClass = bindingClass;
        cancellation = new CancellationTokenSource();
    }
    public void Start()
    {
        bindingClass.SecondsElapsed = 20;
        CancellationTokenSource cts = cancellation;
        Device.StartTimer(new TimeSpan(0, 0, 1), () =>
        {
            if (cts.IsCancellationRequested) return false;
            if (bindingClass.SecondsElapsed > 0)
            {
                bindingClass.SecondsElapsed--;
            }
            return true;
        });
    }
    public void Stop()
    {
        Interlocked.Exchange(ref this.cancellation, new CancellationTokenSource()).Cancel();
    }
}

Another object that holds some variables:

public class BindingClass : INotifyPropertyChanged
{
    private int _secondsElapsed;
    public int SecondsElapsed
    {
        get { return _secondsElapsed; }
        set
        {
            if (_secondsElapsed != value)
            {
                _secondsElapsed = value;
                OnPropertyChanged();
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string name = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

And a main page:

public partial class GamePage : ContentPage
{
    private int currentSelector;
    private int selectorCount = 0;
    TapGestureRecognizer tapGestureRecognizer = new TapGestureRecognizer();
    Image img;
    BindingClass bindingClass;
    GameTimer gameTimer;
    public GamePage(BindingClass bindingClass)
    {
        InitializeComponent();
        this.bindingClass = bindingClass;
        gameTimer = new GameTimer(bindingClass);
        gameTimer.Start();
        this.BindingContext = this.bindingClass;
        NavigationPage.SetHasNavigationBar(this, false);
    }
}

What would be the proper to display some sort of alert or at least some event, like after the SecondsElapsed reaches 0? I tried putting a DisplayAlert inside set{}, but it does not show any pop-up:

public class BindingClass : INotifyPropertyChanged
{
    private static Page page = new Page();
    private int _secondsElapsed;
    public int SecondsElapsed
    {
        get { return _secondsElapsed; }
        set
        {
            if (_secondsElapsed == 0)
            {
                page.DisplayAlert("AW", "AW", "AW");
            }
            if (_secondsElapsed != value)
            {
                _secondsElapsed = value;
                OnPropertyChanged();
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string name = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

I don't know if I can call some functions or fire some event inside BindingClass.

Carl Binalla
  • 5,153
  • 5
  • 25
  • 44
  • You never assigned anything to `BindingClass.page` – Camilo Terevinto Jan 22 '18 at 09:22
  • @CamiloTerevinto Actually I'm not here for the `NullReferenceException`, I just shared what happened in my trials. but thanks for the heads-up – Carl Binalla Jan 22 '18 at 09:23
  • First make sure that `page` is set to some value, and then make sure to invoke the alert on the main (UI) thread. `Device.BeginInvokeOnMainThread(async () => { await page.DisplayAlert("", "", "Ok"); });`. Though you don't even need a static reference to the page. You can simply call the current page's methods like so: `await MyProject.App.Current.MainPage.DisplayAlert("", "", "");` – sme Jan 22 '18 at 10:57
  • @sme I added `Device.BeginInvokeOnMainThread(async () => { await MyProject.App.Current.MainPage.DisplayAlert("aw", "aw", "ok"); });` inside `set{}`, but still no alert. Would that be correct, or should it be put elsewhere? – Carl Binalla Jan 23 '18 at 03:59
  • @Swellar it should be fine, are you sure that `_secondsElapsed` is ever being set to 0? EDIT: perhaps you should instead be checking `if (value == 0)` instead of `if (_secondsElapsed == 0)`, because _secondsElapsed will only be set to 0 after the check. – sme Jan 23 '18 at 04:03
  • @sme I tried putting `SecondsElapsed = 20;` inside the `if` statement, but the app stops. But when I use `value ==0`, the app does not stop, but the timer is not resetting. I also tried `value == 0` in displaying an alert, but still no display – Carl Binalla Jan 23 '18 at 05:30
  • @sme I tried using `value == 1` instead, and `SecondsElapsed = 20` is now working. But I can't still display any alert at all – Carl Binalla Jan 23 '18 at 05:52
  • @sme Is there a way to fire an event in `GamePage` from `BindingClass`? – Carl Binalla Jan 23 '18 at 06:01
  • @Swellar I looked at your code a bit more closely, try decreasing the setter like this instead: `secondsElapsed -= 1;` or `secondsElapsed = secondsElapsed - 1;`, I think using the decrement operator does not actually "set" the property, although I could be wrong. Also, put a `System.Diagnostics.Debug.WriteLine("value is 0");` inside the `if (value == 0)` block, just to confirm its actually reaching that section of code. – sme Jan 23 '18 at 06:09
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/163685/discussion-between-swellar-and-sme). – Carl Binalla Jan 23 '18 at 06:13

0 Answers0