The Idea here is that when you are navigating through your pages you will select some filters on the way as here in Figure 1 where we have selected a Customer an Employee and a Shipper so what I wanted was not to throw away that information when I clicked insert and then get Figure 2.
Figure 1 – Filtered List page
Figure 2 – Values Defaulted on Insert
Steps to Accomplish this:
- Modify ForeignKey_Edit.aspx.cs to check for query string parameters relating the column.
- Create a couple of extension methods to get the filters and then return a string of key, value query string.
- Hook up the Insert hyperlink to have these parameters if available to the insert URL.
Hope that makes sense.
Modify ForeignKey_Edit to check for query string parameters relating the column
This is relatively simple we just add an event handler to the DropDownList1’s PreRender event ForeignKey_Edit FieldTemplate code behind file.
protected void DropDownList1_PreRender(object sender, EventArgs e) { // Adding a default value to a textbox // value aquired via query string string value = Request.QueryString[Column.Name]; if (this.Mode == DataBoundControlMode.Insert && !string.IsNullOrEmpty(value)) { ListItem item = DropDownList1.Items.FindByValue(value); if (item != null) DropDownList1.SelectedValue = value; } }
Listing 1 – DropDownList’s PreRender event handler
What this does is check to see if there is a QueryString parameter that matches the column name and if this matches a value in the DropDownList’s Items collection it set’s this value as the DropDownList’s SelectedValue.
Creating Extension Methods that get the FilterUserControls and Return a String of Key, Value query string
There are two extension methods required:
- Gets a collection of the filters from the FilterRepeater that have a value.
- Take the filters and extract the key values pairs and return them as a QueryString to be appended to the Insert URL
Here’s the first one:
public static IEnumerable<FilterUserControlBase> GetFilterControls(this FilterRepeater filterRepeater) { var filters = new List<FilterUserControlBase>(); foreach (RepeaterItem item in filterRepeater.Items) { var filter = item.Controls.OfType<FilterUserControlBase>().FirstOrDefault(); if (filter != null) filters.Add(filter); } return filters.AsEnumerable(); }
Listing 2 – GetFilterControls extension method.
This extension method shown in Listing 2 just loops through the FilterRepeater Items collection and using the OfType<T>() Linq extension method gets the FilterUserControl from it’s controls collection. Then adds this to the the list of found filters and finally returns the list.
public static String GetQueryStringParameters(this FilterRepeater filterRepeater) { var filterControls = filterRepeater.GetFilterControls(); if (filterControls.Count() > 0) { var queryParameters = new StringBuilder(); queryParameters.Append("?"); foreach (var filter in filterControls) { if (filter.SelectedValue != "") queryParameters.Append(filter.DataField + "=" + filter.SelectedValue + "&"); } return queryParameters.ToString().Substring(0, queryParameters.Length - 1); } else return ""; }
Listing 3 – GetQueryStringParameters extensionmethod.
The second extension method shown in Listing 3 takes the output of the first and then loops through building the query parameters string for passing back to the caller.
Hook up the Insert hyperlink to the Returned Query Parameters
Now in the List page all you need to do is add the following code:
// setup the insert hyperlink InsertHyperLink.NavigateUrl = table.GetActionPath(PageAction.Insert) + FilterRepeater.GetQueryStringParameters();
Listing 4 – Putting the extension methods to use.
And this is why I like c# 3.0 extension methods so much
28 comments:
I am new to dynamic data and programming. I am trying to implement this solution but I do not know where the two Extension Methods goes. Where do I paste? In the ForeignKey_Edit.aspx.cs?.
Thanks
Just place the extension methods in a public class of their own in the App_Code folder (I usually call it ExtensionMethods and then put all my extension methods in there.
Steve :D
I create a new class and paste the two extension methods, but I tried to run with no result. It say among other things that the Extension methods must be defined in a non-generic static class and the type or namespace name 'FilterUserControlBase' could not be found (are you missing a using directive or an assembly reference?).
I know this is a blog not a support site, but I thank for the initial responds and any help that you can provide
Thanks.
mahiraldo@hotmail.com
public class ExtensionMethods
{
public static IEnumerable FilterUserControlBase GetFilterControls(this FilterRepeater filterRepeater)
{
var filters = new ListFilterUserControlBase();
foreach (RepeaterItem item in filterRepeater.Items)
{
var filter = item.Controls.OfTypeFilterUserControlBase().FirstOrDefault();
if (filter != null)
filters.Add(filter);
}
return filters.AsEnumerable();
}
public static String GetQueryStringParameters(this FilterRepeater filterRepeater)
{
var filterControls = filterRepeater.GetFilterControls();
if (filterControls.Count() > 0)
{
var queryParameters = new StringBuilder();
queryParameters.Append("?");
foreach (var filter in filterControls)
{
if (filter.SelectedValue != "")
queryParameters.Append(filter.DataField + "=" + filter.SelectedValue + "&");
}
return queryParameters.ToString().Substring(0, queryParameters.Length - 1);
}
else
return "";
}
}
Sorry for not being clear you class also need to be static:
public static class ExtensionMethods
{
Sorry again
Steve :D
Hello Steve, I appreciate all your help that you give me. The solution works well thank to you.
Hi,
I am logging all inserts and updates with user ID information. So i don't want to choose the user who created the insert or edited data. because i already who he/she is. So how can i insert user information when i insert data and user is foreign key.
i tried do it in detailsview1_iteminserting event but it's failed.
protected void DetailsView1_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
e.Values.Add("CreatedDate", DateTime.Now);
//e.Values.Add("aspnet_Users", Tools.GetCurrentUser());
}
I want your wonderful advices.
I would use the model in L2S <Table>Insert partial method on the data context or if you are useing EF look here http://msdn.microsoft.com/en-us/library/cc716714.aspx
Steve :D
Steve, I'm in a bind. I just want to simply have the foreign key selected filters auto-filled in when a user clicks 'Insert New Record' in any dynamic data instance. I need this in VB.net but can't find any instructional videos or step-by-steps. Is there a simple solution for this for a novice? It's the last part I need for my application, save for the proper ordering of the foreign key dropdownlist fields, which are not alphabetized based on the value..rather the primary key behind the scenes. Dynamic data was so close on everything else, not sure why they left out these elements. I'd appreciate anything you can offer. - Matthew Leach (matthewhleach@gmail.com)
How do you 'wire up the event handler' as you noted in Step 1? Shouldn't this be listed in the tutorial for a few of the slower folks (myself!)?
Change to Designe mode and click the dropdownlist and select the event icon (lightening bolt) not you can see the events instead of the properties. Find th ePreRender event and click the drop down list and choose the name of the method you pasted in.
Steve :D
Thanks Steve. The event handler link solved my issue. I appreciate the quick responses as I'm almost there. One last question when you are less busy: Is there a way to apply the same behavior to the 'Insert New Item' button outside of the Gridview? The querystring pass and default set on foreign key filter work fine when inserting off the link within the gridview, but I'm hoping I can link it to the general insert outside of the gridview at the bottom. I tried the code from your steps, but it doesn't seem to operate the hyperlink in the same way. -m
Sorry Matt, I don't understand your question, why don't you e-mail me direct, my e-mail is in the top right hand side of the page.
Steve :D
Hi. Sorry to bother you. I tried to add your tutorial to my dynamic data project and know I get the following compiler error and I don't know how to solve it:
CS0121: The call is ambigous between the following methods: 'ExtensionMethods.GetFilterControls(System.Web.DynamicData.FilterRepeater)' and 'ExtensionMethods.GetFilterControls(System.Web.DynamicData.FilterRepeater)'
Sorry, forget about the issue. I solved it myself. Was a project setting thing. Thanks anyway.
Hello!
Thanks for such a grand nice example. However, I was wondering whether it would be possible to insert a new item on the basis of an existing one that would work similarly to the "Edit" button. Wouldn't it be a good idea for another post?
Hello!
Thanks for such a grand nice example. However, I was wondering whether it would be possible to insert a new item on the basis of an existing one that would work similarly to the "Edit" button. Wouldn't it be a good idea for another post?
There is a project on codeplex N41 which adds clone behavoir to DD already.
Steve :D
Unfortunately, it doesn't work with QueryableFilterRepeater/QueryableFilterUserControl. QueryableFilterRepeater doesn't have an easy way to iterate over filters (but it is not fatal), and DynamicFilter/QueryableFilterUserControl don't have a way to get the selected valuem only IQueryable.
Hi wRaR, is that in DDv2 with VS2010?
No, DD Preview 4 in VS2008.
Hi wRAR they are now superceded with VS2010 and .Net 4.0, I shall look at doing a version for DDv2 and VS2010 soon.
Steve :D
Where do you put the hyperlink in List? In the PageLoad? I tried that and get...
'System.Web.DynamicData.QueryableFilterRepeater' does not contain a definition for 'GetQueryStringParameters' and the best extension method overload 'ExtensionMethods.GetQueryStringParameters(System.Web.DynamicData.FilterRepeater)' has some invalid arguments
Hi there, this is an old post for DD in .Net 3.5 not .Net 4 sorry
Thanks again for the great article. Is there any way to make this work with the 4 framework or do you have an updated article using 4? Thanks again for the article and the quick response.
Hi again, yes you can get the values using this example see http://csharpbits.notaclue.net/2010/12/filter-history-for-dynamic-data-4.html
Steve
Hi Steve, i have a list.aspx page with a gridview and dynamicfilter (dropdownlist) to filter gridview. I add a botton to export gridview to excel. When i click on this botton i need to get the selected values from dropdownlist (that user changed) to show this on the generated excel file... can you guide me how to do that...?
Thakk you very much...
Hi Christian. send me a direct e-mail, I may have some code I can send you.
My e-mail is in the top right of the page.
Steve
Sorry Christian, just looked and my e-mail is no longer there?
e-mail me on steve (AT) NotAClue.net
Steve
Post a Comment