Как программно добавить элементы в список / список / коллекцию CollectionEditor? [Модифицировано]

У меня есть собственный редактор коллекций, и я хочу программно добавить элементы в его список (коллекцию), чтобы они могли отображаться в списке. Как я могу это сделать? Я знаю о методе AddItems CollectionEditor, но он принимает объект коллекции в качестве параметра, но я не могу найти способ получить объект внутреннего списка CollectionEditor...: /

[обновление] Тьфу... правильное имя метода - 'SetItems' [/ update]

[обновление 2] Исходный код того, что я пытаюсь сделать...

public class MyCollectionEditor : CollectionEditor
{
        private Type m_itemType = null;

        public MyCollectionEditor(Type type)
            : base(type)
        {
            m_itemType = type;
        }

        protected override CollectionForm CreateCollectionForm()
        {
            Button buttonLoadItem = new Button();
            buttonLoadItem.Text = "Load from DB";
            buttonLoadItem.Click += new EventHandler(ButtonLoadItem_Click);

            m_collectionForm = base.CreateCollectionForm();

            TableLayoutPanel panel1 = m_collectionForm.Controls[0] as TableLayoutPanel;
            TableLayoutPanel panel2 = panel1.Controls[1] as TableLayoutPanel;
            panel2.Controls.Add(buttonLoadItem);

            return m_collectionForm;
        }

        private void ButtonLoadItem_Click(object sender, EventArgs e)
        {
            if (m_itemType.Equals(typeof(MyCustomCollection)))
            {               
                MyCustomItem item = ...load from DB...

                //definition: SetItems(object editValue, object[] value);
                SetItems( -> what goes here?! <- , new object[] { item });
            }
        }
}

[/ обновление 2]

3 ответа

Я нашел решение благодаря.NET Reflector и механизму отражения. Вместо использования метода SetItems я вызываю закрытый метод CollectionForm: private void AddItems(IList instances), как это:

MethodInfo methodInfo = m_collectionForm.GetType().GetMethod("AddItems", BindingFlags.NonPublic | BindingFlags.Instance);
methodInfo.Invoke(m_collectionForm, new object[] { /* my items here */ });

PS. Смотрите остальную часть кода выше...

Возможно, я неправильно понимаю ваш вопрос, но вам не нужно сначала определить свою коллекцию? а затем украсить его с помощью EditorAttribute

[EditorAttribute (typeof (System.ComponentModel.Design.CollectionEditor), typeof (System.Drawing.Design.UITypeEditor))]

Ребята, это решение, которое включает в себя:
1- Как добавить новую кнопку в CollectionEditor
. В моем случае это «Кнопка-дубликат»: вставьте новый экземпляр с тем же значением реквизита, что и выбранный (клон).
2- Событие MyCollectionEditor_DuplicateClick onclick создает новый экземпляр и привязывает его с помощью механизма отражения.
3- Украсить имя
CheckLastCounter_ItemDuplicate() - это просто метод сохранения последнего количества дубликатов, чтобы украсить имя на основе порядка номеров.

Я надеюсь это тебе поможет. Я добавил это, потому что не нашел ничего законченного по этой проблеме, и поведение controllereditor странно, когда дело доходит до обновления или привязки значений.


      CollectionForm collectionForm;
private int counterAtomiDuplicati { get; set; }
private const string NomeItemDuplicato = "Item_Duplicato_";


protected override CollectionForm CreateCollectionForm()
{
    collectionForm = base.CreateCollectionForm();
    TableLayoutPanel tl =(TableLayoutPanel)collectionForm.Controls[0];
    AddDuplicateButton(tl);
}

private void AddDuplicateButton(TableLayoutPanel tl)
{
   var upButton = (ButtonBase)tl.Controls.Find("upButton", true).First();
   var duplicateButtonLocation = new System.Drawing.Point(upButton.Location.X, 0);
   Button duplicateButton = new Button();
   duplicateButton.Name = "duplicateButton";
   duplicateButton.Image = Resources.img1;
   duplicateButton.Location = duplicateButtonLocation;
   duplicateButton.Size = upButton.Size;
   tl.Controls.Add(duplicateButton);
   duplicateButton.Click += MyCollectionEditor_DuplicateClick;
}

private void MyCollectionEditor_DuplicateClick(object sender, EventArgs e)
{
  if (listbox == null)
      return;

  if (listbox.Items.Count == 0)
      return;

  var o = listbox.SelectedItem;
  PropertyInfo p = o.GetType().GetProperty("Value");
  if (p.GetValue(o, null) is MyObject)
  {
      MyObject selectedItem = p.GetValue(o, null) as MyObject;
      MyObject nuovoItem = selectedItem.Clone();

     CheckLastCounter_ItemDuplicate();
     counterItemDuplicati++;

     nuovoItem.FileZip = nuovoItem.Nome = nuovoItem.DisplayName = "Item_Duplicato_"+ counterItemDuplicati;

    List<MyObject> listaItemDuplicati = new List<MyObject>();
    listaItemDuplicati .Add(nuovoItem);
    var listaOggetti = listaItemDuplicati .Cast<object>().ToArray();

    //reflection mechanism
    MethodInfo methodInfo = collectionForm.GetType().GetMethod("AddItems", BindingFlags.NonPublic | BindingFlags.Instance);
    methodInfo.Invoke(collectionForm, new object[] { listaOggetti });
     }
}

private void CheckLastCounter_ItemDuplicate()
{
   PackageClass pak = (PackageClass)Context.Instance;
   var listaName = pak.MyItems.Select(x => x.Nome).Where(x =>x.Contains(NomeItemDuplicato)).ToList();
   if (listaName != null && listaName.Any())
   {
       List<int> countItemsDuplicati = new List<int>();
       foreach (string item in listaName)
         {
           string countStringa = item.Replace(NomeItemDuplicato, "");
           int valoreCount = Convert.ToInt32(countStringa);
           countItemsDuplicati.Add(valoreCount);
         }

      int countMax = countItemsDuplicati.Count();
      counterItemDuplicati = countMax;
    }
}
Другие вопросы по тегам