How to implement conditional formatting in a GridV

2020-04-07 06:50发布

问题:

I have a GridView on my aspx page which displays a collection of objects defined by the following class

public class Item
{
    public string ItemName{get; set;}
    public object ItemValue{get; set;}
}

Then in my aspx markup I have something like this

<asp:GridView ID="MyTable" runat="server">
    <Columns>
        <asp:BoundField DataField="ItemName" />
        <asp:BoundField DataField="ItemValue" />
    </Columns>
</asp:GridView>

What I want to know is:
Is there a way to use conditional formatting on the ItemValue field, so that if the object is holding a string it will return the string unchanged, or if it holds a DateTime it will displays as DateTime.ToShortDateString().

回答1:

Not sure if you can use a BoundField, but if you change it to a TemplateField you could use a formatting function like in this link.

ie something like

<%# FormatDataValue(DataBinder.Eval(Container.DataItem,"ItemValue")) %>

Then in your codebehind, you can add a Protected Function

Protected Function FormatDataValue(val as object) As String
    'custom enter code hereformatting goes here
End Function

Or you could do something in the OnRowCreated event of the gridview, like in this link

<asp:GridView ID="ctlGridView" runat="server" OnRowCreated="OnRowCreated" />

this function is conditional formatting based on whether or not the datavalue is null/is a double

protected void OnRowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        DataRowView drv = e.Row.DataItem as DataRowView;
        Object ob = drv["ItemValue"];


        if (!Convert.IsDBNull(ob) )
        {
            double dVal = 0f;
             if (Double.TryParse(ob.ToString(), out dVal))
             {
                 if (dVal > 3f)
                 {
                     TableCell cell = e.Row.Cells[1];
                     cell.CssClass = "heavyrow";
                     cell.BackColor = System.Drawing.Color.Orange;
                 }
             }
        }
    }
}


回答2:

i decided with the Paul Rowland solution and more one thing "if (e.Item.DataItem is DataRowView)":

    if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType ==                 ListItemType.AlternatingItem))
     {
       if (e.Item.DataItem is DataRowView)
       {
         DataRowView rowView = (DataRowView)e.Item.DataItem;
         String state = rowView[PutYourColumnHere].ToString();
         if (state.Equals("PutYourConditionHere"))
         {
           //your formating, in my case....
           e.Item.CssClass = "someClass";
         }
       }
     }


回答3:

With BoundField you should modify your Item class.

If you don't want to modify your CodeBehind ther is a sort of trick you can do using a TemplateField:

        <asp:GridView ID="MyTable" runat="server" AutoGenerateColumns="False">
        <Columns>
            <asp:BoundField DataField="ItemName" HeaderText="Name" />
            <asp:TemplateField HeaderText="Value">
                <ItemTemplate>
                    <asp:Label ID="Label1" runat="server" Text='<%# ((Eval("ItemValue") is DateTime) ? ((DateTime)Eval("ItemValue")).ToShortDateString() : Eval("ItemValue")) %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

obviously you can do it for any type of object but maybe your "Text" field would become.. complicated..

by the way.. my CodeBehind for this example was just you class Item and this Page_Load():

    protected void Page_Load(object sender, EventArgs e)
    {
        Item i1 = new Item();
        i1.ItemName = "name1";
        i1.ItemValue = "foo";
        Item i2 = new Item();
        i2.ItemName = "name2";
        i2.ItemValue = DateTime.Now;
        List<Item> list1 = new List<Item>();
        list1.Add(i1);
        list1.Add(i2);
        MyTable.DataSource = list1;
        MyTable.DataBind();
    }

and the result was correct ;)



回答4:

In .NET 2.0 is even easier:

Add this method to code behind: (this example formats a double value as million with 1 digit)

public string EvalAmount(string expression)
{
    double? dbl = this.Eval(expression) as double?;
    return dbl.HasValue ? string.Format("{0:0.0}", (dbl.Value / 1000000D)) : string.Empty;
}

In the aspx code, use this:

<asp:TemplateField ItemStyle-Width="100px">
    <ItemTemplate>
        <asp:Label runat="server" Text='<%# EvalAmount("MyAmount") %>'></asp:
    </ItemTemplate>
</asp:TemplateField>