views:

139

answers:

3

I'm trying to add Intellisense to C# code editor based on the richtextbox control. So far, I've got it parsing the entered text to find all variables and their types (works well). The drop down box works well. What I can't get is a proper list of options for the drop-down list box.

How can I get the following list, programmatically:

alt text

I have already compiled a list of variables and their types, so when the user presses . I know that I have a variable c of type Color. I just need to know what function to call to get the list I need for the drop-down box.

I've tried this code: http://www.codeproject.com/KB/cs/diy-intellisense.aspx but couldn't get it to work properly. I've also read a ton of other threads on StackOverflow to no avail. I'd really like to finish this instead of using someone elses drop-in editor component.

Any hints would be appreciated. Thanks.

+3  A: 

If you know the type, you should be able to Reflect on the type and get all the information you need.

Type.GetMembers would probably be your best bet. You may need a second call to get any static methods as well:

var instanceMembers = typeof(Color)
                      .GetMembers(BindingFlags.Instance | BindingFlags.Public);

var staticMembers = typeof(Color)
                    .GetMembers(BindingFlags.Static | BindingFlags.Public);

Each MemberInfo object will be able to tell you the MemberType (Property, Field, Method, Event, etc.)

Just use the instanceMembers when the user types a variable (like c in your example) followed by . and use the staticMembers when the user types a type name (like Color in your example) followed by ..

Justin Niessner
Yes, Type.GetFields(), Type.GetConstructors(), and Type.GetEvents() will be the other calls needed, I believe.
Nate Dudek
@Nate Dudek - All of those could be handled by the call to GetMembers.
Justin Niessner
Didn't know that. You learn something knew every day!
Nate Dudek
@Nate Dudek - Yep. Just take a look at any of the MSDN Documentation pages for Class Members to see what qualifies. ObservableCollection is a good one: http://msdn.microsoft.com/en-us/library/ms668613.aspx
Justin Niessner
What I was missing to my call to GetMembers was the BindingFlags. Thanks!
BoltBait
+1  A: 

Assuming you have a name table with types this should give you a decent start:

var type = _names[name].Type;
var members = type.GetMembers(); // Check context to grab private methods?

So maybe you can extend your name table to include:

Type
Context
Members
ChaosPandion
I'm storing the name and type as a pair of strings.
BoltBait
@BoltBait - You may want to create a nice structure and hold the type as a `Type` instance instead.
ChaosPandion
Thanks. Storing the `Type` made it much easier.
BoltBait
+1  A: 

You'd want to use reflection to some degree. If you have the type, or the name of the type, you can get a Type instance.

E.g. Type.GetType("System.Int32")

Then you can call Type.GetMembers() on that Type object, see here:

http://msdn.microsoft.com/en-us/library/424c79hc.aspx

...and you'll have an array of MemberInfo objects which have the name (.Name), type of the member (.MemberType), and from that other information, like parameter lists.

Hope that helps.

Kieren Johnstone