更改页面时如何停止Device.StartTimer()?

时间:2018-11-29 19:25:18

标签: c# xamarin.forms

我有一个ListView,我将使用Device.StartTimer()每5秒更新一次,我想在计时器离开ViewModel页面时停止它。因为您必须知道necsito这样做是因为Device.StartTimer()是全局的,即使当我更改页面仍在更新ListView时,如何使ViewModel知道我正在更改页面?

这是我的ViewModel的一部分:

private ObservableCollection sensors;

public ObservableCollection<PcData> Sensors
{
    get { return sensors; }
    set
    {
        sensors = value;
        OnPropertyChanged();
    }
}


public MonitoringTabsViewModel(string idCode, string description)
{
    Description = description;
    LoadSensors(idCode);
    Device.StartTimer(TimeSpan.FromSeconds(5), () =>
    {
        RefreshSensors(idCode);
        return true;
    });
}

private async void LoadSensors(string idCode)
{
    Sensors = new ObservableCollection<PcData>(await App.WebApiManager.GetCurrentStatusDeviceAsync(idCode));
}

private async void RefreshSensors(string idCode)
{
    Sensors = null;
    Sensors = new ObservableCollection<PcData>(await App.WebApiManager.GetCurrentStatusDeviceAsync(idCode));
}

最后,我来到了下面的实现中,它实际上做了我想要的: ViewModel:

public class MonitoringTabsViewModel : Notificable
{
    public string IdCode { get; set; }

    public bool InPage { get; set; }

    private string description;

    public string Description
    {
        get { return description; }
        set
        {
            description = value;
            OnPropertyChanged();
        }
    }

    private ObservableCollection<PcData> sensors;

    public ObservableCollection<PcData> Sensors
    {
        get { return sensors; }
        set
        {
            sensors = value;
            OnPropertyChanged();
        }
    }


    public MonitoringTabsViewModel(string idCode, string description)
    {
        IdCode = idCode;
        Description = description;
        LoadSensors(idCode);
        MessagingCenter.Subscribe<MonitoringView>(this, "OnAppearing", (sender) =>
        {
            InPage = true;
        });
        MessagingCenter.Subscribe<MonitoringView>(this, "OnDisAppearing", (sender) =>
        {
            InPage = false;
        });
        Device.StartTimer(TimeSpan.FromSeconds(5), TimerCallBack);
    }

    private bool TimerCallBack()
    {
        if (InPage)
        {
            RefreshSensors(IdCode);
            MessagingCenter.Unsubscribe<MonitoringView>(this, "OnAppearing");
            return true;
        }
        else
        {
            MessagingCenter.Unsubscribe<MonitoringView>(this, "OnDisAppearing");
            return false;
        }
    }

    private async void LoadSensors(string idCode)
    {
        Sensors = new ObservableCollection<PcData>(await App.WebApiManager.GetCurrentStatusDeviceAsync(idCode));
    }

    private async void RefreshSensors(string idCode)
    {
        Sensors = null;
        Sensors = new ObservableCollection<PcData>(await App.WebApiManager.GetCurrentStatusDeviceAsync(idCode));
    }

}

查看:

protected override void OnAppearing()
{
    base.OnAppearing();
    MessagingCenter.Send<MonitoringView>(this, "OnAppearing");
}

protected override void OnDisappearing()
{
    base.OnDisappearing();
    MessagingCenter.Send<MonitoringView>(this, "OnDisAppearing");
}

仍然有两件事与我有关: 1.我不知道我对MessagingCenter进行的管理是否合适,如您所见,我通过在对unsubscribe方法的两个调用中放置断点而取消了对TimerCallBack方法的预订,我看到在计时器处于每5秒运行一次仍然调用onAppearing消息的取消订阅方法。 2.尽管这种实现有效,但我仍然有一个问题,当使应用程序处于休眠状态或将其置于后台时,我的方法RefreshSensors()仍然运行,并且我想在segudno flat中也停止执行。

有人能给我关于我仍然存在的这两个问题的想法吗?

2 个答案:

答案 0 :(得分:1)

Page有2种指示符方法OnAppearing()OnDisappearing()取决于您的设置,您应该挂接到此事件并通知ViewModel

这可以通过多种方式完成:

  • Page可能具有对ViewModel的直接或间接引用(BindingContext),因此只是连接。
  • 您可以使用MessagingCenter
  • 如果您有定制的手工制作的NavigationService,则可以在此处进行连接。
  • 使用现有的MVVM框架,其中有很多,其中大多数都支持这种情况

答案 1 :(得分:0)

  

我仍然有一个问题,当使应用程序处于休眠状态或将其放入时   在后台仍在运行我的方法RefreshSensors()

如果您查看App.xaml.cs文件,则会发现以下方法:

protected override void OnStart()
{
    // Handle when your app starts
}

protected override void OnSleep()
{
    // Handle when your app sleeps
}

protected override void OnResume()
{
    // Handle when your app resumes
}