【问题标题】:How to programmatically add items to CollectionEditor's list/listbox/collection ? [modified]如何以编程方式将项目添加到 CollectionEditor 的列表/列表框/集合? [修改的]
【发布时间】:2009-07-28 09:01:46
【问题描述】:

我有自定义集合编辑器,我想以编程方式将项目添加到它的列表(集合)中,以便它们可以在列表框中可见。我怎么能这样做?我知道 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 });
            }
        }
}

[/更新 2]

【问题讨论】:

  • +1 用于发布更新以充分解释他的解决方案!!!现在我们看看它是否适合我...... ;)

标签: c# winforms collectioneditor


【解决方案1】:

感谢 .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。请参阅上面的其余代码...

【讨论】:

    【解决方案2】:

    我可能误解了您的问题,但您不必先定义自己的收藏吗?然后用 EditorAttribute 装饰它

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

    【讨论】:

    • 是的,你是对的。我有我的收藏,我派生了 CollectionEditor 类并按照您的建议装饰了我的收藏。我想要实现的是 - 在 CollectionEditor 中,我添加了一个按钮来从数据库加载项目(在要添加和删除的原始按钮旁边),在我处理加载后,我想将此项目添加到列表中。有一种“设置”项目的方法(在 CollectionEditor 中),但必须传递实际的对象列表,该列表受到保护,因此无法访问。
    【解决方案3】:

    伙计们,这是包含以下内容的解决方案:
    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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-03-07
      • 1970-01-01
      • 1970-01-01
      • 2011-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-09
      • 2022-12-20
      相关资源
      最近更新 更多