WPF делает ServiceController [] наблюдаемым

#c# #wpf #binding #observablecollection #servicecontroller

#c# #wpf #привязка #observablecollection #ServiceController

Вопрос:

Итак, я пытаюсь создать таблицу данных, которая отображает некоторую информацию о локальных оконных службах, в частности, о моей, я хотел бы иметь отображаемое имя и статус службы, а затем нажать кнопку для запуска или остановки. Я могу связать метод button нормально, но статус службы не меняется, есть какие-либо предложения о том, как сделать это свойство наблюдаемым для datagrid, а также возможно изменить кнопку «на лету» с start на stop в зависимости от статуса, во-вторых, я хотел бы, чтобы команда stop былакоманда кнопки, если возможно.

Есть предложения?

Ответ №1:

Вам нужно обернуть свой сервис в свой собственный класс, который реализует INotifyPropertyChanged. При запуске / остановке службы вызывайте событие изменения свойства для этого экземпляра.

Ответ №2:

Это то, на что я в конечном итоге жаловался. По большей части это работает довольно хорошо, однако я готов к любым предложениям по коду, которые кто-либо может предложить.

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.ServiceProcess;

namespace v7quickbar
{
    class NotifiableServiceController : INotifyPropertyChanged
    {

        private ServiceController m_oServiceController = null;
        private System.Timers.Timer m_oServiceCheckTimer = new System.Timers.Timer();

        public ServiceControllerStatus Status { get { return this.m_oServiceController.Status; } }

        public string DisplayName { get { return this.m_oServiceController.DisplayName; } }

        public string ServiceName { get { return this.m_oServiceController.ServiceName; } }

        public bool CanStop { get { return this.m_oServiceController.CanStop; } }

        public NotifiableServiceController(ServiceController oService)
        {
            CreateObject(oService, TimeSpan.FromSeconds(.5));
        }

        public NotifiableServiceController(ServiceController oService, TimeSpan oInterval)
        {
            CreateObject(oService, oInterval);
        }

        private void CreateObject(ServiceController oService, TimeSpan oInterval)
        {
            m_oServiceController = oService;
            m_oServiceCheckTimer.Interval = oInterval.TotalMilliseconds;

            m_oServiceCheckTimer.Elapsed  = new System.Timers.ElapsedEventHandler(m_oServiceCheckTimer_Elapsed);
            m_oServiceCheckTimer.Start();
        }

        public void Start()
        {
            try
            {
                this.m_oServiceController.Start();
                this.m_oServiceController.WaitForStatus(ServiceControllerStatus.Running);
            }
            catch (Exception)
            {
            }
        }

        public void Stop()
        {
            try
            {
                this.m_oServiceController.Stop();
                this.m_oServiceController.WaitForStatus(ServiceControllerStatus.Stopped);
            }
            catch (Exception)
            {
            }
        }

        public void Restart()
        {
            try
            {
                if (m_oServiceController.CanStop amp;amp; (m_oServiceController.Status == ServiceControllerStatus.Running || m_oServiceController.Status == ServiceControllerStatus.Paused))
                {
                    this.Stop();
                    this.m_oServiceController.WaitForStatus(ServiceControllerStatus.Stopped);
                }

                if (m_oServiceController.Status == ServiceControllerStatus.Stopped)
                {
                    this.Start();
                    this.m_oServiceController.WaitForStatus(ServiceControllerStatus.Running);
                }
            }
            catch (Exception)
            {
            }
        }

        void m_oServiceCheckTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            ServiceControllerStatus oCurrentStatus = m_oServiceController.Status;
            m_oServiceController.Refresh();

            if (oCurrentStatus != m_oServiceController.Status)
            {
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Status"));
            }

        }

        public static IEnumerable<NotifiableServiceController> GetServices()
        {
            List<NotifiableServiceController> oaServices = new List<NotifiableServiceController>();
            foreach (ServiceController sc in ServiceController.GetServices())
            {
                oaServices.Add(new NotifiableServiceController(sc));
            }

            return oaServices;
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
  

Ответ №3:

К сожалению, поскольку ServiceController.GetServices() call всегда будет возвращать массив, мы должны иметь DispatcherTimer и в его галочке, вызвать ServiceController.GetServices() и вызвать свойство notify, измененное для того свойства, которое содержит массив сервисов.

Сделать его наблюдаемым ради наблюдаемости нецелесообразно, верно? В любом случае мы не получим от этого никакого преимущества.

Комментарии:

1. В итоге я сделал что-то вроде этого ServiceController sc = ((ServiceController)elem. DataContext); если (sc.CanStop amp;amp; sc.Status == ServiceControllerStatus. Выполняется) { sc.Stop(); sc.WaitForStatus(ServiceControllerStatus. Остановлено, TimeSpan.FromSeconds(15)); sc.Refresh(); V7ServicesGrid. Товары. Обновить(); }