2010-03-25 2 views
3

FormView 내에 ascx 컨트롤이 있습니다. 내가 원하는 것은 ascx 내부에 Bind 구문을 사용하는 것입니다. 여기 내부 .ascx 컨트롤 및 FormView의 데이터 바인딩

<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") %>' /> 

잘 작동 여기 내 페이지입니다. 바인딩은 텍스트 상자에 예상 값을 채 웁니다. 그러나 "Update"버튼을 눌렀을 때 ObjectDataSource의 메소드 Update는 입력 된 텍스트가 예상되는 동안 이름 대신 null이있는 Ent 인스턴스를 가져옵니다. 테스트 용으로 .aspx에 텍스트 상자를 넣었으며 모든 것이 잘 작동합니다.

필자는 반사체 FormView에 의해 역 컴파일을 마쳤습니다. 여기서 ExtractRowValues는 직접 자식을 통해 반복 된 이후에 실패했습니다. 누구든지 어린이 구속력을 해결하는 방법을 알고 있습니까?

+0

같은 질문을 입력하는 중이었습니다. 당신의 생각이 잘 드러났습니다. 또한 폼뷰 내에서 ascx 컨트롤의 속성을 데이터 바인딩하고 같은 문제에 직면하려고합니다. 너가 그것을 이해하면 공유 하십시요. –

+0

@The_AlienCoder Reflector로 분해했습니다. 중첩 컨트롤의 경우 updateTemplate에 대한 구문 분석 구문 구문이 없습니다. 그러나 같은 구문이 itemTemplate에서 제공되므로 aspx의 구문 분석을 재정의하는 것이 유일한 방법입니다. – Dewfy

답변

2

죄송합니다. 아무데도 Bind 메서드가 없습니다. ASP.NET 컴파일러에게 데이터 바인딩에 'Eval'호출 (실제로는 Eval 메서드가 있음)을 추가하고 양방향 바인딩을위한 특정 추출 코드 숨김 메서드를 생성하는 ASP.NET 토큰입니다.

그러나이 메서드는 ITemplate 속성 (예 : FormView의 ItemTemplate, EditItemTemplate 등)이 장착되어 있고 양방향으로 바인딩 할 수 있다고 선언 된 컨트롤에 대해서만 추가되고 추출시 호출됩니다.

사용자 컨트롤 (ascx)의 경우, 그런 종류의 메소드를 생성하는 쉬운 방법이 없습니다.

WebUserControl.ascx :

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

(주

그러나 덜 선언, 덜 자동 비록 같은 일부 통합 할 수 있습니다 사용자 정의 컨트롤에서 구현할 수있는 IBindableControl Interface있다 Bind는 쓸모가 없으므로 Eval을 고수 할 수 있습니다.)

WebUserControl.ascx.cs :

public partial class WebUserControl : UserControl, IBindableControl 
{ 
    public void ExtractValues(IOrderedDictionary dictionary) 
    { 
     dictionary["Name"] = txt1.Text; 
    } 
} 
+0

나는 당신의 생각을 즉각적으로 시도 할 수는 없으므로 당신의 말을 받아 들일 것입니다. 한 가지만 대답하십시오 : * "TextBox에 값을 선택하면 모든 것이 잘 작동합니다. 그러나 "Update"버튼을 누르면 ObjectDataSource의 메서드 Update가 null로 Ent의 인스턴스를 가져옵니다 "* - 업데이트 중에 IBindableControl 메서드가 호출됩니까? – Dewfy

+0

@Dewfy - 예, IBindableControl.ExtractValues는 FormView 명령 핸들러에 의해 호출됩니다 (이는 아이디어가 아닙니다. 실제로 작동해야합니다 :-) –

2

당신은 포함하는 페이지 (ASPX)에 대한 사용자 제어 (ASCX)에서 <% 번호 바인드 ("") %> 구문을 이동 얻기 위해 사용자 정의 컨트롤에 속성을를 사용하여 설정해야 양식 값. 그것이 현실 만들려고 노력하는 내 예를 아래에 몇 가지 더 세부 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 
     ... 
    } 
} 
+0

내가 쓴 것을주의 깊게 읽으십시오 : "테스트를 위해서 .aspx에 텍스트 상자를 놓았습니다. 모든 것이 잘 작동합니다"그래서 분명합니다. bind 내부에서 .ascx를 사용하는 방법에 대한 질문에 대답하지 않았습니다. 범위를 벗어났습니다 - 일부 솔루션을 게시하면 샘플을 최소화하려고합니다. 위의 4 대 목록에서 그 내용을 분명히 알 수 없습니다. – Dewfy

+0

처음으로 정확하게 이해했습니다. 내 대답은 아직도있다. Bind() 구문을 데이터 바인딩 된 사용자 정의 컨트롤과 함께 사용하는 방법을 알고 싶습니까? 내 대답은 * 사용자 정의 컨트롤에 Bind() 구문을 사용할 수 없다는 것입니다. 포함 된 ASPX 페이지에 있어야하며 사용자 정의 컨트롤의 속성을 사용해야합니다. ASCX와 ASPX 파일의 예제를 함께 제공하여 함께 짜여진 모습을 보여줍니다. 미안해. 내 대답이 마음에 들지 않는다면 미안해. 네가 질문을 한 지 2 년 만에받은 유일한 질문인데, 네 기대가 좀 높을 거 같아. –

+0

당신은 답장을하지 않습니다. 답변 정보 - 이미이 문제를 해결했으며 내 질문에서이를 볼 수 있습니다. 따라서이 기간에는 기대가 없었습니다. 나는 이것이 더 우아한 해결책으로 존재하는지 궁금해했다. 또한 일부 초보자가이 페이지로 이동한다고 가정 해 봅시다 - 귀하의 목록이 너무 많아서 답변에서 아무 도움도 얻을 수 없습니다. 이 관점에서 나는 정확하고 도움이되는 답을 받아 들일 수 없습니다. 관심을 가져 주셔서 감사 드리며 불쾌하지 않으시 고 더 많이 시도해 보시면 곧 전문가 수준에 도달하게 될 것입니다. – Dewfy

관련 문제