Metadata method
Add a new class the your website called DefaultValueAttribute with the code below.
using System; using System.Collections.Generic; using System.Linq; using System.Web.DynamicData; [AttributeUsage(AttributeTargets.Property)] public class DefaultValueAttribute : System.Attribute { // As implemented, this identifier is merely the Type of the attribute. // However, it is intended that the unique identifier be used to identify // two attributes of the same type. public override object TypeId { get { return this; } } /// <summary> /// Constructor /// </summary> /// <param name="value">String</param> public DefaultValueAttribute(String value) { this._value = value; } private String _value; public String Value { get { return this._value; } } }
Listing 1 - DefaultValueAttribute
Add your metadata to the appropriate FK fields
[MetadataType(typeof(OrderMetadata))] public partial class Order { } public class OrderMetadata { [DefaultValue("3")] public Object Shipper { get; set; } }
Listing 2 - Metadata
Open your DynamicData FieldTemplates folder and edit the ForeigKey_Edit.aspx, and add an OnDataBound="DropDownList1_DataBound" entry as in Listing 3
<asp:DropDownList ID="DropDownList1" runat="server" CssClass="droplist" OnDataBound="DropDownList1_DataBound"> </asp:DropDownList>
Listing 3 - Adding the OnDataBound event handler
Next in the code behind file add the DropDownList1_DataBound event handler Listing 4a
protected void DropDownList1_DataBound(object sender, EventArgs e) { // value gotten via a query string as below //string value = Request.QueryString[Column.Name]; // value gotten via metadata string value = Column.GetDefaultValue(); if (this.Mode == DataBoundControlMode.Insert && !string.IsNullOrEmpty(value)) { ListItem item = this.DropDownList1.Items.FindByValue(value); if (item != null) { item.Selected = true; } } }
Listing 4a - The OnDataBound event handler Metadata version
In this event handler Listing 4a the default value is aquired via the metadata from Listing 2.
Query String Method
Open your DynamicData FieldTemplates folder and edit the ForeigKey_Edit.aspx, and add an OnDataBound="DropDownList1_DataBound" entry as in Listing 3, next in the code behind file add the DropDownList1_DataBound event handler Listing 4b see Figure 1 for the query string.
protected void DropDownList1_DataBound(object sender, EventArgs e) { // value gotten via a query string as below string value = Request.QueryString[Column.Name]; //// value gotten via metadata //string value = Column.GetDefaultValue(); if (this.Mode == DataBoundControlMode.Insert && !string.IsNullOrEmpty(value)) { ListItem item = this.DropDownList1.Items.FindByValue(value); if (item != null) { item.Selected = true; } } }
Listing 4b - The OnDataBound event handler QueryString version
Figure 1 - Query String
In Listing 4b event handler all I'm doing is checking for a value passed in the query string see Figure 1 as in this POST from the ASP.Net DynamicData Forum
Other FieldTemplates
This same pattern can be applied to all FieldTemplates for adding default values see Listing 5 which is added to the Text_Edit.ascx FieldTemplate.
protected void TextBox1_PreRender(object sender, EventArgs e) { // Adding a default value to a textbox // value aquired via metadata string value = Column.GetDefaultValue(); if (this.Mode == DataBoundControlMode.Insert && !string.IsNullOrEmpty(value)) { TextBox1.Text = value; } }
Listing 5
Again the value could be acquired either via metadata or query string Listing 6 would replace the line that contains Column.GetdefaultValue().
// value acquired via query string string value = Request.QueryString[Column.Name];
My feeling on this is you could do all this in the code behind of any of the pages that perform Inserts, on the OnPreRender event however if you put this code in more than one Insert page then you create a code maintenance issue. You will need to make changes in several different places, plus each extra Insert page you create will need this same code adding. However adding this small amount of code to each FieldTemplate you wish to have auto-fill of default values will reduce then amount of maintenance etc.
10 comments:
Thank you so much for this brilliant listing. Allowed me to do exactly what I needed. Ive used your blog for lots of dynamic data tid bits and it continues to be of great use! Keep up the good work!
nice, worked like a charm
This is fantastic and works great!
Now my issue is that I need to get this information passed back to the list page after the user clicks Insert or Cancel. It would be great if I could just carry the querystring forward, but that doesn't work. The list page expects query string keys of "Table.ID=X" or on lists with multiple filters "TableID=X". I wrote a very ugly hack to accomplish this but if you had any ideas to point me in a better direction that would be much appreciated. Thanks!
Hi Anon :) if you send me an e-mail direct (my address is at the top right of the page) we can have a chat and see what is the best way to do what you want.
Steve :D
Hi,
page_init in VS10 looks different and I tried it in a different ways but or it is avoiding the change or I have an error:
"Exception Details: System.ArgumentNullException: Value cannot be null.
Parameter name: dictionary"
Do you know What I should do ?
Hi Tali, move the code to the pages Pre-Render event.
Steve :D
Hi Steve, I have an issue with the DynamicHyperLink's URL that was generated using the wrong column name.
In my metadata, I have my Employee class plus, a property column [int CompanyId] and another [Company Company] property.
The DynamicHyperLink generates a URL with the Query Parameter, CompanyId=xx instead of Company=xx. However, the ForeignKey field template's Column.Name is 'Company'.
Hi redevolve, this is correct as the FK column in the DB would be CompanyId and the Navigation Property is Company.
This is easy to see in Entity Framework but not so easy in Linq to SQL.
Steve
Thanks, Steve. Do you think I should intercept the NavigateURL property to have it to generate the Navigation property instead of the FK column?
Do you have any suggestion on what's the correct way to solve this in order to have the Company auto-selected in the 'add new employee' page?
Thanks.
can you e-mail me direct my e-mail is in the top right of this site.
Steve
Post a Comment