Запутался в циклах

WPF
  1. 5 года назад

    Привет,
    Ситуация такая: Делаю загрузку плагинов с помощью MEF.
    Содержание плагина.

    using System;
    using System.ComponentModel.Composition;
    using InterfacePlugin;
    using System.Windows;
     
    namespace Plugin1
    {
        [Export(typeof(IPlugin))]
        public class Class1 : IPlugin
        {
            public string PluginName { get { return "Name"; } } // Имя плагина
            public string PlugunCategory { get { return "Test"; } } // Категория 
     
            public void PluginStart(string str)
            {
                //-- Что-то тут --------------
            }
        }
    }

    Нужно следующие на форме tabControl1, при загрузки плагина создается tabPage, на tabPgae создается ListView, нужно проверять категорию по индификатору PlugunCategory, и добавлять запись индефикатора PluginName в в ListView на указанной tabPage.

    То есть если у нас есть вкладка на tabControl1 с именем "Test" и у индификатора плагина название тоже "Test" то добавить в PluginName в ListView на этой вкладке.

    Не понятно? Пойдем к практике.

    Код обработки

            public void PluginConnect()
            {
                //  ListView Box = new ListView();
                int Incriment = 0;
                DirectoryCatalog m_catalog = new DirectoryCatalog("Plugin");
                CompositionContainer container = new CompositionContainer(m_catalog);
                container.ComposeParts(this);
                if (Plugins == null) return;
     
     
                foreach (var plugin in Plugins) // Цикл перебора плагинов 
                {
     
                    if (tabControl1.TabPages.Count == 0) // Проверяем если нету вкладки создаем
                    {
                        ListView Box = new ListView();
                        tabControl1.TabPages.Add(plugin.PlugunCategory);
                        Box.Parent = tabControl1.TabPages[Incriment];
                        Box.Name = plugin.PlugunCategory;
                        Box.Top = 111;
                        Box.Show();
                        Box.Items.Add(plugin.PluginName);
                        Incriment++;
                    }
     
                    else
                    {
                        foreach (TabPage tab in tabControl1.TabPages) // Получаем список вкладок
                        {
                            foreach (ListView item in tab.Controls) //Получаем список ListView на вкладках
                            {
                                ListView List = item as ListView;
     
                                /*Проверяем имя ListView если оно равно имени
                                  индификатора то добавляем PluginName в него*/
                                if (List.Name == plugin.PlugunCategory)
                                {
                                    List.Items.Add(plugin.PluginName);
                                }
                                else //Если нет такова имени создаем новою вкладку.
                                {
                                    ListView Box = new ListView();
                                    tabControl1.TabPages.Add(plugin.PlugunCategory);
                                    Box.Parent = tabControl1.TabPages[Incriment];
                                    Box.Name = plugin.PlugunCategory;
                                    Box.Top = 111;
                                    Box.Show();
                                    Box.Items.Add(plugin.PluginName);
                                    Incriment++;
                                }
                            }
                        }
                    }
                }

    Выглядит это все так
    Есть 4 плагина.
    Со следующими индификаторами
    1)Плагин:
    public string PluginName { get { return "NamePlagin 1"; } }
    public string PlugunCategory { get { return "Test_1"; } }
    2)Плагин:
    public string PluginName { get { return "NamePlagin 2"; } }
    public string PlugunCategory { get { return "Test_1"; } }
    3)Плагин:
    public string PluginName { get { return "NamePlagin 3"; } }
    public string PlugunCategory { get { return "Test_2"; } }
    4)Плагин:
    public string PluginName { get { return "NamePlagin 4"; } }
    public string PlugunCategory { get { return "Test_2"; } }

    Проект выглядит как на рисунки один.
    Но на рисунки видна 3 вкладка которой не должно быть (см. Описание индификаторов плагинов чуть выше.)
    Проблему нашел с помощью отладки цикл foreach (ListView item in tab.Controls) крутит больше, чем нужно относительно главному циклу.
    Причину объяснять долго, приложу исходный проект с 4 плагинами, у плагинов индификаторы те что описаны выше.

    Помогите решить задачу.
    Attached Thumbnails

    -image-
    -image-

  2. Добавлено 5 года назад Foru

    Я сначала думал что нужно вернуть шаг второго цикла назад, но получается зацикливание.
    Вариант с for,

    public void PluginConnect()
            {
                int Incriment = 1;
                DirectoryCatalog m_catalog = new DirectoryCatalog("Plugin");
                CompositionContainer container = new CompositionContainer(m_catalog);
                container.ComposeParts(this);
                if (Plugins == null) return;
          
               foreach (var plugin in Plugins) // Цикл перебора плагинов 
                      {
                              for (int i = 0; i < tabControl1.TabPages.Count; i++) // Проверяем количество вкладок
                                {
                                  for (int j = 0; j < tabControl1.TabPages[i].Controls.Count; j++)
    							  {
                                      ListView lv = (ListView)tabControl1.TabPages[i].Controls[j];
                                      if (lv.Name == plugin.PlugunCategory) // проверяем если равно
                                      {  
                                          lv.Items.Add(plugin.PluginName); // добавляем итем
                                      }
    								  else
    								  {
                                          ListView[] Box = new ListView[Incriment];
                                          tabControl1.TabPages.Add(plugin.PlugunCategory);
                                          Box[Incriment].Parent = tabControl1.TabPages[Incriment];
                                          Box[Incriment].Name = plugin.PlugunCategory;
                                          Box[Incriment].Top = 111;
                                          Box[Incriment].Show();
                                          Box[Incriment].Items.Add(plugin.PluginName);
                                          Incriment++;
                                   }    
                                }
                             }
                         }
                      }

    Желательно использовать первый вариант с foreach.

  3. Добавлено 5 года назад stenly

    Я бы сделал так (на работоспособность не проверял):

            public void PluginConnect()
            {
                int Incriment = 1;
                DirectoryCatalog m_catalog = new DirectoryCatalog("Plugin");
                CompositionContainer container = new CompositionContainer(m_catalog);
                container.ComposeParts(this);
                if (Plugins == null) return;
    
                int countTab = tabControl1.TabPages.Count; // Тут запоминаем сколько у нас вкладок
                foreach (var plugin in Plugins) // Цикл перебора плагинов 
                {
                    for (int i = 0; i < countTab; i++) // А здесь уже используем запомненное число
                    {
                        foreach (ListView item in tabControl1.TabPages[i].Controls) //Получаем список ListView на вкладках
                        {
                            ListView List = item as ListView;
    
                            /*Проверяем имя ListView если оно равно имени
                              индификатора то добавляем PluginName в него*/
                            if (List.Name == plugin.PlugunCategory)
                            {
                                List.Items.Add(plugin.PluginName);
                            }
                            else //Если нет такова имени создаем новою вкладку.
                            {
                                ListView Box = new ListView();
                                tabControl1.TabPages.Add(plugin.PlugunCategory);
                                Box.Parent = tabControl1.TabPages[Incriment];
                                Box.Name = plugin.PlugunCategory;
                                Box.Top = 111;
                                Box.Show();
                                Box.Items.Add(plugin.PluginName);
                                Incriment++;
                            }
                        }
                    }
                }
            }
  4. Найти это сообщение stenly Я бы сделал так (на работоспособность не проверял):
    public void PluginConnect() { int Incriment = 1; DirectoryCatalog m_catalog = new DirectoryCatalog("Plugin"); CompositionContainer container = new CompositionContainer(m_catalog); container.ComposeParts(this); if (Plugins == null) return; int countTab = tabControl1.TabPages.Count; // Тут запоминаем сколько у нас вкладок foreach (var plugin in Plugins) // Цикл перебора плагинов { for (int i = 0; i < countTab; i++) // А здесь уже используем запомненное число { foreach (ListView item in tabControl1.TabPages[i].Controls) //Получаем список ListView на вкладках { ListView List = item as ListView; /*Проверяем имя ListView если оно равно имени индификатора то добавляем PluginName в него*/ if (List.Name == plugin.PlugunCategory) { List.Items.Add(plugin.PluginName); } else //Если нет такова имени создаем новою вкладку. { ListView Box = new ListView(); tabControl1.TabPages.Add(plugin.PlugunCategory); Box.Parent = tabControl1.TabPages[Incriment]; Box.Name = plugin.PlugunCategory; Box.Top = 111; Box.Show(); Box.Items.Add(plugin.PluginName); Incriment++; } } } } }

    Ваш вариант тоже перекручивает цикл =(. Постараюсь отладить ваш вариант мб что и выйдет.

  5. Добавлено 5 года назад stenly

    Foru
    еще я забыл, что надо инкрементировать countTab в ветке с созданием новой вкладки (кол-во вкладок то увеличивается),
    т.е. после Incriment++; можно добавить countTab++;
    и еще одна ошибка, из-за чего собственно создается новая вкладка - в цикле по сути проверяется только ListBox в первой вкладке, если его имя не совпадает с плагином, то сразу создается новая вкладка с новым листбоксом, несмотря на то, что в следующей итерации цикла такая вкладка уже есть.
    может вот так пройдет
    public void PluginConnect() { int Incriment = 1; DirectoryCatalog m_catalog = new DirectoryCatalog("Plugin"); CompositionContainer container = new CompositionContainer(m_catalog); container.ComposeParts(this); if (Plugins == null) return; int countTab = tabControl1.TabPages.Count; // Тут запоминаем сколько у нас вкладок bool flagAdded; // флаг для создания вкладок foreach (var plugin in Plugins) // Цикл перебора плагинов { if (countTab == 0) // Проверяем если нету вкладки создаем { ListView Box = new ListView(); tabControl1.TabPages.Add(plugin.PlugunCategory); Box.Parent = tabControl1.TabPages[Incriment]; Box.Name = plugin.PlugunCategory; Box.Top = 111; Box.Show(); Box.Items.Add(plugin.PluginName); Incriment++; } else { flagAdded = false; for (int i = 0; i < countTab; i++) // А здесь уже используем запомненное число { foreach (ListView item in tabControl1.TabPages[i].Controls) //Получаем список ListView на вкладках { ListView List = item as ListView; /*Проверяем имя ListView если оно равно имени индификатора то добавляем PluginName в него*/ if (List.Name == plugin.PlugunCategory) { List.Items.Add(plugin.PluginName); flagAdded = true; break; // прерываем цикл foreach (ListView item in tabControl1.TabPages[i].Controls) } } if (flagAdded) // прерываем цикл for(int i = 0; i < countTab; i++) break; } if (flagAdded == false) // если не нашлось вкладки под нужный плагин - создаем ее (т.е. все циклы выше отработали, но flagAdded по прежнему равен false) { ListView Box = new ListView(); tabControl1.TabPages.Add(plugin.PlugunCategory); Box.Parent = tabControl1.TabPages[Incriment]; Box.Name = plugin.PlugunCategory; Box.Top = 111; Box.Show(); Box.Items.Add(plugin.PluginName); Incriment++; countTab++; // увеличивается кол-во вкладок } } }
    если сработает, то можно попробовать убрать countTab и цикл for (int i = 0; i < countTab; i++) заменить циклом foreach (TabPage tab in tabControl1.TabPages)

  6. Добавлено 5 года назад Foru

    Не работает, что-то вообще не понятное твориться как не крути не выходит.

или зарегистрируйтесь чтобы ответить