Saturday 24 July 2010

Conditional Row Highlighting in Dynamic Data

There are occasions when you want to highlight a row in the GridView (I usually want this based on a Boolean field) so here’s what you do.

First of all we need some way of telling the column to do this an I usually use an attribute see Listing 1 it have two properties one for the value when we want the CSS class to be applied, and the other the CSS class to apply.

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class RowHighlightingAttribute : Attribute
{
    /// <summary>
    /// Initializes a new instance of the <see cref="RowHighlightingAttribute"/> class.
    /// </summary>
    /// <param name="valueWhenTrue">The value when true.</param>
    /// <param name="cssClass">The CSS class.</param>
    public RowHighlightingAttribute(String valueWhenTrue, String cssClass)
    {
        ValueWhenTrue = valueWhenTrue;
        CssClass = cssClass;
    }

    /// <summary>
    /// Gets or sets the value when true.
    /// </summary>
    /// <value>The value when true.</value>
    public String ValueWhenTrue { get; set; }

    /// <summary>
    /// Gets or sets the CSS class.
    /// </summary>
    /// <value>The CSS class.</value>
    public String CssClass { get; set; }
}

Listing 1 – RowHighlightingAttribute

Next we need a way of applying the CSS class based on the condition, see Listing 2.

/// <summary>
/// Highlights the row.
/// </summary>
/// <param name="fieldTemplate">The field template.</param>
public static void HighlightRow(this FieldTemplateUserControl fieldTemplate)
{
    // get the attribute
    var rowHighlighting = fieldTemplate.MetadataAttributes.GetAttribute<RowHighlightingAttribute>();
    // make sure the attribute is not null
    if (rowHighlighting != null)
    {
        // get the GridViewRow, note this will not
        // be present in a DetailsView.
        var parentRow = fieldTemplate.GetContainerControl<GridViewRow>();
        if (parentRow != null 
            && rowHighlighting.ValueWhenTrue == fieldTemplate.FieldValueString)
        {
            // apply the CSS class appending if a class is already applied.
            if (String.IsNullOrWhiteSpace(parentRow.CssClass))
                parentRow.CssClass += " " + rowHighlighting.CssClass;
            else
                parentRow.CssClass = rowHighlighting.CssClass;
        }
    }
}

Listing 2 – HighlightRow extension method

Now to add the extension method to a field template, we will apply it to the Boolean read-only field template.

protected override void OnDataBinding(EventArgs e)
{
    base.OnDataBinding(e);

    object val = FieldValue;
    if (val != null)
        CheckBox1.Checked = (bool)val;

    // apply highlighting
    this.HighlightRow();
}

Listing 3 – Apply highlighting.

For the sample I’ve also added it to the Text.ascx.cs field template.

Adding some attributes

Metadata applied

Figure 1 - Metadata applied

You could also us this technique on other values, but this will do for this sample.

Row Highlighting applied

Figure 2 – Row Highlighting applied.

So you can see with a little bit of work you can add conditional row level highlighting to Dynamic Data.

Download

7 comments:

Alexander said...

Need help regarding Foreign Key relationship in Dynamic Data [Linq to Sql] project.

I have two tables : Dealer & DealerVendor and the relationShip is set on DealerId(One to Many) and not on ID.

the structure of tables are :

Table Dealer :
Id as Int Primary
DealerID as string,
Description as string

Table DealerVendor :
Id as int primary,
DealerID as string

my problem is that, that when i click on Dealer Table it displays the DealerVendor column but when i click on DealerVendor link i got an error
"Operator '==' incompatible with operand types 'String' and 'Int32' "

because the List.aspx shows the querystring of ID column not the DealerID.....

I want that it should display the DealerId link so that DealerVendor table can be sorted on "DealerId"...

Please help me in this matter.

Appreciate for quick help.

Stephen J. Naughton said...

You cannot have that kind of relationship it must be PK->FK not FK->FK

Steve

Shankey said...

hey i have three tables..
CowDetail Cow no PK
BullDetail BULL no PK
ANd Medication Detail
Animal No FK

I want to link Animal No FK with both Cow No and BUll no

Thanks for help

Stephen J. Naughton said...

To have relationships in DD you MUSt have those same relationships in the Database.

Steve

Shankey said...

how can we have a FKRelationship with the Who columns?

Stephen J. Naughton said...

Hi Shankey, this is a little off topic so I wont reply here please post to ASP.Net Dynamic Data Forum

Steve

Unknown said...

Hi Steve,

is it possible to add some conditional comparision. e.g. if value is bigger than 5 and smaller than 2 make the gridview linge highlighted.

Where am I supposed to extend your class?

BR
Souf