如何将 WMI 集合显示到 WPF 数据网格



我刚刚开始WPF,有点迷茫。

XAML 代码:

<DataGrid  Name="dgResults" AutoGenerateColumns="True" ItemsSource="{Binding}">
</DataGrid>

C# 代码:

private void GetServices(string strComputer)
{
     ManagementScope scope = new ManagementScope(@"\" + strComputer + @"rootcimv2");
     SelectQuery query = new SelectQuery("Select * From Win32_Service");
     ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
     ManagementObjectCollection services = searcher.Get();
     dgResults.ItemsSource = services;
}

我期望 WMI Win32_Service查询会将 WMI 属性显示为标头,并且返回集合中的每个对象将显示为一行。 但它显示的是 ManagementObjectCollection 属性。 有没有办法转换它并仍然允许所有属性可访问?

任何帮助将不胜感激。

这是一件有点棘手的事情。

首先,由于您不想显示ManagementBaseObject实例的 CLR 属性,因此必须使用类型描述符概念来告知绑定引擎您具有自定义属性集。以下是您需要CustomTypeDescriptorPropertyDescriptor的后代:

internal sealed class ManagementObjectPropertDescriptor : PropertyDescriptor
{
    private readonly PropertyData propertyData;
    public ManagementObjectPropertDescriptor(PropertyData propertyData)
        : base(propertyData.Name, null)
    {
        this.propertyData = propertyData;
    }
    public override bool CanResetValue(object component)
    {
        return false;
    }
    public override Type ComponentType
    {
        get { return typeof(ManagementObjectTypeDescriptor); }
    }
    public override object GetValue(object component)
    {
        return propertyData.Value;
    }
    public override bool IsReadOnly
    {
        get { return true; }
    }
    public override Type PropertyType
    {
        get { return propertyData.Value != null ? propertyData.Value.GetType() : typeof(object); }
    }
    public override void ResetValue(object component)
    {
    }
    public override void SetValue(object component, object value)
    {
    }
    public override bool ShouldSerializeValue(object component)
    {
        return false;
    }
}
public sealed class ManagementObjectTypeDescriptor : CustomTypeDescriptor
{
    private PropertyData[] managementObjectProperties;
    public ManagementObjectTypeDescriptor(ManagementBaseObject source)
    {
        this.managementObjectProperties = source
            .Properties
            .Cast<PropertyData>()
            .ToArray();
    }
    public override PropertyDescriptorCollection GetProperties()
    {
        return new PropertyDescriptorCollection(managementObjectProperties
            .Select(p => new ManagementObjectPropertDescriptor(p))
            .ToArray());
    }
}

为简单起见,属性设置为只读。
接下来,您需要将ManagementObjectCollection转换为ManagementObjectTypeDescriptor集合:

        ManagementScope scope = new ManagementScope(@"\" + strComputer + @"rootcimv2");
        SelectQuery query = new SelectQuery("Select * From Win32_Service");
        var typeDescriptors = new ObservableCollection<ManagementObjectTypeDescriptor>();
        using (var searcher = new ManagementObjectSearcher(scope, query))
        {
            using (var managementObjects = searcher.Get())
            {
                foreach (ManagementBaseObject managementObject in managementObjects)
                {
                    using (managementObject)
                    {
                        typeDescriptors.Add(new ManagementObjectTypeDescriptor(managementObject));
                    }
                }
            }
        }
        dgResults.ItemsSource = new ArrayList(typeDescriptors);

请注意,ItemsSourceIList 的非泛型实现。从我的角度来看,DataGrid有一个错误的行为:如果你将一个通用IList<ManagementObjectTypeDescriptor>设置为项目源,DG只会忽略从CustomTypeDescriptor继承的事实,并且你会看到网格中根本没有列。同时,非泛型IList按预期工作。

相关内容

  • 没有找到相关文章

最新更新