我正在为Xamarin表单使用MVVM模式,但我的问题主要是关于C#的。
我想创建一个事件处理程序,以使用计时器方法控制自定义状态。那行得通,但是我不确定下面的方法真的正确吗?
我的问题;
如果我不使用InvokeCustomStatusEvent
中的MyPageViewModel
CustomStatusEvent
不能加注。那有必要吗?
当我在MyService.CustomStatusChanged -=
MyService_CustomStatusChanged;
MyPageViewModel
中拆下Device.StartTimer
时循环继续运行。我正在使用bool CustomStatusLoop
停止该操作。那是正确的方法吗?
谢谢你。
IMyService.cs
namespace MyAppService.Services
{
public interface IMyService
{
event EventHandler<CustomStatusEventArgs> CustomStatusChanged;
void InvokeCustomStatusEvent(int seconds);
bool CustomStatusLoop { get; set; }
}
}
MyService.cs
namespace MyAppService.Services
{
public class CustomStatusEventArgs : EventArgs
{
public bool IsCustomEnable;
public CustomStatusEventArgs(bool isCustomEnable)
{
IsCustomEnable = isCustomEnable;
}
}
public class MyService : IMyService
{
private IPageDialogService PageDialogService { get; }
public bool CustomStatusLoop { get; set; }
public MyService(IPageDialogService pageDialogService)
{
PageDialogService = pageDialogService;
}
#region //> Events
event EventHandler<CustomStatusEventArgs> CustomStatusEvent;
readonly object objectLock = new object();
event EventHandler<CustomStatusEventArgs> IMyService.CustomStatusChanged
{
add
{
lock (objectLock)
{
CustomStatusEvent += value;
}
}
remove
{
lock (objectLock)
{
CustomStatusEvent -= value;
}
}
}
public void InvokeCustomStatusEvent(int seconds)
{
Device.StartTimer(TimeSpan.FromSeconds(seconds), () =>
{
CustomStatusEvent?.Invoke(this, new CustomStatusEventArgs(IsCustomEnable()));
return CustomStatusLoop;
});
}
#endregion
public bool IsCustomEnable()
{
return Xamarin.Forms.DependencyService.Get<ICustomDependencyService>().IsCustomEnable();
}
}
}
MyPageViewModel.cs
namespace MyAppService.ViewModels
{
public class MyPageViewModel : ViewModelBase
{
#region //> Services
private IPageDialogService PageDialogService { get; }
public IMyService MyService { get; set; }
#endregion
#region //> Constructor
public HomePageViewModel
(
IPageDialogService pageDialogService,
IMyService MyService,
INavigationService navigationService
) : base(navigationService)
{
PageDialogService = pageDialogService;
MyService = MyService;
}
public override void Initialize(INavigationParameters parameters)
{
base.Initialize(parameters);
MyService_CustomStatusChanged(this, new CustomStatusEventArgs(MyService.IsCustomEnable()));
}
public override void OnAppearing()
{
base.OnAppearing();
MyService.CustomStatusChanged += MyService_CustomStatusChanged;
MyService.InvokeCustomStatusEvent(5);
MyService.CustomStatusLoop = true;
}
public override void OnDisappearing()
{
base.OnDisappearing();
MyService.CustomStatusChanged -= MyService_CustomStatusChanged;
MyService.CustomStatusLoop = false;
}
}
private async void MyService_CustomStatusChanged(object sender, CustomStatusEventArgs e)
{
IsCustomEnable = e.IsCustomEnable;
}
private bool _isCustomEnable;
public bool IsCustomEnable
{
get => _isCustomEnable;
set => SetProperty(ref _isCustomEnable, value);
}
}
如果我在MyPageViewModel中不使用InvokeCustomStatusEvent,则不会引发CustomStatusEvent。那有必要吗?
在大多数情况下,事件应该来自类的inside,因此通常没有任何RaiseMyEventForMe
方法。一个显着的例外是DelegateCommand
,但是在那里显式地表示not每个命令都有一个类(然后可以从内部引发事件)。
当我拆开MyService.CustomStatusChanged-= MyService_CustomStatusChanged时;在MyPageViewModel Device.StartTimer循环中继续运行。我正在使用bool CustomStatusLoop停止该操作。那是正确的方法吗?
我宁愿使用CancellationToken
来说明正在发生的事情,即您要在分离事件时停止计时器。