Click here to Skip to main content
15,867,756 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
Hi,

I'm trying to access the method Clear() from a listBox or a comboBox.

I've maanged to go as far as the example below:

C#
// aListBox == A listBox in my form

var propertyFromControl = aListBox.GetType().GetProperty("Items");


The thing is that, for my project I'll be receiving a group of controls, and some of them will have a Items property with the Clear() method. Is it possible to access/execute this Clear()?

C#
// Not Actual code

var propertyFromControl = aListBox.GetType().GetProperty("Items");

var methodFromProperty = propertyFromControl.GetMethod("Clear");

//here is where it gets confusing
methodFromProperty.execute(propertyFromControl, null);//how to point it to the original aListBox


I hope to have provided enough information.

regards
Posted
Comments
Sergey Alexandrovich Kryukov 7-Apr-14 16:45pm    
This is easy, but why? ListBox type usually have accessible Items.Clear(). So, why?
—SA
Paulo Augusto Kunzel 7-Apr-14 17:49pm    
Because I want to practice
PIEBALDconsult 7-Apr-14 17:57pm    
Then you don't want us to just tell you. What you have is on the right track.
Paulo Augusto Kunzel 7-Apr-14 18:04pm    
Thanks, but I've been on stuck on the right track for over a couple days.
I can't find neither material nor people that can help me. It is getting a bit frustrating.

regards
PIEBALDconsult 7-Apr-14 18:07pm    
You might want to know the word "Invoke".

See if this helps you get going. Put a ListBox, named 'listBox1, on a Form, add this method:
C#
// required
using System.Reflection;

private void ClearListBox()
{
    Control theControl = listBox1;

    Type cType = theControl.GetType();

    PropertyInfo[] cProps = cType.GetProperties();

    PropertyInfo targetProperty = null;

    Type targetType = typeof (ListBox.ObjectCollection);

    foreach (PropertyInfo cProp in cProps)
    {
        if (cProp.Name == "Items" && cProp.PropertyType == targetType)
        {
            
            targetProperty = cProp;
            break;
        }
    }

    if (targetProperty != null)
    {
        object items = targetProperty.GetValue(theControl, null);
        MethodInfo clear = targetProperty.PropertyType.GetMethod("Clear");
        if(clear != null) clear.Invoke(items, null);
    }
}
Of course, this is specific to a ListBox, but it demonstrates the steps you'll need to take to invoke 'Clear using reflection. You can extend this by writing code to handle the various cases of other Controls that have Item collections of varying Types, such as the ComboBox (ComboBox.ObjectCollection), the ListView (ListViewItemCollection), etc.
 
Share this answer
 
Comments
Paulo Augusto Kunzel 7-Apr-14 20:58pm    
Ok,
That is starting to make sense. Walking through the properties list.. cool
The --> Type targetType = typeof (ListBox.ObjectCollection);
works quite nicely. One thing I noticed when I tried something like this is that you must use ListBox or ComboBox to get the ObjectColletion. Can I ever call ObjectColletion by itself?

Thx.. That's going to serve as a base for a lot of study which I'll still have to do in this subject.
BillWoodruff 8-Apr-14 0:18am    
I suggest you execute this code ... put a break-point on the last statement ... and think about what you observe:

Type t1 = listBox1.Items.GetType();

Type t2 = typeof (ListBox.ObjectCollection);

bool same = t1 == t2;

The value of the 'Items property of a ListBox is an instance of the ListBox.ObjectCollection object.

good luck, Bill
Paulo Augusto Kunzel 8-Apr-14 7:13am    
Wow. How about that. I've tried to "extend" the test and noticed that I can't have ObjectColletion by itself or try to convert between ComboBox.ObjectCollection to ListBox.ObjectCollection. Interesting

Thank you Bill,
That was the final issue to solve.
Paulo Augusto Künzel wrote:
Thanks, but I've been on stuck on the right track for over a couple days. I can't find neither material nor people that can help me. It is getting a bit frustrating.
I repeat, that is quite easy. Look, if you want to practice, some ready-to-use code sample will not allow you to practice on your own experience, will be nearly useless. That's why I don't want to write the code for you. To really help, I want to give you some hints, because I know where some people typically got stuck.

I never used anything but regular MSDN documentation; so you, too, don't need anything else, just act by definition.

You have two types, property type and list box type; you need to reflect both. You reflect the type of the list box, get instance of the Items property. This is done by invocation of the property getter. (Was that so hard to guess? This point could be a reason why you stuck. Call the getter.) You already have the instance of the list box, so use it to pass to the getter, which is an instance (non-static) method.

When you got an instance of the Items property, it's time to forget the instance of the list box. Reflect the type of Items and find the method you want. This is of course also the instance method, so to call it, you need to pass the instance of the Items you obtained on the next step.

So, in addition to what you already found, you need to learn how to get an accessor ("getter"): http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.getmethod.aspx[^].

[EDIT]

Something like:
C#
PropertyInfo pi = //... say, you got a property info of "Items"
MethodInfo mi = pi.GetMethod;
object itemsInstance = mi.Invoke(/* ... */);
//...


[END EDIT]

And you also need to know how to invoke an instance method:
http://msdn.microsoft.com/en-us/library/a89hcwhh%28v=vs.110%29.aspx[^],
http://msdn.microsoft.com/en-us/library/4k9x6bc0%28v=vs.110%29.aspx[^].

In invocation of the method, pay attention for the parameter Object obj. This is how you pass the instance of the object on which you invoke the method ("this" reference in the method implementation).

All this is really, really easy. You will see.

Now, in practice, you should understand that using reflection to find anything by some string representing the name is a bad practice (it is needed in, say, implementation of the IDE designers though), because such solutions are not supportable. Imagine what can happen if you rename some method or simply misspell the string with a method name. The compiler won't detect a problem, but such solution will stop working. One robust approach is finding an interface implemented by some class/structure, found by interface definition, not by its name. Than you can call interface method of this type instance quite safely.

—SA
 
Share this answer
 
v4
Comments
Paulo Augusto Kunzel 7-Apr-14 19:20pm    
Ok, this is as far as I went:

foreach (Control c in groupBox1.Controls)
{
if (c is ListBox || c is ComboBox)
{
var x = c;

var propertyFromControl = x.GetType().GetProperty("Items");

//var metItems = propertyFromControl.GetMethod;

//object o = metItems.Invoke(x, null);
}
}

But the getMethod doesn't mean much to me. What does it return? how can I get the Clear()? What if I there are many method, how can a property know which one I want? If there were a couple examples on msdn I would probably have a better grasp of what it does.
Sergey Alexandrovich Kryukov 7-Apr-14 20:19pm    
You haven't done anything I told you to do. Why?
You got property of the type PropertyInfo, this is the metadata object, not property object. Now, get its instance... I just told you how, see after [EDIT]...
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900