Q: DataGrid [Attribute] - $10 for answer

B

Bret Pehrson

(I'm resorting to bribery for an answer here... First person to post to
_newsgroup_ a definitive and substantive answer (i.e. references), I'll give
$10.)

Question/issue:

I'm using a custom data source for my (WinForms) datagrid:

public class MyDataSource : IList
{
public void AddRow(string firstName, string lastName, ...);
// ...
}

each row is a:

public class MyDataRow
{
public string FirstName
{
get { return firstName; }
}
private string firstName;
//...
}

Then:

MyDataSource data = new MyDataSource();
data.AddRow("Bret", "Pehrson" //...

grid.DataSource = data;


Now, everything displays fine in the datagrid. I'm not using any designer or
other parameters to set up the columns, just letting the data source and grid
figure that out. The only problem that I have is that I want the DataGrid to
display "First name" as the column header and not "FirstName" as is currently
happening.

What I'd hope would be possible is some attribute on the FirstName property
that would specify the column name, something like

[HeaderText("First name")]
public string FirstName
{
get { return firstName; }
}

Is there such a beast? I've looked and looked, and can't find anything. I
want all of this to be done in the code for the MyDataRow/MyDataSource class.

Thanks

(There is probably a better newsgroup for this post, but I couldn't find that
either. The only DataGrid newsgroup I could find was for ASP.NET.)
 
N

Nicholas Paldino [.NET/C# MVP]

Bret,

I believe that what you want to do is use the ICustomTypeDescriptor
interface on your MyDataRow class. This will allow you to return type
descriptor information which the grid will pick up and use to display it's
properties. I don't know if you can actually use "First name" as a column
header, as that is not a valid property name in .NET, but you can try.

Of course, why not just go to the DataGrid and modify the
DataGridColumnStyle instances to just change the header name? You can add
the data grid column styles first, and then bind your data source to the
grid, and it should work (with out you having to implement the custom type
descriptor interface).

Hope this helps.
 
B

Bret Pehrson

Nicholas Paldino said:
Bret,

I believe that what you want to do is use the ICustomTypeDescriptor
interface on your MyDataRow class. This will allow you to return type
descriptor information which the grid will pick up and use to display it's
properties. I don't know if you can actually use "First name" as a column
header, as that is not a valid property name in .NET, but you can try.

Of course, why not just go to the DataGrid and modify the
DataGridColumnStyle instances to just change the header name? You can add
the data grid column styles first, and then bind your data source to the
grid, and it should work (with out you having to implement the custom type
descriptor interface).

What I'm after is completely separating the data design from the (coded)
presentation layer.

In my case, although I didn't elaborate on it in my original post, is that the
grid will actually be displaying search results -- the output columns, types,
etc. are all dependent on the inputs, therefore a particular column may or may
not actually be there from search to search. It seems like it would be a
trivial to have originally implemented the DataGrid in such a way as to query
for a (predefined) set of public property attributes that would ultimately
control the appearance of the column, cell, and related formatting -- true
data-driven design.

I'll look at the ICustomTypeDescriptor and see if it does what I need and
report back. Thanks for the response so far...

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Bret Pehrson said:
(I'm resorting to bribery for an answer here... First person to post to
_newsgroup_ a definitive and substantive answer (i.e. references), I'll
give
$10.)

Question/issue:

I'm using a custom data source for my (WinForms) datagrid:

public class MyDataSource : IList
{
public void AddRow(string firstName, string lastName, ...);
// ...
}

each row is a:

public class MyDataRow
{
public string FirstName
{
get { return firstName; }
}
private string firstName;
//...
}

Then:

MyDataSource data = new MyDataSource();
data.AddRow("Bret", "Pehrson" //...

grid.DataSource = data;


Now, everything displays fine in the datagrid. I'm not using any designer
or
other parameters to set up the columns, just letting the data source and
grid
figure that out. The only problem that I have is that I want the DataGrid
to
display "First name" as the column header and not "FirstName" as is
currently
happening.

What I'd hope would be possible is some attribute on the FirstName
property
that would specify the column name, something like

[HeaderText("First name")]
public string FirstName
{
get { return firstName; }
}

Is there such a beast? I've looked and looked, and can't find anything.
I
want all of this to be done in the code for the MyDataRow/MyDataSource
class.

Thanks

(There is probably a better newsgroup for this post, but I couldn't find
that
either. The only DataGrid newsgroup I could find was for ASP.NET.)
 
J

John J. Hughes II

Bret,

What I do for a data query windows I have is create a new dataset based on
the received data, create a new set of data style columns and set the data
grid to use the new dataset. This way the colunm header and column types
are the same as the returned data.

SqlCommand cmd = new SqlCommand(cmdStr, conn);
SqlDataReader dr = cmd.ExecuteReader();

DataTable dt = new DataTable();

for(int i=0; i<dr.FieldCount; i++)
dt.Columns.Add(dr.GetName(i), dr.GetType());

if(dsFlag)
{
DataSet dsData = new DataSet();
dsData.Tables.Add(dt);

DataGridTableStyle ts = new DataGridTableStyle();
ts.MappingName = dsData.Tables[0].TableName;
ts.RowHeadersVisible = true;
ts.RowHeaderWidth = 16;

for(int i=0;i<dr.FieldCount; i++)
{
DataGridTextBoxColumn c1 = new DataGridTextBoxColumn();
c1.Format = "";
c1.FormatInfo = null;
c1.HeaderText = dr.GetName(i);
c1.MappingName = dr.GetName(i);
switch(dr.GetDataTypeName(i))
{
case "datetime":
c1.Width = 130;
break;
case "int":
c1.Width = 50;
break;
case "varchar":
c1.Width = 200;
break;
default:
c1.Width = dr.GetName(i).Length * 10;
break;
}
c1.ReadOnly = true;
ts.GridColumnStyles.Add(c1);
}

BeginInvoke(new SetDataGrid(SetDataGridSource), new object[]{dsData});
BeginInvoke(new SetDataTableStyleDelegate(SetDataTableStyle), new
object[]{ts});
}
BeginInvoke(new EnableStopMenu(EnableStop), null);

while(!IsCancel() && dr.Read())
{
DataRow row = dt.NewRow();
for(int i=0; i<dr.FieldCount; i++)
row = dr;

BeginInvoke(new SetDataGridRowDelegate(SetDataGridRow), new object[]{row});
}

dr.Close();

Regards,
John
 

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