如何以编程方式将项目添加到 CollectionEditor 的列表/列表框/集合? [修改的]

发布于 2024-07-29 13:01:19 字数 1489 浏览 10 评论 0原文

我有自定义集合编辑器,我想以编程方式将项目添加到其列表(集合)中,以便它们可以在列表框中可见。 我怎样才能做到这一点? 我知道 CollectionEditor 的 AddItems 方法,但它以集合对象作为参数,但我无法找到获取 CollectionEditor 的内部列表对象的方法... :/

[更新] 呃..正确的方法名称是“SetItems” [/更新]

[更新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 });
            }
        }
}

[/update 2]

I have custom collection editor and I want to programmatically add items to it's list (collection) so they will could visible in a listbox. How I can do that? I know about CollectionEditor's AddItems method, but it takes collection object as a parameter, but I cannot figure out a way to get CollectionEditor's inner list object... :/

[update]
Ugh.. the proper method name is 'SetItems'
[/update]

[update 2]
Source code of what I'm trying to do...

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 });
            }
        }
}

[/update 2]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

肩上的翅膀 2024-08-05 13:01:19

感谢 .NET Reflector 和反射机制,我找到了解决方案。 我没有使用 SetItems 方法,而是调用 CollectionForm 的私有方法:private void AddItems(IListInstances),如下所示:

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

PS。 请参阅上面的其余代码...

I've found solution thanks to .NET Reflector and reflection mechanism. Instead of using SetItems method I'm invoking private method of CollectionForm: private void AddItems(IList instances), like this:

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

PS. See the rest of code above...

木落 2024-08-05 13:01:19

我可能误解了你的问题,但你不需要先定义你自己的集合吗? 然后用 EditorAttribute 装饰它

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

I may be misunderstanding your question but dont you have to define you own collection first ? and then decorate it with the EditorAttribute

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

雨轻弹 2024-08-05 13:01:19

伙计们,这是解决方案,其中包括:
1-如何在CollectionEditor中添加新按钮
在我的例子中是一个“复制按钮”:插入一个与所选实例(克隆)具有相同属性值的新实例。
2- MyCollectionEditor_DuplicateClick onclik 事件,创建新的
实例并使用反射机制绑定它。

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;
    }
}

Guys this is the solution that includes:
1- How to add a new button in CollectionEditor
In my case is a "Duplicate Button": insert a new instance that have the same props value as the selected one (a clone).
2- MyCollectionEditor_DuplicateClick onclik event,creates the new
instance and bind it using the reflecton mechanism.

3- Decorate name
CheckLastCounter_ItemDuplicate() is just a method to save the last count of duplicated in order to decorate the name based on number order.

I hope this can help you. I added this because I didn't found nothing completed about this problem and the behaviour of controllereditor is strange when it comes to refresh or bind the values.


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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文