【问题标题】:WPF making ServiceController[] ObservableWPF 使 ServiceController[] 可观察
【发布时间】:2011-10-13 22:17:19
【问题描述】:

所以我试图制作一个显示有关本地窗口服务的一些信息的数据网格,特别是我的,我想拥有服务的显示名称和状态,然后有一个按钮可以单击以启动或停止.我可以很好地链接按钮方法,但服务状态没有改变,任何建议如何使这个属性可观察到数据网格,也可以根据状态动态更改按钮从开始到停止,其次我如果可能的话,想让停止命令成为按钮命令。

有什么建议吗?

【问题讨论】:

    标签: c# wpf binding observablecollection servicecontroller


    【解决方案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 && (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() 调用总是会返回一个数组,我们必须有DispatcherTimer 并在其刻度中调用ServiceController.GetServices() 并为保存服务数组的属性引发通知属性更改。

        为了可观察性而使其可观察是不切实际的吗?无论如何,我们不会从中获得任何优势。

        【讨论】:

        • 我最终做了这样的事情 ServiceController sc = ((ServiceController)elem.DataContext); if (sc.CanStop && sc.Status == ServiceControllerStatus.Running) { sc.Stop(); sc.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(15)); sc.刷新(); V7ServicesGrid.Items.Refresh(); }
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-13
        • 1970-01-01
        • 1970-01-01
        • 2011-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多