Foreach中的Foreach会同时进行迭代

时间:2018-09-07 00:54:32

标签: c# display multiple-monitors

我想知道如何从第一个foreach循环和第二个foreach循环中同时向字典添加项目。

例如-第一个循环将第一个内容添加到项目中,并启动第二个循环,我希望它在循环中添加第一个项目,然后在不读取第二个项目的情况下启动外部循环。这样做,并从第二个循环中添加第二个项目。

很抱歉,这个问题令人困惑。英语薄弱。

List<object> items = new List<object>();
DeviceSettings deviceSettings = new DeviceSettings();
List<object> deviceName = deviceSettings.GetMonitorFriendlyName();

using (ManagementObjectCollection moc = searcher.Get())
{  
    foreach (ManagementObject mo in moc)
    {
        Dictionary<string, object> item = new Dictionary<string, object>();
        ConnectedMonitor_Number = searcher.Get().Count;

        item.Add("DefaultMonitorLength", DefaultMonitor_Width);
        item.Add("DefaultMonitorHeight", DefaultMonitor_Height);
        item.Add("ConnectedMonitor_Numb", Convert.ToString(ConnectedMonitor_Number));
        item.Add("Caption", Convert.ToString(mo["Caption"]));
        item.Add("Name", Convert.ToString(mo["Name"]));
        item.Add("Description", Convert.ToString(mo["Description"]));
        item.Add("DeviceID", Convert.ToString(mo["DeviceID"]));
        item.Add("Manufacturer", Convert.ToString(mo["Manufacturer"]));
        string[] HardwareID = (string[])mo["HardwareID"];
        item.Add("HardwareID", string.Join(";", HardwareID));
        item.Add("Status", Convert.ToString(mo["Status"]));

        foreach (Dictionary<string, string> dm in deviceName)
        {
            item["monitorname"] = Convert.ToString(dm["monitorname"]);
        }

        items.Add(item);
    }
}

---这是devicesettings.cs ---

public static string MonitorFriendlyName(LUID adapterId, uint targetId)
    {
        DISPLAYCONFIG_TARGET_DEVICE_NAME deviceName = new DISPLAYCONFIG_TARGET_DEVICE_NAME();
        deviceName.header.size = (uint)Marshal.SizeOf(typeof(DISPLAYCONFIG_TARGET_DEVICE_NAME));
        deviceName.header.adapterId = adapterId;
        deviceName.header.id = targetId;
        deviceName.header.type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
        int error = DisplayConfigGetDeviceInfo(ref deviceName);
        if (error != ERROR_SUCCESS)
            throw new Win32Exception(error);
        return deviceName.monitorFriendlyDeviceName;
    }

    public List<object> GetMonitorFriendlyName()
    {
        try
        {
            List<object> items = new List<object>();
            uint PathCount, ModeCount;
            int error = GetDisplayConfigBufferSizes(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS,
                out PathCount, out ModeCount);
            if (error != ERROR_SUCCESS)
            {
                throw new Win32Exception(error);
            }

            DISPLAYCONFIG_PATH_INFO[] DisplayPaths = new DISPLAYCONFIG_PATH_INFO[PathCount];
            DISPLAYCONFIG_MODE_INFO[] DisplayModes = new DISPLAYCONFIG_MODE_INFO[ModeCount];
            error = QueryDisplayConfig(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS,
                ref PathCount, DisplayPaths, ref ModeCount, DisplayModes, IntPtr.Zero);

            for (int i = 1; i < ModeCount; i++)
            {
                if (DisplayModes[i].infoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_TARGET)
                {
                    Dictionary<string, string> item = new Dictionary<string, string>();

                    item["MonitorName"] = (MonitorFriendlyName(DisplayModes[i].adapterId, DisplayModes[i].id));
                    items.Add(item);


                }
            }

            return items;
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }


    }

3 个答案:

答案 0 :(得分:0)

每次迭代时,您似乎都在覆盖字典条目中的monitorname键。这会将每个项目设置为具有相同的监视器名称。尝试这样的事情:

List<object> items = new List<object>();
DeviceSettings deviceSettings = new DeviceSettings();
List<object> deviceNames = deviceSettings.GetMonitorFriendlyName();

using (ManagementObjectCollection moc = searcher.Get())
{
    var managementObjects = moc.Cast<ManagementObject>().ToArray();
    ConnectedMonitor_Number = managementObjects.Length;

    for (int i = 0; i < managementObjects.Length; i++)
    {
        object device = deviceNames[i];
        ManagementObject mo = managementObjects[i];

        Dictionary<string, object> item = new Dictionary<string, object>
        {
            { "DefaultMonitorLength", DefaultMonitor_Width },
            { "DefaultMonitorHeight", DefaultMonitor_Height },
            { "ConnectedMonitor_Numb", Convert.ToString(ConnectedMonitor_Number) },
            { "Caption", Convert.ToString(mo["Caption"]) },
            { "Name", Convert.ToString(mo["Name"]) },
            { "Description", Convert.ToString(mo["Description"]) },
            { "DeviceID", Convert.ToString(mo["DeviceID"]) },
            { "Manufacturer", Convert.ToString(mo["Manufacturer"]) },
            { "HardwareID", string.Join(";", (string[])mo["HardwareID"]) },
            { "Status", Convert.ToString(mo["Status"]) },
            { "monitorname", Convert.ToString(device["monitorname"])}
        };

        items.Add(item);
    }
}

请注意,这不会编译,因为您将deviceNames声明为List<object>,但是似乎将其视为Dictionary<string,string>。我们没有看到演员表吗?同样,此答案基于您仅搜索连接的显示器的假设。

更新:

看到copied your source from的位置后,您需要将代码恢复为原始作者的操作。如果您确实想要字典,则需要从上方选择一个可以与您的WMI搜索结果绑定的键。

答案 1 :(得分:0)

  

查看更新的代码后进行编辑。

您的代码似乎都被弄乱了,我确信它甚至没有完全执行。

您在字典(Dictionary<string, string> item)列表中使用相同的字典密钥(List<object> items)。这意味着在任何给定时间,您的词典中您只有一个值您打算通过什么实现?

现在,出现一个问题,您试图在第二个foreach中循环一次,然后退出。

我在这里看到一个重大问题。您试图访问“监视器名称”的值,而在源头,您正在将值分配给“监视器名称”。

  1. 基于字典的初始化,字典中的键区分大小写,在这里您尝试访问错误的键。
  2. 由于字典中始终只有一个条目,键为“ MonitorName”,因此这行代码 将在运行时抛出KeyNotFoundException

但是,您已经报告了将break;添加到第二个foreach会破坏第一个foreach。我的猜测是,您甚至还没有调试代码,而是根据所获得的输出在假设条件下发布了问题。这是由于运行时异常引起的,而不是由于break;未能按预期工作。

尽管您的代码中还有很多不清楚的地方,但我认为您有充分的理由采用这种方式。

以下代码可以解决您的问题:

    foreach (Dictionary<string, string> dm in deviceName)
    {
        item["monitorname"] = Convert.ToString(dm["MonitorName"]);
        break;
    }
  

通知 dm["MonitorName"],其中我已将密钥从“显示器名称”更新为“显示器名称”。

     

请记住,在访问item["monitorname"]

时要使用正确的密钥

希望这会有所帮助!

答案 2 :(得分:0)

如果我收到您的问题,这可能是您要寻找的逻辑(不确定)。使用外部循环仅保留项目,使用内部循环进行实际操作。

 foreach (ManagementObject mo in moc)
{
   foreach (item-no-n mo in ManagementObject )
    {
      ///1st item loop to n-item
    }
   foreach (item-no-n mo in ManagementObject )
    {
      ///1st item loop to n-item
    }

}