Событие для интерфейса с методом таймера - PullRequest
1 голос
/ 07 мая 2020

Я использую шаблон MVVM для Xamarin Forms, но мои вопросы касаются в основном C#.

Я хотел бы создать обработчик событий для управления настраиваемым статусом с помощью метода таймера. Это работает, но я не уверен, что приведенный ниже подход действительно правильный?

Мои вопросы о;

  • Если я не использую InvokeCustomStatusEvent в MyPageViewModel CustomStatusEvent не могу поднять. Это необходимо?

  • После отключения MyService.CustomStatusChanged -=<br> MyService_CustomStatusChanged; в MyPageViewModel Device.StartTimer l oop продолжить работу. Я использую 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);
        }

}

1 Ответ

1 голос
/ 07 мая 2020

Если я не использую InvokeCustomStatusEvent в MyPageViewModel, CustomStatusEvent не может поднять. Это необходимо?

В большинстве случаев события должны исходить из внутри класса, поэтому обычно нет методов RaiseMyEventForMe. Заметным исключением является DelegateCommand, но тот, который явно существует для , а не , имеет класс для каждой команды (который затем может вызвать событие изнутри).

Когда я отключить MyService.CustomStatusChanged - = MyService_CustomStatusChanged; в MyPageViewModel Device.StartTimer l oop продолжить работу. Я использую bool CustomStatusL oop, чтобы остановить это. Это правильный подход?

Я бы предпочел использовать CancellationToken, чтобы прояснить, что происходит, т.е. что вы хотите остановить таймер при отсоединении события.

...