|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Using Custom Control in a FormViewI have a rather odd problem when using my custom control in a FormView control. The custom control inherits the CompositeControl. It is two DropDownLists. The first DDL binds to a DataSource internally. When a user selects a value in the first DDL a second DDL is bound to another DataSource, again internally, based on the selected value of the first DDL. This all works well until I place the control in a FormView control. On first page request the custom control is loaded with the first DDL populated with data but the list contains the values twice, i.e. Value1 Value2 Value3 Value1 Value2 Value3 This does not happen when the control is used without the FormView. I have tried debugging by adding a break point to where the first DDL is data bound and the method only appears to be called once and contains the correct values. Can someone suggest what might be happening and how I can fix it? It would be a real pain if I couldn't use the FormView. Many thanks Andrew Hello Andrew,
From your description, you have developed a custom webserver control which contains two dropdownlists (with cascaded data items). This dropdownlist works well when it be put on page individually, however, you found the dropdownlist contains duplidated items if it is put in a FormView control, correct? Based on my experience, such problem generally related to the custom control's sub control population logic. Your own custom control will do the control creation and data population such as databinding. And when you add it into FormView, the creation and databinding will also related to the FormView container. If convenient, would you provide the code logic of your custom control or if possible you can try creating a simplified one (or use a ascx usercontrol to simulate it) whic can repro the same behavior. Thus, I can help you perform some local tests. Please feel free to let me know if there is anything I missed. Sincerely, Steven Cheng Microsoft MSDN Online Support Lead ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hi Steven
Here's some cut down code for my control. I think I need to know what logic to add so that the control can be used both within a FormView or other DataBound parent control and on it's own. Are there any 'best practices' I should be aware of? Thanks Andrew public class GroupsSetsDropDown : CompositeControl { private DropDownList ddlGroups = new DropDownList(); private DropDownList ddlSets = new DropDownList(); protected override void CreateChildControls() { Controls.Clear(); // only get data if visible is true if (this.Visible == true) CreateControlHierarchy(); ClearChildViewState(); } protected virtual void CreateControlHierarchy() { CreateGroupsSetsDdl(); this.Controls.Add(ddlGroups); this.Controls.Add(ddlSets); } private void CreateGroupsSetsDdl() { ddlGroups.Items.Add(new ListItem("Select...", "-1", true)); ddlGroups.AutoPostBack = true; if (this.DesignMode == false) { Dictionary<int, string> groups = new GroupsBLL().GetLookup(); if (groups != null) { ddlGroups.AppendDataBoundItems = true; ddlGroups.DataSource = groups; ddlGroups.DataValueField = "key"; ddlGroups.DataTextField = "value"; //ddlGroups.SelectedIndexChanged += new EventHandler(this.ddlGroupSets_SelectedIndexChanged); // what conditions should be considered before adding this line?, i.e. if the control is placed inside a FormView then the will do the binding. ddlGroups.DataBind(); } } ddlSets.Enabled = false; ddlSets.Items.Add(new ListItem("Any", "-1", true)); } } } Hi
Another thing I notice is that I get quite strange results when EnableViewState = true. I guess I need to allow for this somehow in the custom control? Thanks again Andrew Thanks for your reply Andrew,
After some further troubleshooting on the code you provided, I found the root cause of this issue. The double-data-population is caused by the dropdownlist in your custom webcontrol have been called twice. Here is how the ASP.NET page call the databind twice on them: 1. First time, it is in your custom webcontrol's control creation time, the "CreateChildControls" method will perform databinding to populate the main dropdownlist. 2. When you put the custom webcontrol in a template databound control(such as FormView, repeater, datalist, gridView....), since the template databound container will call DataBind(), this Databind method will recursively call DataBind() method on all the child controls. And for your scenario, the two DropDownLists in your custom webcontrols' Databind will be called. Currently, I've considerred the following two means to resolve the issue: 1) In the custom control's CreateChildControls code logic, instead of databind, we manually copy each items from the Datasource into the dropdownlist. e.g. foreach(item in Dictionary) { ddl.items.Add(item.key, item.value) } 2) Override your custom webcontrol's DataBind method and do not recursively call sub control's databind method(remove base.DataBind). e.g. public override void DataBind() { //remove the base.DataBind(); call //base.DataBind(); } Here is a complete code fragment of the modified control ================ [ToolboxData("<{0}:GroupsSetsDropDown runat=server></{0}:GroupsSetsDropDown>")] public class GroupsSetsDropDown : CompositeControl { private DropDownList ddlGroups; private DropDownList ddlSets; protected override void CreateChildControls() { Page.Response.Write("<br/>CreateChildControls+" + this.ID); Controls.Clear(); // only get data if visible is true //if (this.Visible == true) CreateControlHierarchy(); //ClearChildViewState(); } protected virtual void CreateControlHierarchy() { CreateGroupsSetsDdl(); } private void CreateGroupsSetsDdl() { ddlGroups = new DropDownList(); ddlSets = new DropDownList(); ddlGroups.ID = "ddlGroups"; ddlSets.ID = "ddlSets"; this.Controls.Add(ddlGroups); this.Controls.Add(ddlSets); ddlGroups.Items.Add(new ListItem("Select...", "-1", true)); ddlGroups.AutoPostBack = true; if (this.DesignMode == false) { Dictionary<int, string> groups = new GroupsBLL().GetLookup(); if (groups != null) { ddlGroups.AppendDataBoundItems = true; ddlGroups.DataSource = groups; ddlGroups.DataValueField = "key"; ddlGroups.DataTextField = "value"; //ddlGroups.SelectedIndexChanged += new EventHandler(this.ddlGroupSets_SelectedIndexChanged); // what conditions should be considered before adding this line?, i.e. if //the control is placed inside a FormView then the will do the binding. ddlGroups.DataBind(); } } ddlSets.Enabled = false; ddlSets.Items.Add(new ListItem("Any", "-1", true)); } public override void DataBind() { //base.DataBind(); } } ================================= for custom webserver control development, you can refer to those reference in MSDN: #Developing Custom ASP.NET Server Controls http://msdn2.microsoft.com/ru-ru/library/zt27tfhy.aspx Also, I would like to lookup the ASP.NET built-in control code(through reflector) to get some ideas when developing a custom webcontrol. Hope this helps you. Sincerely, Steven Cheng Microsoft MSDN Online Support Lead This posting is provided "AS IS" with no warranties, and confers no rights. Hi Steven
This is very useful stuff. I've used the first option of manually adding the dictionary to the Dropdown and this works fine. I have a another issue to do with the control which I would appreciate some advice on. I want to make sure that the control doesn't call the database (to populate the list) if the control is visible = false. I think the last value is being called from viewstate so I may be calling the database in the wrong part of the page life cycle? if (this.Visible == true) { //code to call db and add dictionary to DDL } I'd also like to use viewstate to store the ddl values from the database. I know that the normal way to build databound controls is to have a separate data source but it makes sense for me to do everything in the control as the datasource is a permanent feature of this control. Can you give me your thoughts on this? Thanks again Andrew Hi Andrew,
It's my understanding that the CreateChildControls() will not get called if the control is not visible. Therefore I don't think you need to check for visibility before binding data. If you've bound the data to the DDL from database and the DDL has viewstate enabled, I think you don't have to persistent the data yourself. I hope I didn't misunderstand your question. Regards, Walter Wang (waw***@online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights.
#include for a DropDownList?
Collection Property in web custom control Using Ajax control in custom server control How to show initial default values in a detailsview form Can I Use RequiredFieldValidator inside a repeater ? open explorer from asp.net? Setting name=, ID= for TextBox AutoComplete in ASP:TextBox control in ASP.NET 1.1 User Control access fails in debug mode, works in release mode Solution for GridView Pager Style Problem |
|||||||||||||||||||||||