Passing Arguments to a Dynamic Data Field Template from a UIHint Attribute

Update: Make sure to also check out: Generic Access to ASP.NET Dynamic Data UIHint Attribute Values

I’ve been working with Dynamic Data websites on and off for the last couple of weeks in order to prepare some screen casts I'm doing that demonstrate how to use the Infragistics toolset with Dynamic Data.

As I started building my sample I quickly found that I needed to pass arguments from a UIHint attribute in my model’s meta-data up to a field template.

The context I am working in features two auditing columns that are on each of my tables: CreatedOn and ModifiedOn.

The business rules are simple: when adding a record both fields must have the current date and time. When editing a record the ModifiedOn field must always have the current date and time – overwriting the existing data.

The field template I needed is easy to create, but it does require that I pass in an argument telling the template whether or not to overwrite the date or to simply add the data if nothing is there.

Here’s how I implemented my solution.

I updated the model with the following meta-data:

[MetadataType(typeof(Intervew_Metadata))]
public partial class Interview{}

public class Intervew_Metadata
{
[UIHint("DateTimeAutoFill")]
public object CreatedOn;

[UIHint("DateTimeAutoFill",null,"Overwrite","true")]
public object ModifiedOn;
}

My two date fields are decorated with the UIHint attribute signaling to Dynamic Data that the control used to render these fields is my custom DateTimeAutoFill templates. The ModifiedOn field is using a params list to pass in a series of name/value arguments.

Here is my field template markup:

<%@ Control Language="C#" CodeFile="DateTimeAutoFill_Edit.ascx.cs" Inherits="DateTime_EditField" >
<%@ Register Assembly="Infragistics35.WebUI.WebDateChooser.v8.1, Version=8.1.20081.1000, Culture=neutral, PublicKeyToken=7dd5c3163f2cd0cb"
Namespace="Infragistics.WebUI.WebSchedule" TagPrefix="igsch" >

<igsch:WebDateChooser value="<%# FieldValueEditString %>" id="WebDateChooser1" runat="server">
</igsch:WebDateChooser>

<asp:RequiredFieldValidator runat="server" id="RequiredFieldValidator1" controltovalidate="WebDateChooser1" display="Dynamic" enabled="false"></asp:RequiredFieldValidator>

<asp:DynamicValidator runat="server" id="DynamicValidator1" controltovalidate="WebDateChooser1" display="Dynamic"></asp:DynamicValidator>

The ASCX is pretty basic. All that is here is my UI control and the needed validation controls.

Here’s the code-behind:

using System.ComponentModel.DataAnnotations;

...

protected override void OnPreRender(EventArgs e)
{
UIHintAttribute hint = null;
bool overwrite = false;

hint = (UIHintAttribute)this.Column.Attributes[typeof(UIHintAttribute)];

if (hint != null)
{
if (hint.ControlParameters.Count > 0)
{
if (hint.ControlParameters["Overwrite"] != null)
{
overwrite = Convert.ToBoolean(hint.ControlParameters["Overwrite"]);
}
}
}

if (overwrite)
{
this.WebDateChooser1.Value = DateTime.Now.ToString();
}
else
{
if (string.IsNullOrEmpty(this.WebDateChooser1.Value.ToString()))
{
this.WebDateChooser1.Value = DateTime.Now.ToString();
}
}

base.OnPreRender(e);

}

I chose to hook into the PreRender event so that I knew I was out of the way of any Dynamic Data processing and late enough in the page event lifecycle that all the data would be available.

The most interesting part about this code is how you get to the argument values. The values from the UIHint attribute are passed to the template in the Columns.Attribute collection. You can access the contents of the Attributes either via index or by passing in the type of the attribute that you are looking for.

Small Tangent
I can’t think of any reason why there would be more that one attribute of the same type so passing the type in seems like the best way to proceed – I could be totally wrong on this however.

I resist passing in the index because since I don’t know how the index position are decided, I don’t feel comfortable passing in hard-coded index position values. When debugging this sample I noticed that the UIHint attributed showed up in the 4th index position which I thought was curious because the UIHint attribute was the only attribute I added to the meta-data.

Once the hint attribute is found the next step is to query the ControlParameters collection for the arguments passed to the template. In this case the only option you have is to request the name/value pair by the string you used to define the argument in the meta-data. The rest of the code simply formats the controls according to my business rules.

I know this isn't a picture-perfect implementation for these fields. Really they should be read-only at all times and not give the user a chance to edit the values, but like I said this is just me getting to know the system.

Hopefully you will find this useful as you are building out your own dynamic data field templates!

 

Update: Make sure to also check out: Generic Access to ASP.NET Dynamic Data UIHint Attribute Values

4 Comments

  • Hi,
    I've been looking for this over all places related to dynamic data and finally have found here. However there is one glitch probably you could easily resolve. The control displays correct value but it doesn't persist to database. Maybe I am doing something wrong, but I cannot find it by myself. Any help will be greatly appreciated.

  • What happens when you debug through the code? Is your field template correctly reading the meta data to get to the argument?

  • This is regarding DYNAMIC DATA

    Let's say I have a grid showing the following labels: Size, color, material, style, sex, etc. These attributes are generic to all of the products of an specific kind.

    That means that NOT ALL ATTRIBUTES are the same for all kind of products. So this is a reference table (a parent table)

    I want my end user to fill in the blanks (TextBoxes to the right of the labels) these information and save it to the database, including all other info related to that product:audit, dates, logins, etc.

    So the process will be save all of this data in a different table: productID plus the gathered data from the grid plus all audit and control and loging fields

    Any help will be very welcomed

    Is that posible at all

  • Dynamic data is very much table-based, so I've never tried to do what you are describing. I suppose you could in theory either build up the UI elements required for the reference table in a custom class and expose it in the child tables, but then you'd be moving away from the 'dynamic' parts of dynamic data.

Comments have been disabled for this content.