I am trying to discover the properties of the components on a Form using automation, and all goes well until I get to the DataBindings property. It displays as a System.Windows.Forms.ControlBindingCollection. I can get ahold of this object and get its BindingSource, but I cannot figure out how to get ahold of the BindingSource.DataSource. I know it's bound to an object and I can see the correct object in the debugger, but when I call BindingSource.DataSource.getType(), I just get a System.RuntimeType object.
So, is there an easier way to introspect the properties of DataBindings, and if not, how can I discover the type of the object bound to the BindingSource
Thanks in advance for any help.
Herman Post
public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
handled = false;
if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if(commandName == "DataBindingExample.Connect.DataBindingExample")
{
IDesignerHost host;
host = (IDesignerHost)_applicationObject.ActiveWindow.Object as System.ComponentModel.Design.IDesignerHost;
PropertyDescriptorCollection propertyDescriptorCollection;
String message = "";
foreach (Component component in host.Container.Components)
{
message += "**************************************************\n";
message += "Component Type: " + component.GetType() + "\n";
message += "*************** Properties follow ***************" + "\n";
propertyDescriptorCollection = TypeDescriptor.GetProperties(component);
foreach (PropertyDescriptor property in propertyDescriptorCollection)
{
message += property.Name + " : " + property.GetValue(component) + "\n";
ControlBindingsCollection cbc;
if (property.Name == "DataBindings")
{
cbc = (System.Windows.Forms.ControlBindingsCollection)property.GetValue(component);
System.Collections.IEnumerator itor = cbc.GetEnumerator();
while (itor.MoveNext())
{
Trace.WriteLine("\nComponent: " + component.ToString()) ;
Binding binding = (Binding)itor.Current;
String debug = "Bound Property: " + binding.PropertyName + "\nDataSource: " + binding.DataSource.ToString() +
"\nBindingMemberInfo.BindingField: " + binding.BindingMemberInfo.BindingField;
BindingSource bindingSource = (BindingSource)binding.DataSource;
// bindingSource.DataSource.getType() is System.RuntimeType
Trace.WriteLine(debug);}
}
}
}
//MessageBox.Show(message);handled =
true; return;}

Inspecting the DataBindings property
Frank J DeFalco
Hi,
I finally have tested some code with an add-in and:
- For VS.NET 2003, I get a Dataset type, not a System.RuntimeType
- For VS 2005, I get a BindingSource type (which is a new type in .NET 2.0), not a System.RuntimeType.
In both cases I bound the Text and Tag properties of the DataBindings property of a form to some fields of a Dataset that I added to the form.
So, I don’t know why you get a RuntimeType. Can you explain step by step what binding you did in the form
My (VB.NET) code is:
_applicationObject = CType(application, DTE)
objIDesignerHost = CType(_applicationObject.ActiveWindow.Object, IDesignerHost)
For Each objComponent In objIDesignerHost.Container.Components
For Each objPropertyDescriptor As PropertyDescriptor In TypeDescriptor.GetProperties(objComponent)
If objPropertyDescriptor.Name = "DataBindings" Then
objControlBindingsCollection = DirectCast(objPropertyDescriptor.GetValue(objComponent), ControlBindingsCollection)
For Each objBinding In objControlBindingsCollection
objObject = objBinding.DataSource
Next
End If
Next
Next
--
Best regards,
Carlos J. Quintero
MZ-Tools: Productivity add-ins for Visual Studio
You can code, design and document much faster:
http://www.mztools.com
_MRCHINGON_
The Fullname property still comes thru as System.RuntimeType.
Type
type = (Type)bindingSource.DataSource.GetType();// type.FullName is System.RuntimeType
haricharan
Hi Herman,
I have not tested it in your case, but try adding a reference to the Microsoft.VisualBasic assembly and use:
Microsoft.VisualBasic.Information.Typename(bindingSource.DataSource).
That little gem function of Visual Basic should return a string with the actual type name of an Object and give you a clue about what to cast it to (then you can remove the VisualBasic assembly). At least it works with System.__ComObject when using COM Interop....
--
Best regards,
Carlos J. Quintero
MZ-Tools: Productivity add-ins for Visual Studio
You can code, design and document much faster:
http://www.mztools.com
MAOWEIJUN
Thanks for taking the time to look into this Carlos - I appreciate it.
I bind to a type that exists in the project. I created a simple Person class with a name, birthday and gender. I can see the BindingSource object fine. It is the BindingSource.DataSource property that is coming back as a RuntimeType. In the debugger I can see the that BindingSource.DataSource contains the assembly and class name of the object I'm bound to (Person), but I can't figure out how to cast it in code. So to continue your sample:
For Each objBinding In objControlBindingsCollection
objBindingSource = objBinding.DataSource
Type type = objBindingSource.DataSource.GetType(); ' I can see Form1.Person here as the binding
MessageBox.Show(type.FullName); ' System.RuntimeType
Next
I confess I am somewhat new to C# (switching from Java), so there may be something here I am overlooking.
Thanks,
Herman Post
Jesse - MSFT
> I confess I am somewhat new to C# (switching from Java),
> so there may be something here I am overlooking.
And I was not that familiar with databinding or binding to objects. The behavior is the expected, you get a RuntimeType as BindingSource.DataSource when binding to an object (instead of to a dataset). As I said, RuntimeType is an internal class of the .NET Framework but you can cast it to the public System.Type. This class represents the type of an object and it is the central class of Reflection, a part of the .NET framework that allows you to introspect the properties, methods, etc of the class (type) of an object. I think that Java has this capability as well.
For example, if you have:
Dim objPerson As Person
Dim objType As System.Type
objPerson = New Person()
objType = objPerson.GetType()
then, using objType, you can discover all the properties, methods, fields, etc. of the Person object.
So, returning to your case, using System.Type you can know whatever you want from the class bound to your control. For example:
Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, ByVal addInInst As Object, ByRef custom As Array) Implements IDTExtensibility2.OnConnection
Dim objIDesignerHost As System.ComponentModel.Design.IDesignerHost
Dim objControlBindingsCollection As ControlBindingsCollection
Dim objBinding As Binding
Dim objBindingSource As BindingSource
Dim objType As System.Type
Try
_applicationObject = CType(application, DTE2)
objIDesignerHost = TryCast(_applicationObject.ActiveWindow.Object, System.ComponentModel.Design.IDesignerHost)
For Each objComponent As Component In objIDesignerHost.Container.Components
For Each objPropertyDescriptor As PropertyDescriptor In TypeDescriptor.GetProperties(objComponent)
If objPropertyDescriptor.Name = "DataBindings" Then
objControlBindingsCollection = DirectCast(objPropertyDescriptor.GetValue(objComponent), ControlBindingsCollection)
For Each objBinding In objControlBindingsCollection
objBindingSource = DirectCast(objBinding.DataSource, BindingSource)
If TypeOf objBindingSource.DataSource Is System.Type Then
objType = DirectCast(objBindingSource.DataSource, System.Type)
MessageBox.Show("Control property '" & objBinding.PropertyName & "' is bound to object property '" & objBinding.BindingMemberInfo.BindingMember & "' of class '" & objType.FullName & "' of assembly '" & objType.Assembly.FullName & "'")
End If
Next
End If
Next
Next
Catch ex As Exception
End Try
End Sub
Notice that your confusion was that you were using BindingSource.DataSource.GetType() instead of casting BindingSource.DataSource to Type to get the Type of your bound class. In your case, BindingSource.DataSource is already the Type that you were looking for to inspect. Using GetType on a Type class is like getting metadata from metadata, no point at all in most cases...
I hope you understand the thing now. Let me know otherwise.
--
Best regards,
Carlos J. Quintero
MZ-Tools: Productivity add-ins for Visual Studio
You can code, design and document much faster:
http://www.mztools.com
mark87544
System.RuntimeType is an internal (Friend) class inside the mscorlib.dll assembly which inherits from System.Type (which is abstract) and implements its methods.
I am not sure if you are familiar with Reflection, but given an object "o", o.GetType() returns an instance of System.RuntimeType.
What does the FullName property return for that System.RuntimeType instance
--
Best regards,
Carlos J. Quintero
MZ-Tools: Productivity add-ins for Visual Studio
You can code, design and document much faster:
http://www.mztools.com
Anssi Lehtonen
Ah - that last piece was it - casting Datasource to Type.
Thanks much for your help.
Herman Post
fbrian
Thanks for responding. Unfortunately, that returns the same thing as Object.getType(): System.RuntimeType, which curiously is not documented in help. Is there another way to get at the values of the DataBindings property, rather than going after the ControlBindingsCollection
Thanks,
Herm