所以我试图制作一个数据网格来显示有关本地窗口服务的一些信息,特别是我的,我想拥有服务的显示名称和状态,然后有一个按钮可以单击以启动或停止。我可以很好地链接按钮方法,但服务状态没有改变,任何建议如何使这个属性可观察到数据网格,也可以根据状态动态更改按钮从开始到停止,其次我如果可能的话,想让停止命令成为按钮命令。
有什么建议么?
所以我试图制作一个数据网格来显示有关本地窗口服务的一些信息,特别是我的,我想拥有服务的显示名称和状态,然后有一个按钮可以单击以启动或停止。我可以很好地链接按钮方法,但服务状态没有改变,任何建议如何使这个属性可观察到数据网格,也可以根据状态动态更改按钮从开始到停止,其次我如果可能的话,想让停止命令成为按钮命令。
有什么建议么?
您需要将服务包装到您自己的实现 INotifyPropertyChanged 的类中。当您启动/停止服务时,在该实例上引发属性更改事件。
这就是我最终实施的。它在大多数情况下工作得很好,但是我愿意接受任何人可能会提出的任何代码建议。
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;
}
}
可悲的是,因为ServiceController.GetServices()
call 总是返回一个数组,所以我们必须DispatcherTimer
在它的滴答声中,为保存服务数组的属性调用ServiceController.GetServices()
并引发 notify 属性更改。
为了可观察性而使其可观察是不切实际的吗?无论如何,我们不会从中获得任何优势。