我在FormView中有ascx控件。我想要的是在ascx中使用语法绑定。 这是我的页面:
<asp:ObjectDataSource runat="server" ID="ods" TypeName="MyDS" SelectMethod="Get" UpdateMethod="Update" DataObjectTypeName="Ent">
</asp:ObjectDataSource>
<asp:FormView runat="server" DefaultMode="Edit" ID="fv1" DataSourceID="ods">
<EditItemTemplate>
<uc1:WebUserControl ID="WebUserControl1" runat="server" />
<asp:Button runat="server" CommandName="Update" Text="Update"/>
</EditItemTemplate>
</asp:FormView>
这是WebUserControl.ascx:
<asp:TextBox ID="txt1" runat="server" Text='<%# Bind("Name") %>' />
在TextBox中选择值时,一切正常。绑定使用期望值填充文本框。但是当按钮“更新”按下ObjectDataSource的方法Update时,获取Ent的实例,而不是Name,而是输入文本。 只是为了测试我已经将文本框放入.aspx中,一切正常。
最后我通过反射器FormView反编译,其中ExtractRowValues看起来失败,因为只迭代直接子节点。有人知道如何处理子绑定吗?
答案 0 :(得分:2)
您必须将&lt;%#Bind(“”)%&gt; 语法从用户控件(ASCX)移动到包含页面(ASPX)并使用属性在您的用户控件中获取和设置表单值。我在下面的示例改编自http://oudinia.blogspot.co.uk/2007/12/aspnet-20-and-up-c-user-control-within.html给出的解决方案,其中包含一些细节以尝试使其变为现实:
ASCX加价:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="PaperForm.ascx.cs" Inherits="PaperForm" %>
<asp:ValidationSummary runat="server" HeaderText="<b>Please supply the missing information below.</b>" />
<p class="SectionHeading">Section A: Your Details</p>
<table border="1" width="100%">
<tr>
<td width="220px">Membership number</td>
<td colspan="3"><asp:TextBox ID="txtMemNo" runat="server" MaxLength="9"></asp:TextBox>
<asp:RegularExpressionValidator runat="server" ControlToValidate="txtMemNo" Display="Dynamic" Text="Please check your membership number" ValidationExpression="\d{9}"></asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td><asp:Label ID="lblFirstName" runat="server">First name</asp:Label></td>
<td><asp:TextBox ID="txtForename" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator runat="server" ControlToValidate="txtForename" Text="Required"></asp:RequiredFieldValidator>
</td>
<td width="110px"><asp:Label ID="lblLastName" runat="server">Last name</asp:Label></td>
<td><asp:TextBox ID="txtSurname" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator runat="server" ControlToValidate="txtSurname" Text="Required"></asp:RequiredFieldValidator>
</td>
</tr>
...
</table>
<script type="text/javascript" language="javascript">
// perform additional client-side validation in JavaScript
function ValidateForm()
{
// check membership number (via web-service)
...
}
</script>
ASCX代码隐藏:
public partial class PaperForm : UserControl
{
// **public properties representing form data**
public string MemNo { get { return txtMemNo.Text; } set { txtMemNo.Text = value; } }
public string Forename { get { return txtForename.Text; } set { txtForename.Text = value; } }
public string Surname { get { return txtSurname.Text; } set { txtSurname.Text = value; } }
...
protected void Page_Load(object sender, EventArgs e)
{
// prevent browser caching
...
}
}
ASPX加价:
<%--register the user control here--%>
<%@ Register TagPrefix="UC" TagName="PaperForm" Src="~/Proposals/PaperForm.ascx" %>
<asp:FormView ID="fvPaper" runat="server" DataKeyNames="PprPropID" DataSourceID="tblPprProp" DefaultMode="Insert" Width="780px">
<InsertItemTemplate>
<%--insert the user control here, **and bind the database fields to its properties**--%>
<UC:PaperForm ID="pf" runat="server" MemNo='<%# Bind("MemNo") %>' Forename='<%# Bind("Forename") %>' Surname='<%# Bind("Surname") %>' ... />
...
<%--can use the JavaScript ValidateForm() function defined in the ASCX file--%>
<asp:Button ID="InsertButton" runat="server" CausesValidation="True" CommandName="Insert" Text="Submit" BackColor="#C2D9EC" OnClientClick="return ValidateForm();" />
</InsertItemTemplate>
</asp:FormView>
<%--define the data-source here rather than in the ASCX file--%>
<asp:SqlDataSource ID="tblPprProp" runat="server" ConflictDetection="CompareAllValues" ConnectionString="<%$ ConnectionStrings:confConnectionString %>" OnInserted="AfterInsertion"
InsertCommand="INSERT INTO [tblPprProp] ([MemNo], [Surname], [Forename], ...) VALUES (@MemNo, @Surname, @Forename, ...); SELECT @RowID = SCOPE_IDENTITY()"
OldValuesParameterFormatString="original_{0}">
<InsertParameters>
<asp:Parameter Name="MemNo" Type="String" />
<asp:Parameter Name="Surname" Type="String" />
<asp:Parameter Name="Forename" Type="String" />
...
</InsertParameters>
</asp:SqlDataSource>
ASPX代码隐藏:
public partial class PaperProposal : Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void AfterInsertion(object sender, SqlDataSourceStatusEventArgs e)
{
// get Proposal ID
string rowId = e.Command.Parameters["@RowID"].Value.ToString();
// get e-mail address from ASCX property
string address = ((PaperForm)this.fvPaper.FindControl("pf")).Email;
// send acknowledgement e-mail
...
}
}
答案 1 :(得分:2)
对不起,如果这有点晚了: - )
“绑定”是一个奇怪的野兽。没有Bind方法无处可去。它只是一个特定的ASP.NET标记,它指示ASP.NET编译器在数据绑定时添加“Eval”调用(确实有一个Eval方法),并为双向绑定生成特定的提取代码隐藏方法。但是这个方法只为配备了ITemplate属性的控件(例如FormView的ItemTemplate,EditItemTemplate等等)添加(并在提取时调用),并且声明为双向绑定。
不幸的是,对于用户控件(ascx),没有简单的方法可以生成这种方法。
但是,您可以在用户控件中实现IBindableControl Interface,允许进行一些集成,尽管它不那么自动,声明性较小,如下所示:
WebUserControl.ascx:
<asp:TextBox ID="txt1" runat="server" Text='<%# Eval("Name") %>' />
(注意Bind没用,所以你可以坚持Eval)。
WebUserControl.ascx.cs:
public partial class WebUserControl : UserControl, IBindableControl
{
public void ExtractValues(IOrderedDictionary dictionary)
{
dictionary["Name"] = txt1.Text;
}
}