Asp.net 在内部.ascx控件和FormView中进行数据绑定

Asp.net 在内部.ascx控件和FormView中进行数据绑定,asp.net,formview,data-binding,Asp.net,Formview,Data Binding,我在FormView中有ascx控件。我想在ascx中使用语法绑定。 这是我的页面: <asp:ObjectDataSource runat="server" ID="ods" TypeName="MyDS" SelectMethod="Get" UpdateMethod="Update" DataObjectTypeName="Ent"> </asp:ObjectDataSource> <asp:FormView runat="server

我在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") %>' />
<asp:TextBox ID="txt1" runat="server" Text='<%# Eval("Name") %>' />

在文本框中选择值时,一切正常。Bind使用预期值填充文本框。但当按下按钮“Update”时,ObjectDataSource的方法Update会以null代替名称获取Ent实例,而输入的文本是预期的。 为了测试,我将文本框放入.aspx中,一切正常


最后,我使用reflector FormView进行了反编译,其中ExtractRowValues看起来失败了,因为它只对直接子级进行迭代。有人知道如何处理子绑定吗?

您必须将语法从用户控件(ASCX)移动到包含页面(ASPX),并使用用户控件中的属性来获取和设置表单值。我下面的示例是根据在中给出的解决方案改编的,并提供了一些更详细的细节,以使其变得现实:

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>
<%--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加价:

<%@ 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>
<%--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>

抱歉,如果有点晚了:-)

“Bind”是一种奇怪的野兽。在任何地方都没有绑定方法。它只是一个特定的ASP.NET令牌,指示ASP.NET编译器在数据绑定上添加“Eval”调用(确实有一个方法),并为双向绑定生成一个特定的提取代码隐藏方法

但此方法仅针对具有属性(如FormView的ItemTemplate、EditItemTemplate等)且声明为两种可绑定方式的控件添加(并在提取时调用)

不幸的是,对于用户控件(ascx),没有简单的方法生成这种方法

但是,您可以在用户控件中实现一些集成,尽管它的自动化程度较低,声明性较低,如下所示:

WebUserControl.ascx:

<asp:TextBox ID="txt1" runat="server" Text='<%# Bind("Name") %>' />
<asp:TextBox ID="txt1" runat="server" Text='<%# Eval("Name") %>' />

我刚打了同一个问题,你的问题来了,我来了。我还试图在formview中对ascx控件的属性进行数据绑定,但遇到了同样的问题。如果你找到了,请分享。@Reflector反汇编的\u AlienCoder-对于嵌套控件,updateTemplate根本没有解析绑定语法。但itemTemplate中也有相同的语法,所以唯一的方法是重写对aspx的解析。请仔细阅读我写的内容:“为了测试,我将文本框放在了.aspx中,一切正常”,这是显而易见的。对于如何使用bind inside.ascx这个问题,您并没有提供答案。超出范围-如果您发布了一些解决方案,尝试最小化样本,从上面的4个巨大列表中,不清楚您在说什么;我的答案仍然有效。您想知道如何对数据绑定用户控件使用Bind()语法,是吗?我的答案是,用户控件中不能有Bind()语法:必须在包含ASPX的页面中有它,并在用户控件中使用属性。我已经给出了ASCX和ASPX文件的示例,以展示它们是如何结合在一起的。如果你不喜欢我的答案,我很抱歉——因为这是你两年来唯一收到的答案,我想你的期望可能有点高。你的答案站不住脚——因为它是从以前说过的答案复制过来的。关于答案-我已经解决了这个问题,你可以在我的问题中看到-所以在这段时间里没有任何期望。我想知道是否有更优雅的解决方案。另外,让我们假设一些新手会转到这个页面-他/她无法从你的答案中得到任何有用的信息,因为你的列表太大了。即使从这个角度来看,我也不能接受你的回答是正确的和有帮助的。谢谢你的关注,希望它不会冒犯你,尝试更多,你很快就会达到专家水平。我无法立即尝试/检查你的想法,所以我要相信你的话,只回答一件事:“在文本框中选择值时,一切都很好。Bind使用预期值填充文本框。但是当按钮”更新“按下ObjectDataSource的方法Update获取Ent实例为null”-那么在更新过程中会调用IBindableControl方法吗?@Dewfy-是的,IBindableControl.ExtractValues将由FormView命令处理程序调用(这不是一个想法,它实际上应该可以工作:-)