Foreach in Foreach 同时迭代

Foreach in Foreach iterate at the same

我想知道如何从第一个 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;
        }


    }

您似乎在每次迭代时都覆盖了字典条目中的 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 搜索结果中。

Edit after looking at the updated code.

您的代码似乎一团糟,我敢肯定它甚至没有完全执行。

您在词典列表 (List<object> items) 中对词典 (Dictionary<string, string> item) 使用相同的键。这意味着,在任何给定时间,您的字典中只有一个值你想通过这个达到什么目的?

现在,来到你的问题,你试图循​​环通过第二个 foreach 一次并退出。

我发现这里有一个主要问题。您正在尝试访问 key "monitorname" 的值,而在源头,您正在将值分配给 key "MonitorName".

  1. 根据您的 Dictionary 初始化,您的 Dictionary 中的键区分大小写,而您在此处尝试访问错误的键。
  2. 因为字典中总是有一个键为 "MonitorName" 的条目,所以这行代码 在运行时抛出 KeyNotFoundException

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

尽管您的代码中有很多地方不清楚,但我假设您有充分的理由这样做。

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

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

Notice dm["MonitorName"] where I have updated the key from "monitorname" to "MonitorName".

Also remember to use correct key while accessing item["monitorname"]

希望这对您有所帮助!

如果我得到你的问题,这可能是你正在寻找的逻辑(不确定)。使用外循环来保存项目,使用内循环来做真正的操作。

 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
    }

}