views:

639

answers:

3

EDIT: I changed wording, added long sample code to be more descriptive

I need to read type name of object bind via BindingSource.
My method accepts BindingSource as parameter and it doesnt know about object type 'hosted' by BindingSource. But I need to read that object type

To explain better what I meant, assume I have 2 classes

class Person {
    public string Name { get; set; }
    public List<Parent> Parents { get; set; }

}
class Parent {
    public string Name { get; set; }
    public int ChildrenCount { get; set; }
}

Than I'm using them in Windows Forms binding scenario:

        // Create Person List
        List<Person> Persons = new List<Person>();

        // add Sample data
        Persons.Add(new Person() { Name = "Person_1" });
        Persons.Add(new Person() { Name = "Person_2" });
        Persons[0].Parents = new List<Parent>();
        Persons[0].Parents.Add(new Parent() { Name = "Father_1", ChildrenCount = 2 });
        Persons[0].Parents.Add(new Parent() { Name = "Mother_1", ChildrenCount = 2 });
        Persons[1].Parents = new List<Parent>();
        Persons[1].Parents.Add(new Parent() { Name = "Father_2", ChildrenCount = 1 });
        Persons[1].Parents.Add(new Parent() { Name = "Mother_2", ChildrenCount = 1 });


        // create binding sources
        BindingSource bs1 = new BindingSource(Persons, null);
        BindingSource bs2 = new BindingSource(bs1, "Parents");

        // bind to grid
        dataGridView1.DataSource = bs1;
        dataGridView2.DataSource = bs2;


        // ****************************************
        // ****** Read type 'hosted' by BS ********
        // ****************************************
        // BS1 - Expected: System.Collections.Generic.List`1[Person]
        // That's easy...
        Console.WriteLine("type bind to BS1=" + bs1.DataSource.GetType());

        // BS2 - Expected: System.Collections.Generic.List`1[Person]
        // HOW TO READ THAT ??!!

        // this returns BindingSource type
        Console.WriteLine("type bind to BS2=" + bs2.DataSource.GetType());
        // this returns: System.Collections.Generic.List`1[Person] (I need List<Parents> or Person.List<Parents>"
        Console.WriteLine("type bind to BS2=" + (bs2.DataSource as BindingSource).DataSource.GetType());

So, as you noticed this is Master-Detail binding (bs1 is bind to one grid, bs2 to second)*

So I would like to read somehow type 'hosted' via bindingSource bs2 (Expected type is List < Parent > )

Method I need to write shall looks as follow:

Type GetBSType (BindingSource bs)

Appreciate any help...

+1  A: 

In .NET every object inherits from System.Object, which has a method named GetType() that will return the type of the object--which can solve your first question of testing bs1

Type bs1DataType = bs1.DataSource.GetType();
string bs1DataTypeName = bs1DataType.Name;

The second question is a little unclear; you can use the same method to determine that bs2.DataSource's Type == BindingSource (since you set it to bs1). You can then cast it from Object back to BindingSource and query it's DataSource Property to determine the underlying type (Essentially just doing the same thing as the above example to determine bs1's underlying datasource type).

// Since bs2's DataSource type is a BindingSource, you
// can cast it as such and query it's underlying data-type as well
BindingSource bs2DataBindingSource = (BindingSource)bs2.DataSource;
Type bs2DataBindingSourceType = bs2DataBindingSource.DataSource.GetType();
Console.WriteLine(bs2DataBindingSourceType.Name);

It's all convoluted because you're digging through two binding sources to find the underlying type.


Could you possibly remove bs2, and just use bs1 as it's received from the external source? If you're already receiving a BindingSource then wrapping it inside another BindingSource seems very strange.

Another option would be to set bs2's DataSource to bs1's DataSource, rather than to bs` itself:

// This is essentially binding bs2 to the underlying List<Person>
bs2.DataSource = bs1.DataSource;
STW
Thanks for your comment - sorry I wasnt imprecise in my question. I've edited it and added better example. Hope now it is clear that the problem is with bs.DataMember rather than DataSource - because it allways points to List<Person> I need to get info what BS2 is 'hosting' -> in that case Person.Parents -> type I'd like to read would be List<Parent>. ANy idea how to get that??
Maciej
+1  A: 

You may also be looking for a way to precisely identify the type. To determine that a BindingSource bs has a DataSource that is a List<Parent>, you would do the following:

if (bs.DataSource.GetType() == typeof(List<Parent>))
{
  //Do something useful
}

Furthermore, to find if something is derived from a type (or that something implements a specific interface), use:

if (typeof(MyFancyType).IsAssignableFrom(bs.DataSource.GetType()))
{
  //Do something useful
}

IsAssignableFrom returns true if a variable with the passed type can be stored in a variable of type MyFancyType. For example:

if (typeof(object).IsAssignableFrom(typeof(string)))
{
  //Do something useful
}

Would always return true and do "something useful". (Because you can stick a string object reference into an object variable)

Where:

if (typeof(string).IsAssignableFrom(typeof(object)))
{
  //Do something useful
}

Would never do anything "useful". (you can't stick a generic object object reference into a string variable...(at compile time or without a cast))

ee
A: 

Seems I found solution finally...

Posted in separate thread

Hope it helps someone

Maciej