473,404 Members | 2,114 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,404 software developers and data experts.

InsertItemTemplate and ControlParameter

I have a simple Formview like this:

<%@ Page Language="C#" EnableViewState="true" AutoEventWireup="true"
CodeFile="HelloWorld.aspx.cs" Inherits="_HelloWorld"%>

<html>
<body>
<form runat="server">
<asp:FormView DataSourceID="myODS"
ID="ItemFormView"
runat="server">
<InsertItemTemplate>
<asp:DropDownList ID="myDDL" runat="server"></
asp:DropDownList>
</InsertItemTemplate>
</asp:FormView>

<asp:ObjectDataSource ID="myODS" runat="server" >
<SelectParameters>
<asp:ControlParameter ControlID="faa" />
</SelectParameters>
</asp:ObjectDataSource>

<asp:TextBox ID="faa" runat="server" visible="false"></
asp:TextBox>
</form>

</body>
</html>

and a codebehind file

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _HelloWorld : System.Web.UI.Page
{

protected void Page_Load(object sender, EventArgs e)
{
ItemFormView.ChangeMode(FormViewMode.Insert);
if (!IsPostBack)
PopulateDDL();
}

private void PopulateDDL()
{
DropDownList ddl =
(DropDownList)ItemFormView.FindControl("myDDL");

ddl.Items.Add("aaa");
ddl.Items.Add("bbb");
ddl.Items.Add("ccc");
}

}
When I run this page, the dropdown list is expected to be populated,
but it's not. However, if I remove the line

<asp:ControlParameter ControlID="faa" />

, it then works. It also works perfectly if using other type of
parameter, like

<asp:Parameter Name="woo"/>

So, I don't understand what happen behind the scene. Any idea???

Thanks in advance!

Nate

Feb 2 '07 #1
2 5678
Hi there,

I had a look at the System.Web.UI.WebControls code, and it seems there’s a
tiny *bug* - ConvertEmptyStringToNull is not used in
ControlParameter.Evaluate() method. Let me explain the problem in details.
Every Parameter in ObjectDataSource.SelectParameters collection inherits from
System.Web.UI.WebControls.Parameter class, which defines virtual method
protected virtual object Evaluate(HttpContext context, Control control)
{
Return null;
}
As you can see default implementation returns null reference, but every
derived parameter class overrides this method with its own implementation
(this mechanism is called polymorphism). For instance, ControlParameter class
provides its own, following implementation:

protected override object Evaluate(HttpContext context, Control control)
{
if (control == null)
{
return null;
}
string text1 = this.ControlID;
string text2 = this.PropertyName;
if (text1.Length == 0)
{
throw new
ArgumentException(SR.GetString("ControlParameter_C ontrolIDNotSpecified", new
object[] { base.Name }));
}
Control control1 = DataBoundControlHelper.FindControl(control, text1);
if (control1 == null)
{
throw new
InvalidOperationException(SR.GetString("ControlPar ameter_CouldNotFindControl", new object[] { text1, base.Name }));
}
ControlValuePropertyAttribute attribute1 =
(ControlValuePropertyAttribute)
TypeDescriptor.GetAttributes(control1)[typeof(ControlValuePropertyAttribute)];
if (text2.Length == 0)
{
if ((attribute1 == null) || string.IsNullOrEmpty(attribute1.Name))
{
throw new
InvalidOperationException(SR.GetString("ControlPar ameter_PropertyNameNotSpecified", new object[] { text1, base.Name }));
}
text2 = attribute1.Name;
}
object obj1 = DataBinder.Eval(control1, text2);
if (((attribute1 != null) && string.Equals(attribute1.Name, text2,
StringComparison.OrdinalIgnoreCase)) && ((attribute1.DefaultValue != null) &&
attribute1.DefaultValue.Equals(obj1)))
{
return null;
}
return obj1;
}

A lot of code but nothing really interesting – the only thing missing is use
of ConvertEmptyStringToNull. However, the problem shows up somwehere else -
in ParameterCollection class. As you may know every BaseDataBoundControl
(including FormView) populates the data on prerender event. Before doing so,
control performs a simple check to see if the data needs to be (re)populated
(actually this task is delegated to SelectParameters member which is an
instance of ParameterCollection class, control is notified by handling
ParametersChanged event which occurrence indicates data should be retrieved
again):

public void ParameterCollection.UpdateValues(HttpContext context, Control
control)
{
foreach (Parameter parameter1 in base)
{
parameter1.UpdateValue(context, control);
}
}

And here comes the problem:

internal void Parameter.UpdateValue(HttpContext context, Control control)
{
object originalValue = this.ViewState["ParameterValue"];
object evaluatedValue = this.Evaluate(context, control);
this.ViewState["ParameterValue"] = obj2;
if (((evaluatedValue == null) && (originalValue!= null)) ||
((evaluatedValue!= null) && ! evaluatedValue.Equals(originalValue)))
{
this.OnParameterChanged();
}
}

In your case, originalValue is null, evaluatedValue is String.Empty
therefore parameter is considered as changed (TextBox.Text never returns null
reference but String.Empty, unfortunately, as I mentioned,
ControlPatameter.Eval() method does not replace empty string with null value
even if ConvertEmptyStringToNull == true. It doesn’t happen for Parameter
class because Parameter.Eval() always returns null, so the condition
if (((evaluatedValue == null) && (originalValue!= null)) ||
((evaluatedValue!= null) && ! evaluatedValue.Equals(originalValue)))
{
this.OnParameterChanged();
}
is never met.

There are two easy ways to solve the problem.
1. Do not use Page_Load event to popuate the dropdownlist, use pre_render:

protected void Page_PreRender(object sender, EventArgs e)
{
if (!IsPostBack)
PopulateDDL();
}

2. Create your own parameter class derived from ControlParameter

public class MyControlParameter : ControlParameter
{

protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
}

protected override object Evaluate(HttpContext context, Control control)
{
object value = base.Evaluate(context, control);

if (value is String)
{
if (ConvertEmptyStringToNull && ((string)value) == String.Empty)
return null;
else
return value;
}
else
return value;
}
}
<asp:FormView ID="ItemFormView" DataSourceID="myODS" runat="server"
DefaultMode="Insert">
<InsertItemTemplate>
<asp:DropDownList ID="myDDL" runat="server"/>
</InsertItemTemplate>
</asp:FormView>

<asp:ObjectDataSource ID="myODS" runat="server">
<SelectParameters>
<cc1:MyControlParameter ControlID="faa" PropertyName="Text"/>
</SelectParameters>
</asp:ObjectDataSource>

<asp:TextBox ID="faa" runat="server" visible="true"/>
--
Milosz

"np****@gmail.com" wrote:
I have a simple Formview like this:

<%@ Page Language="C#" EnableViewState="true" AutoEventWireup="true"
CodeFile="HelloWorld.aspx.cs" Inherits="_HelloWorld"%>

<html>
<body>
<form runat="server">
<asp:FormView DataSourceID="myODS"
ID="ItemFormView"
runat="server">
<InsertItemTemplate>
<asp:DropDownList ID="myDDL" runat="server"></
asp:DropDownList>
</InsertItemTemplate>
</asp:FormView>

<asp:ObjectDataSource ID="myODS" runat="server" >
<SelectParameters>
<asp:ControlParameter ControlID="faa" />
</SelectParameters>
</asp:ObjectDataSource>

<asp:TextBox ID="faa" runat="server" visible="false"></
asp:TextBox>
</form>

</body>
</html>

and a codebehind file

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _HelloWorld : System.Web.UI.Page
{

protected void Page_Load(object sender, EventArgs e)
{
ItemFormView.ChangeMode(FormViewMode.Insert);
if (!IsPostBack)
PopulateDDL();
}

private void PopulateDDL()
{
DropDownList ddl =
(DropDownList)ItemFormView.FindControl("myDDL");

ddl.Items.Add("aaa");
ddl.Items.Add("bbb");
ddl.Items.Add("ccc");
}

}
When I run this page, the dropdown list is expected to be populated,
but it's not. However, if I remove the line

<asp:ControlParameter ControlID="faa" />

, it then works. It also works perfectly if using other type of
parameter, like

<asp:Parameter Name="woo"/>

So, I don't understand what happen behind the scene. Any idea???

Thanks in advance!

Nate

Feb 2 '07 #2
On Feb 2, 11:25 am, Milosz Skalecki [MCAD] <mily...@DONTLIKESPAMwp.pl>
wrote:
Hi there,

I had a look at the System.Web.UI.WebControls code, and it seems there's a
tiny *bug* - ConvertEmptyStringToNull is not used in
ControlParameter.Evaluate() method. Let me explain the problem in details.
Every Parameter in ObjectDataSource.SelectParameters collection inherits from
System.Web.UI.WebControls.Parameter class, which defines virtual method
protected virtual object Evaluate(HttpContext context, Control control)
{
Return null;}

As you can see default implementation returns null reference, but every
derived parameter class overrides this method with its own implementation
(this mechanism is called polymorphism). For instance, ControlParameter class
provides its own, following implementation:

protected override object Evaluate(HttpContext context, Control control)
{
if (control == null)
{
return null;
}
string text1 = this.ControlID;
string text2 = this.PropertyName;
if (text1.Length == 0)
{
throw new
ArgumentException(SR.GetString("ControlParameter_C ontrolIDNotSpecified", new
object[] { base.Name }));
}
Control control1 = DataBoundControlHelper.FindControl(control, text1);
if (control1 == null)
{
throw new
InvalidOperationException(SR.GetString("ControlPar ameter_CouldNotFindContro*l", new object[] { text1, base.Name }));
}
ControlValuePropertyAttribute attribute1 =
(ControlValuePropertyAttribute)
TypeDescriptor.GetAttributes(control1)[typeof(ControlValuePropertyAttribute*)];
if (text2.Length == 0)
{
if ((attribute1 == null) || string.IsNullOrEmpty(attribute1.Name))
{
throw new
InvalidOperationException(SR.GetString("ControlPar ameter_PropertyNameNotSpe*cified", new object[] { text1, base.Name }));
}
text2 = attribute1.Name;
}
object obj1 = DataBinder.Eval(control1, text2);
if (((attribute1 != null) && string.Equals(attribute1.Name, text2,
StringComparison.OrdinalIgnoreCase)) && ((attribute1.DefaultValue != null) &&
attribute1.DefaultValue.Equals(obj1)))
{
return null;
}
return obj1;

}

A lot of code but nothing really interesting - the only thing missing is use
of ConvertEmptyStringToNull. However, the problem shows up somwehere else-
in ParameterCollection class. As you may know every BaseDataBoundControl
(including FormView) populates the data on prerender event. Before doing so,
control performs a simple check to see if the data needs to be (re)populated
(actually this task is delegated to SelectParameters member which is an
instance of ParameterCollection class, control is notified by handling
ParametersChanged event which occurrence indicates data should be retrieved
again):

public void ParameterCollection.UpdateValues(HttpContext context, Control
control)
{
foreach (Parameter parameter1 in base)
{
parameter1.UpdateValue(context, control);
}

}

And here comes the problem:

internal void Parameter.UpdateValue(HttpContext context, Control control)
{
object originalValue = this.ViewState["ParameterValue"];
object evaluatedValue = this.Evaluate(context, control);
this.ViewState["ParameterValue"] = obj2;
if (((evaluatedValue == null) && (originalValue!= null)) ||
((evaluatedValue!= null) && ! evaluatedValue.Equals(originalValue)))
{
this.OnParameterChanged();
}

}

In your case, originalValue is null, evaluatedValue is String.Empty
therefore parameter is considered as changed (TextBox.Text never returns null
reference but String.Empty, unfortunately, as I mentioned,
ControlPatameter.Eval() method does not replace empty string with null value
even if ConvertEmptyStringToNull == true. It doesn't happen for Parameter
class because Parameter.Eval() always returns null, so the condition
if (((evaluatedValue == null) && (originalValue!= null)) ||
((evaluatedValue!= null) && ! evaluatedValue.Equals(originalValue)))
{
this.OnParameterChanged();
}
is never met.

There are two easy ways to solve the problem.
1. Do not use Page_Load event to popuate the dropdownlist, use pre_render:

protected void Page_PreRender(object sender, EventArgs e)
{
if (!IsPostBack)
PopulateDDL();

}

2. Create your own parameter class derived from ControlParameter

public class MyControlParameter : ControlParameter
{

protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
}

protected override object Evaluate(HttpContext context, Control control)
{
object value = base.Evaluate(context, control);

if (value is String)
{
if (ConvertEmptyStringToNull && ((string)value) == String.Empty)
return null;
else
return value;
}
else
return value;
}

}

<asp:FormView ID="ItemFormView" DataSourceID="myODS" runat="server"
DefaultMode="Insert">
<InsertItemTemplate>
<asp:DropDownList ID="myDDL" runat="server"/>
</InsertItemTemplate>
</asp:FormView>

<asp:ObjectDataSource ID="myODS" runat="server">
<SelectParameters>
<cc1:MyControlParameter ControlID="faa" PropertyName="Text"/>
</SelectParameters>
</asp:ObjectDataSource>

<asp:TextBox ID="faa" runat="server" visible="true"/>
--
Milosz

"npe...@gmail.com" wrote:
I have a simple Formview like this:
<%@ Page Language="C#" EnableViewState="true" AutoEventWireup="true"
CodeFile="HelloWorld.aspx.cs" Inherits="_HelloWorld"%>
<html>
<body>
<form runat="server">
<asp:FormView DataSourceID="myODS"
ID="ItemFormView"
runat="server">
<InsertItemTemplate>
<asp:DropDownList ID="myDDL" runat="server"></
asp:DropDownList>
</InsertItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="myODS" runat="server" >
<SelectParameters>
<asp:ControlParameter ControlID="faa" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:TextBox ID="faa" runat="server" visible="false"></
asp:TextBox>
</form>
</body>
</html>
and a codebehind file
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class _HelloWorld : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ItemFormView.ChangeMode(FormViewMode.Insert);
if (!IsPostBack)
PopulateDDL();
}
private void PopulateDDL()
{
DropDownList ddl =
(DropDownList)ItemFormView.FindControl("myDDL");
ddl.Items.Add("aaa");
ddl.Items.Add("bbb");
ddl.Items.Add("ccc");
}
}
When I run this page, the dropdown list is expected to be populated,
but it's not. However, if I remove the line
<asp:ControlParameter ControlID="faa" />
, it then works. It also works perfectly if using other type of
parameter, like
<asp:Parameter Name="woo"/>
So, I don't understand what happen behind the scene. Any idea???
Thanks in advance!
Nate- Hide quoted text -

- Show quoted text -
That explains!

Thanks Milosz.

Feb 6 '07 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: pjbates | last post by:
Hi, I've been using the GridView and DetailsView controls for a while, and I'm beginning to get annoyed by the redundancy of EditItemTemplate and InsertItemTemplate in many cases. In the...
0
by: Lee Moore | last post by:
I have the following code, which I thought should work. I get an error stating ... Could not find control 'GOAL_TEXT_CONTROL' in ControlParameter 'GOAL_TEXT'. Any help would be great. ...
0
by: Swetha | last post by:
Hello I have a FormView with InsertItem, EditItem and ItemTemplates. Depending on from where the page is accessed, the page opens up in either Insert, Edit or ReadOnly mode. The FormView is...
3
by: K B | last post by:
Hi, I've tried this several ways but get the error that the control can't be found. I have a details view with a dropdownlist in the EditItemTemplate populated and assigned the selected value...
1
by: Cas | last post by:
Hi, How to add a controlparameter in the code-behind that is the equivalent in the aspx file of: <UpdateParameters> <asp:ControlParameter ControlID="myID" Name="myname"...
0
by: Cas | last post by:
Hi, I want to create a InsertItemTemplate in a detailsview (only insertmode)programmatically. I first defined a Template, then i tried to create within that templatefield a InsertItemTemplate...
0
by: Bart | last post by:
Hi, i want to programmatically manipulate the property 'Name' of a ControlParameter inside a InsertParameters tag. This the aspx code: ------------------ <asp:SqlDataSource...
2
by: David C | last post by:
Is it possible to refer to a ControlID that is inside a FormView? If so, what is syntax? I tried to reference it just by the controlid and it created an exception with the message Could not find...
0
by: =?Utf-8?B?U2F0aGVlc2g=?= | last post by:
Hi all, When the below code executed it is not binding the Dropdownlist in insertitemtemplate. But the same is binding the Dropdownlist in EditItemTemplate. Also, when i use LINQDataSource in...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.