我正在尝试创建一个ListView,它每5秒刷新一次其内容,为此,我正在使用Device.StartTimer(),我设法使其工作,但是我注意到Device.StartTimer ()对于应用程序是全局的,即使我更改页面或更改设备上的应用程序,回调中的内容仍在运行。
我的问题是:更改页面和更改应用程序时如何使计时器停止计时?
到目前为止,我已经取得了一些进展,那就是使用OnAppearing,OnDisAppearing和MessagingCenter,我设法在计时器停止时更改了页面。
使用此实现,我担心我真的不知道我是否真的取消订阅该消息,这是正确的位置,我也希望有人也告诉我。
以下是我的View和ViewModel的片段:
查看:
public partial class MonitoringView : TabbedPage
{
MonitoringViewModel context = new MonitoringViewModel();
public MonitoringView()
{
InitializeComponent();
BindingContext = context;
}
protected override void OnAppearing()
{
base.OnAppearing();
MessagingCenter.Send<MonitoringView>(this, "OnAppearing");
}
protected override void OnDisappearing()
{
base.OnDisappearing();
MessagingCenter.Send<MonitoringView>(this, "OnDisAppearing");
}
}
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));
}
}
答案 0 :(得分:0)
解决方案:
使用此实现,我担心我真的不知道自己是否 真的取消订阅了邮件
要测试您是否确实已取消订阅消息,可以在调试与VS连接的应用程序时将breakpoint
添加到RefreshSensors
函数中。
然后,您可以在离开MessagingCenter.Send<MonitoringView>(this, "OnAppearing");
来查看MonitoringView
是否被触发后,在另一页中发送与breakpoint
相同的消息,如果没有触发,则表示您已取消订阅从消息中成功。
在您的TimerCallBack
代码中,我想您should not
在此处取消订阅该消息。当您从其他页面退回时,您将永远不会收到该消息,因为您已取消订阅它们。您可以在此页面为onDestory
时退订该消息。
private bool TimerCallBack()
{
if (InPage)
{
RefreshSensors(IdCode);
//MessagingCenter.Unsubscribe<MonitoringView>(this, "OnAppearing");
return true;
}
else
{
//MessagingCenter.Unsubscribe<MonitoringView>(this, "OnDisAppearing");
return false;
}
}
此外,您应该在Device.StartTimer(TimeSpan.FromSeconds(5), TimerCallBack);
消息中放入onappearing
。
public MonitoringTabsViewModel(string idCode, string description)
{
IdCode = idCode;
Description = description;
LoadSensors(idCode);
MessagingCenter.Subscribe<MonitoringView>(this, "OnAppearing", (sender) =>
{
InPage = true;
Device.StartTimer(TimeSpan.FromSeconds(5), TimerCallBack);
});
MessagingCenter.Subscribe<MonitoringView>(this, "OnDisAppearing", (sender) =>
{
InPage = false;
});
}
一旦收到OnAppearing
消息,Device.StartTimer
将在页面中运行,一旦收到OnDisAppearing
消息,回调将返回false并且Device.StartTimer
将停止。