Foreach в Foreach повторяется одновременно - PullRequest
0 голосов
/ 07 сентября 2018

Хотелось бы узнать, как добавить элемент в словарь из первого цикла 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);
    }
}

--- Это настройки устройства.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 голосов
/ 07 сентября 2018

Изменить после просмотра обновленного кода.

Ваш код, кажется, испорчен, и я уверен, что он даже не выполняется полностью.

Вы используете тот же ключ для словаря (Dictionary<string, string> item) в своем списке словарей (List<object> items). Это означает, что в любой момент времени в вашем словаре будет ровно одно значение . Чего вы пытаетесь достичь этим?

Теперь , перейдя к вашему вопросу, где вы пытаетесь перебрать второй foreach только один раз и выйти.

Я вижу здесь серьезную проблему. Вы пытаетесь получить доступ к значению key «имя монитора», тогда как в источнике вы присваиваете значение key «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"]

Надеюсь, это поможет!

0 голосов
/ 07 сентября 2018

Если я получил ваш вопрос, это может быть логика, которую вы ищете (не уверен). Используйте внешний цикл, чтобы просто удерживать элемент, и внутренний цикл, чтобы выполнить реальную операцию.

 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 голосов
/ 07 сентября 2018

Вы, кажется, перезаписываете свой ключ 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>. Есть ли актеры, которых мы не видим? Также этот ответ основан на предположении, что вы ищете только подключенные мониторы.

Обновление:

Видя, куда вы скопировали исходный код из , вам нужно вернуть свой код обратно к тому, что делал первоначальный автор. Если вам действительно нужен словарь, вам нужно выбрать ключ, который вы можете привязать к результатам поиска WMI сверху.

...