DataGridView / DataPropertyName - Displaying nested object information

C

connected

I'm having difficulty with populating a DataGridView control with data
correctly. It works with a single class, for example...


class MyClass
{
private string _propertyOne;
private string _propertyTwo;

public string PropertyOne { get { return this._propertyOne; } }
public string PropertyTwo { get { return this._propertyTwo; } }

public MyClass(string propertyOne, string propertyTwo)
{
this._propertyOne = propertyOne;
this._propertyTwo = propertyTwo;
}
}


I can create a DataGridView and bind it to a BindingList of MyClasses
as follows:


myGrid.AutoGenerateColumns = false;

myGrid.Columns.Add("propertyOneColumn", "Property 1");
myGrid.Columns.Add("propertyTwoColumn", "Property 2");

myGrid.Columns["propertyOneColumn"].DataPropertyName = "PropertyOne";
myGrid.Columns["propertyTwoColumn"].DataPropertyName = "PropertyTwo";

myGrid.DataSource = new BindingList<MyClass>(
new MyClass[]
{
new MyClass("big", "small"),
new MyClass("hot", "cold"),
new MyClass("fast", "slow")
}
);


This works very well, and now I have a DataGridView with two columns
and three rows of data being displayed. However, in the real world, we
often deal with composition. For example...


class MyNestedClass
{
private string _propertyThree;

public string PropertyThree { get { return this._propertyThree; } }

public MyNestedClass(string propertyThree)
{
this._propertyThree = propertyThree;
}
}

class MyClass
{
private string _propertyOne;
private string _propertyTwo;
private MyNestedClass _nestedObject;

public string PropertyOne { get { return this._propertyOne; } }
public string PropertyTwo { get { return this._propertyTwo; } }
public MyNestedClass NestedObject { get { return
this._nestedObject; } }

public MyClass(string propertyOne, string propertyTwo,
MyNestedClass nestedObject)
{
this._propertyOne = propertyOne;
this._propertyTwo = propertyTwo;
this._nestedObject = nestedObject;
}
}


Unfortunately, this is where I start having a problem because now I
have to adjust the code for the DataGridView...


myGrid.AutoGenerateColumns = false;

myGrid.Columns.Add("propertyOneColumn", "Property 1");
myGrid.Columns.Add("propertyTwoColumn", "Property 2");
myGrid.Columns.Add("propertyThreeColumn", "Property 3");

myGrid.Columns["propertyOneColumn"].DataPropertyName = "PropertyOne";
myGrid.Columns["propertyTwoColumn"].DataPropertyName = "PropertyTwo";
myGrid.Columns["propertyThreeColumn"].DataPropertyName = ?????;

myGrid.DataSource = new BindingList<MyClass>(
new MyClass[]
{
new MyClass("big", "small", new MyNestedClass("medium")),
new MyClass("hot", "cold", new MyNestedClass("warm")),
new MyClass("fast", "slow", new MyNestedClass("steady"))
}
);


As you can see, I don't know what to put for the DataPropertyName for
the third column. Someone previously suggested
"NestedObject.PropertyThree," however this does NOT work. Yet another
suggestion was to create a public accessor in MyClass like this:


public string PropertyThree { get { return
this._nestedObject.PropertyThree; } }


To say that this is a half-assed workaround would be modest at best. I
am looking for the proper way to implement this, not a cheap hack. If
anyone knows the right way, I would be very grateful if you would share
your wisdom on this topic.
 
G

Guest

Hi,

If you try to display an object in DataGridView, it will display the string
property of the object. So, 1st you must override the ToString() method of
MyNestedClass.

class MyNestedClass
{
private string _propertyThree;

public string PropertyThree { get { return this._propertyThree; } }

public MyNestedClass(string propertyThree)
{
this._propertyThree = propertyThree;
}

public override string ToString()
{
return this._propertyThree;
}
}

Now you must change the DataPropertyName as bellow,
myGrid.Columns["propertyThreeColumn"].DataPropertyName = "NestedObject";

Cheers,
Chester

connected said:
I'm having difficulty with populating a DataGridView control with data
correctly. It works with a single class, for example...


class MyClass
{
private string _propertyOne;
private string _propertyTwo;

public string PropertyOne { get { return this._propertyOne; } }
public string PropertyTwo { get { return this._propertyTwo; } }

public MyClass(string propertyOne, string propertyTwo)
{
this._propertyOne = propertyOne;
this._propertyTwo = propertyTwo;
}
}


I can create a DataGridView and bind it to a BindingList of MyClasses
as follows:


myGrid.AutoGenerateColumns = false;

myGrid.Columns.Add("propertyOneColumn", "Property 1");
myGrid.Columns.Add("propertyTwoColumn", "Property 2");

myGrid.Columns["propertyOneColumn"].DataPropertyName = "PropertyOne";
myGrid.Columns["propertyTwoColumn"].DataPropertyName = "PropertyTwo";

myGrid.DataSource = new BindingList<MyClass>(
new MyClass[]
{
new MyClass("big", "small"),
new MyClass("hot", "cold"),
new MyClass("fast", "slow")
}
);


This works very well, and now I have a DataGridView with two columns
and three rows of data being displayed. However, in the real world, we
often deal with composition. For example...


class MyNestedClass
{
private string _propertyThree;

public string PropertyThree { get { return this._propertyThree; } }

public MyNestedClass(string propertyThree)
{
this._propertyThree = propertyThree;
}
}

class MyClass
{
private string _propertyOne;
private string _propertyTwo;
private MyNestedClass _nestedObject;

public string PropertyOne { get { return this._propertyOne; } }
public string PropertyTwo { get { return this._propertyTwo; } }
public MyNestedClass NestedObject { get { return
this._nestedObject; } }

public MyClass(string propertyOne, string propertyTwo,
MyNestedClass nestedObject)
{
this._propertyOne = propertyOne;
this._propertyTwo = propertyTwo;
this._nestedObject = nestedObject;
}
}


Unfortunately, this is where I start having a problem because now I
have to adjust the code for the DataGridView...


myGrid.AutoGenerateColumns = false;

myGrid.Columns.Add("propertyOneColumn", "Property 1");
myGrid.Columns.Add("propertyTwoColumn", "Property 2");
myGrid.Columns.Add("propertyThreeColumn", "Property 3");

myGrid.Columns["propertyOneColumn"].DataPropertyName = "PropertyOne";
myGrid.Columns["propertyTwoColumn"].DataPropertyName = "PropertyTwo";
myGrid.Columns["propertyThreeColumn"].DataPropertyName = ?????;

myGrid.DataSource = new BindingList<MyClass>(
new MyClass[]
{
new MyClass("big", "small", new MyNestedClass("medium")),
new MyClass("hot", "cold", new MyNestedClass("warm")),
new MyClass("fast", "slow", new MyNestedClass("steady"))
}
);


As you can see, I don't know what to put for the DataPropertyName for
the third column. Someone previously suggested
"NestedObject.PropertyThree," however this does NOT work. Yet another
suggestion was to create a public accessor in MyClass like this:


public string PropertyThree { get { return
this._nestedObject.PropertyThree; } }


To say that this is a half-assed workaround would be modest at best. I
am looking for the proper way to implement this, not a cheap hack. If
anyone knows the right way, I would be very grateful if you would share
your wisdom on this topic.
 
C

connected

Thanks for the prompt response. Unfortunately, while valid in this
particular case, this is not a universal solution. Consider the
possibility that MyNestedClass may have more properties that must also
be displayed in their own columns on the DataGridView, as in...


class MyNestedClass
{
private string _propertyThree;
private string _propertyFour;

public string PropertyThree { get { return this._propertyThree; } }
public string PropertyFour { get { return this._propertyFour; } }

public MyNestedClass(string propertyThree, string propertyFour)
{
this._propertyThree = propertyThree;
this._propertyFour = propertyFour;
}
}


Now the ToString() hack will not work because it can only return one
property at a time.
Hi,

If you try to display an object in DataGridView, it will display the string
property of the object. So, 1st you must override the ToString() method of
MyNestedClass.

class MyNestedClass
{
private string _propertyThree;

public string PropertyThree { get { return this._propertyThree; } }

public MyNestedClass(string propertyThree)
{
this._propertyThree = propertyThree;
}

public override string ToString()
{
return this._propertyThree;
}
}

Now you must change the DataPropertyName as bellow,
myGrid.Columns["propertyThreeColumn"].DataPropertyName = "NestedObject";

Cheers,
Chester

connected said:
I'm having difficulty with populating a DataGridView control with data
correctly. It works with a single class, for example...


class MyClass
{
private string _propertyOne;
private string _propertyTwo;

public string PropertyOne { get { return this._propertyOne; } }
public string PropertyTwo { get { return this._propertyTwo; } }

public MyClass(string propertyOne, string propertyTwo)
{
this._propertyOne = propertyOne;
this._propertyTwo = propertyTwo;
}
}


I can create a DataGridView and bind it to a BindingList of MyClasses
as follows:


myGrid.AutoGenerateColumns = false;

myGrid.Columns.Add("propertyOneColumn", "Property 1");
myGrid.Columns.Add("propertyTwoColumn", "Property 2");

myGrid.Columns["propertyOneColumn"].DataPropertyName = "PropertyOne";
myGrid.Columns["propertyTwoColumn"].DataPropertyName = "PropertyTwo";

myGrid.DataSource = new BindingList<MyClass>(
new MyClass[]
{
new MyClass("big", "small"),
new MyClass("hot", "cold"),
new MyClass("fast", "slow")
}
);


This works very well, and now I have a DataGridView with two columns
and three rows of data being displayed. However, in the real world, we
often deal with composition. For example...


class MyNestedClass
{
private string _propertyThree;

public string PropertyThree { get { return this._propertyThree; } }

public MyNestedClass(string propertyThree)
{
this._propertyThree = propertyThree;
}
}

class MyClass
{
private string _propertyOne;
private string _propertyTwo;
private MyNestedClass _nestedObject;

public string PropertyOne { get { return this._propertyOne; } }
public string PropertyTwo { get { return this._propertyTwo; } }
public MyNestedClass NestedObject { get { return
this._nestedObject; } }

public MyClass(string propertyOne, string propertyTwo,
MyNestedClass nestedObject)
{
this._propertyOne = propertyOne;
this._propertyTwo = propertyTwo;
this._nestedObject = nestedObject;
}
}


Unfortunately, this is where I start having a problem because now I
have to adjust the code for the DataGridView...


myGrid.AutoGenerateColumns = false;

myGrid.Columns.Add("propertyOneColumn", "Property 1");
myGrid.Columns.Add("propertyTwoColumn", "Property 2");
myGrid.Columns.Add("propertyThreeColumn", "Property 3");

myGrid.Columns["propertyOneColumn"].DataPropertyName = "PropertyOne";
myGrid.Columns["propertyTwoColumn"].DataPropertyName = "PropertyTwo";
myGrid.Columns["propertyThreeColumn"].DataPropertyName = ?????;

myGrid.DataSource = new BindingList<MyClass>(
new MyClass[]
{
new MyClass("big", "small", new MyNestedClass("medium")),
new MyClass("hot", "cold", new MyNestedClass("warm")),
new MyClass("fast", "slow", new MyNestedClass("steady"))
}
);


As you can see, I don't know what to put for the DataPropertyName for
the third column. Someone previously suggested
"NestedObject.PropertyThree," however this does NOT work. Yet another
suggestion was to create a public accessor in MyClass like this:


public string PropertyThree { get { return
this._nestedObject.PropertyThree; } }


To say that this is a half-assed workaround would be modest at best. I
am looking for the proper way to implement this, not a cheap hack. If
anyone knows the right way, I would be very grateful if you would share
your wisdom on this topic.
 
G

Guest

Hi,

Good point, but DataGridView doesn't support databinding to child
properties. For more info, check this post -
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=834204&SiteID=1

Cheers,
Chester

connected said:
Thanks for the prompt response. Unfortunately, while valid in this
particular case, this is not a universal solution. Consider the
possibility that MyNestedClass may have more properties that must also
be displayed in their own columns on the DataGridView, as in...


class MyNestedClass
{
private string _propertyThree;
private string _propertyFour;

public string PropertyThree { get { return this._propertyThree; } }
public string PropertyFour { get { return this._propertyFour; } }

public MyNestedClass(string propertyThree, string propertyFour)
{
this._propertyThree = propertyThree;
this._propertyFour = propertyFour;
}
}


Now the ToString() hack will not work because it can only return one
property at a time.
Hi,

If you try to display an object in DataGridView, it will display the string
property of the object. So, 1st you must override the ToString() method of
MyNestedClass.

class MyNestedClass
{
private string _propertyThree;

public string PropertyThree { get { return this._propertyThree; } }

public MyNestedClass(string propertyThree)
{
this._propertyThree = propertyThree;
}

public override string ToString()
{
return this._propertyThree;
}
}

Now you must change the DataPropertyName as bellow,
myGrid.Columns["propertyThreeColumn"].DataPropertyName = "NestedObject";

Cheers,
Chester

connected said:
I'm having difficulty with populating a DataGridView control with data
correctly. It works with a single class, for example...


class MyClass
{
private string _propertyOne;
private string _propertyTwo;

public string PropertyOne { get { return this._propertyOne; } }
public string PropertyTwo { get { return this._propertyTwo; } }

public MyClass(string propertyOne, string propertyTwo)
{
this._propertyOne = propertyOne;
this._propertyTwo = propertyTwo;
}
}


I can create a DataGridView and bind it to a BindingList of MyClasses
as follows:


myGrid.AutoGenerateColumns = false;

myGrid.Columns.Add("propertyOneColumn", "Property 1");
myGrid.Columns.Add("propertyTwoColumn", "Property 2");

myGrid.Columns["propertyOneColumn"].DataPropertyName = "PropertyOne";
myGrid.Columns["propertyTwoColumn"].DataPropertyName = "PropertyTwo";

myGrid.DataSource = new BindingList<MyClass>(
new MyClass[]
{
new MyClass("big", "small"),
new MyClass("hot", "cold"),
new MyClass("fast", "slow")
}
);


This works very well, and now I have a DataGridView with two columns
and three rows of data being displayed. However, in the real world, we
often deal with composition. For example...


class MyNestedClass
{
private string _propertyThree;

public string PropertyThree { get { return this._propertyThree; } }

public MyNestedClass(string propertyThree)
{
this._propertyThree = propertyThree;
}
}

class MyClass
{
private string _propertyOne;
private string _propertyTwo;
private MyNestedClass _nestedObject;

public string PropertyOne { get { return this._propertyOne; } }
public string PropertyTwo { get { return this._propertyTwo; } }
public MyNestedClass NestedObject { get { return
this._nestedObject; } }

public MyClass(string propertyOne, string propertyTwo,
MyNestedClass nestedObject)
{
this._propertyOne = propertyOne;
this._propertyTwo = propertyTwo;
this._nestedObject = nestedObject;
}
}


Unfortunately, this is where I start having a problem because now I
have to adjust the code for the DataGridView...


myGrid.AutoGenerateColumns = false;

myGrid.Columns.Add("propertyOneColumn", "Property 1");
myGrid.Columns.Add("propertyTwoColumn", "Property 2");
myGrid.Columns.Add("propertyThreeColumn", "Property 3");

myGrid.Columns["propertyOneColumn"].DataPropertyName = "PropertyOne";
myGrid.Columns["propertyTwoColumn"].DataPropertyName = "PropertyTwo";
myGrid.Columns["propertyThreeColumn"].DataPropertyName = ?????;

myGrid.DataSource = new BindingList<MyClass>(
new MyClass[]
{
new MyClass("big", "small", new MyNestedClass("medium")),
new MyClass("hot", "cold", new MyNestedClass("warm")),
new MyClass("fast", "slow", new MyNestedClass("steady"))
}
);


As you can see, I don't know what to put for the DataPropertyName for
the third column. Someone previously suggested
"NestedObject.PropertyThree," however this does NOT work. Yet another
suggestion was to create a public accessor in MyClass like this:


public string PropertyThree { get { return
this._nestedObject.PropertyThree; } }


To say that this is a half-assed workaround would be modest at best. I
am looking for the proper way to implement this, not a cheap hack. If
anyone knows the right way, I would be very grateful if you would share
your wisdom on this topic.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top