views:

79

answers:

2

I have a ASP gridview control. I have a ASP label control in the item template column. I bind data to the grid using -

<ItemTemplate>
        <asp:Label ID="lblDesc" runat="server" Text='<%# Eval("Description") %>'></asp:Label>
</ItemTemplate>

But, the value of this string can be upto 80 characters. But, I cannot afford to have the column length to be so high. And, there are limitations so I cannot use Wrap="true" and limit the column width.

So, I figured the solution could be to display only about 50 characters in the grid and display the entire string as a tool tip. I managed to do this by using this -

<ItemTemplate>
        <asp:Label ID="lblDesc" runat="server" Text='<%# Eval("Description").ToString().Substring(0,50) %>' ToolTip='<%# Eval("Description") %>'></asp:Label>
</ItemTemplate>

This displays the first 50 characters of the string in the grid column. And, the complete string is displayed as a tool tip when the mouse pointer hovers over the text. But, the problem arises when the string length is less than 50 characters. In this case, an exception is thrown.

I tried modifying this piece of code to allow conditional display by checking for the string length. But, I could not get this to work.

Is there a way to fix this problem? Can we call a javascript function within Eval() ?

+1  A: 

Whenever you need special handling for your databinding expressions, you can just make a helper function in your code-behind, such as

protected string EvalWithMaxLength(string fieldName, int maxLength)
{
    object value = this.Eval(fieldName);
    if (value == null)
        return null;
    string str = value.ToString();
    if (value.Length > maxLength)
        return value.SubString(0, maxLength);
    else
        return value;
}

In your ASPX/ASCX you can then say

<ItemTemplate>
    <asp:Label ID="lblDesc" runat="server" Text='<%# EvalWithMaxLength("Description", 50) %>' ToolTip='<%# Eval("Description") %>'></asp:Label>
</ItemTemplate>

If you'd like to separate the Eval and the truncate, you could make a general extension method like

public static class MyExtensions
{
    public static string ToStringTruncated(this object value, int maxLength)
    {
        if (value == null)
            return null;
        string str = value.ToString();
        if (value.Length > maxLength)
            return value.SubString(0, maxLength);
        else
            return value;
    }
}

and call

Text='<%# Eval("Description").ToStringTruncated(50) %>'

And because you've made this extension method for type object, you can now also say

1234.ToStringTruncated(3) // == "123"

Whether you'd like that is a matter of taste.

Ruben
+2  A: 

Try something like this:

public static string TruncateString(string longString, int maxLength)
{
    if (string.IsNullOrEmpty(longString) || longString.Length <= maxLength)
    {
        return longString;
    }
    else
    {
        return longString.Substring(0, maxLength);
    }
}

Then your code in the aspx would be something like:

<%# TruncateString(Eval("FieldName").ToString(), 150) %>

You might also want to add a postFix parameter to the above so that truncated strings get appended with, say, an ellipsis (...) to warn the user that they've been truncated.

I like to keep things like this in utility classes so that they're available throughout the application. I also think it's a good idea not to try to combine this and Eval into a single method, since a) they're doing very different things, and b) you might want to use the above where you're not using Eval.

Edit: If want to allow Eval("FieldName") to be null without throwing a null reference exception, use this instead:

<%# TruncateString((Eval("FieldName") ?? "").ToString(), 150) %>
Justin Morgan
Be careful with `Eval("...").ToString()`. If Eval returns null, you'd get a NullReferenceException. You could try `<%# TruncateString((Eval("FieldName") ?? "").ToString(), 150) %>` but that doesn't make things more readable.
Ruben
Good call. I was looking for my old code from when I did this before, but I couldn't find it, so the above was pretty much on the fly. I personally like your ?? idea; it would be more readable if only the coalesce operator weren't so (undeservedly) obscure.
Justin Morgan
Personally I'm going into punctuation overload with this solution; but `<%# TruncateString((string)Eval("FieldName"), 150) %>` will bomb if you're using DataTables and you'd get a `DBNull` value back.
Ruben