Foreach中的Foreach迭代相同

问题描述 投票:1回答:3

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


    }
c# display multiple-monitors
3个回答
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搜索结果的密钥。


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
    }

}

0
投票

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

你的代码似乎搞砸了,我确信它甚至都没有完全执行。

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

现在,来到你的问题,你试图循​​环第二个foreach只一次然后退出。

我在这里看到一个重大问题。您正在尝试访问键“monitorname”的值,而在源处,您将值分配给键“MonitorName”。

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

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

虽然你的代码中有很多不清楚的东西,但我认为你有充分的理由让它们以这种方式存在。

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

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

请注意dm["MonitorName"]我已将密钥从“monitorname”更新为“MonitorName”。

还记得在访问item["monitorname"]时使用正确的密钥

希望这可以帮助!

© www.soinside.com 2019 - 2024. All rights reserved.