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]
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))]
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...
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;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.