0

I have a GridView whose data source is built dynamically as a DataTable - how can I specify column-specific header wrapping considering I'm specifying the structure in code?

I've not found anything to deal with this specific situation as I need to wrap only some columns in specific places, e.g. wrapping the second column below after 'Long' but leaving others alone. Adding \n or <br /> don't work as they're just treated as literals.

var statsTable = new DataTable();
statsTable.Columns.Add("Run Date", typeof(DateTime));
statsTable.Columns.Add("Needlessly Long Test Header", typeof(string));
...etc

statsTable.Rows.Add(runDate, "example", ...)

gridView.DataSource = statsTable;
gridView.DataBind();

Not sure if this is relevant, but I've found that I need to keep AutoGenerateColumns = true on my GridView otherwise nothing shows up. This is confusing me as I thought specifying the columns would do the trick - if this is unrelated to this question I'll ask another later.

Using .Net 3.5, if that affects answers. It seems like it'd be a simple/common problem.

Alex
  • 2,681
  • 3
  • 28
  • 43
  • And you don't know which columns you need to wrap at design-time? – James Johnson Oct 25 '11 at 15:09
  • I do know, I'm just not sure how to go about it. In my example I need to wrap the second column after the word 'Long' but I can't find any relevant DataTable/DataRow methods or a way to specify it as part of the row/header text initialisation – Alex Oct 25 '11 at 15:20
  • So you need to wrap at a word, not at a certain length? And you're trying to figure out how to make the column wrap at the occurence of the word "long"? – James Johnson Oct 25 '11 at 15:23
  • Exactly, but I need to specify where, not just after `x` words. For that column, I want it to be "Needlessly Long / Test Header". I may have another that is "This One is Longer at the / Top", etc. – Alex Oct 25 '11 at 15:25
  • It sounds like it might be easier to search the DataTable for occurences of those words, and insert line breaks after them. – James Johnson Oct 25 '11 at 15:31
  • Is sticking a line break in the column headers that complex a task? :/ If I can't format them when creating the DataTable, can I somehow do it after I've set it as the DataSource? – Alex Oct 25 '11 at 16:47
  • Sticking a line break in the header isn't complicated, but the logic to search for those words and insert line-breaks after them is a bit more complicated. – James Johnson Oct 25 '11 at 16:49
  • Yeah, that's why I'm trying to avoid it. Is there a way to tell the gridview to interpret the data table header text as html so that it recognises the `
    `?
    – Alex Oct 25 '11 at 16:54
  • See my suggestion, and try using `HtmlDecode`. If not, try returning putting a LiteralControl in the header. – James Johnson Oct 25 '11 at 16:58

2 Answers2

0

You could use a custom class to achieve that:

class CustomDataRow
{
    public string ColumnHeader { get; set; }
    public string ColumnName { get; set; }
    public string ColumnValue { get; set; }
}

Then, instead of a DataTable, you could use a List to bind the grid. Then, in the ItemDataBound event you could cast the DataItem to a CustomDataRow. If e.Item.ItemType is header, set the header text. If it's an item, set the Text values.

Razvan Trifan
  • 534
  • 2
  • 6
  • Wouldn't ColumnHeader have exactly the same issue as what I have now? i.e. not understanding that `\n` or `
    ` should be line breaks and not string literals? Also, I have a number of different data types in the columns (could use `object` I guess...)
    – Alex Oct 25 '11 at 16:42
  • sorry it took so long to respond. if you're dealing with HTML, it may be a good idea to use HTTpUtility.Encode when saving the text to the db and use HttpUtility.Decode when writing it to the page. read more here http://www.dotnetperls.com/httputility – Razvan Trifan Oct 25 '11 at 17:20
0

Give something like this a shot:

Markup:

<asp:TemplateField>
    <HeaderTemplate>
        <%#HttpUtility.HtmlDecode(InsertBreaks(Eval("DataField")))%>
    </HeaderTemplate>
</asp:TemplateField>

With a LiteralControl:

<asp:TemplateField>
    <HeaderTemplate>
        <asp:Literal ID="litHeader" Text='<%#HttpUtility.HtmlDecode(InsertBreaks(Eval("DataField")))%>' Mode="PassThrough"></asp:Literal>
    </HeaderTemplate>
</asp:TemplateField>

Code-behind:

protected string InsertLineBreaks(string val)
{
    return val.Replace("long", "long<br/>").replace("foo", "foo<br/>");
}
James Johnson
  • 45,496
  • 8
  • 73
  • 110