2009-04-26 2 views
1

비슷한 구조의 FormView가 여러 개 있습니다. 중복 마크 업을 피하기 위해 FormView가 포함 된 마스터 페이지를 만들고 FormView 내에 ContentPlaceHolder를 배치했습니다. 페이지에서 페이지로 변경되는 유일한 데이터 바인딩 된 컨트롤은 해당 마스터 페이지를 사용하는 페이지에 있습니다.마스터 페이지의 FormView는 ContentPlaceHolder 경계를 통해 데이터 바인딩 된 컨트롤을 볼 수 없습니다.

<%@ master ... %> 
... 
<form runat=server> 
... 
    <asp:formview runat="server" ... > 
     <edititemtemplate> 
     ... Lots of common markup ... 
     <asp:contentplaceholder id='FormRows' runat='server' /> 
     ... Lots more common markup ... 
     </edititemtemplate> 
    </asp:formview> 
... 
</form> 

이 같은 모양으로 마스터 페이지 사용하여 페이지 : 기존 레코드의 FormView로

<%@ page masterpagefile="Form.Master" ... %> 
<asp:content contentplaceholderid="FormRows" runat="server" > 
    ... 
    <p> 
    Field One: 
    <asp:textbox runat=server text='<%#Bind("Field1")%>' id='Field1' /> 
    </p> 
    <p> 
    Field Two: 
    <asp:textbox runat=server text='<%#Bind("Field2")%>' id='Field2' /> 
    </p> 
    ... 
</asp:content> 

그래서 내가 이렇게 보이는 마스터 페이지가 데이터 바인딩 된 컨트롤 (Field1 등)을 통해보고 올바른 데이터로 채 웁니다. 그러나 삽입 또는 업데이트 할 때 삽입 또는 업데이트에 포함되지 않습니다. FormView_ItemInserting 이벤트에서 e.Values은 비어 있습니다. 마찬가지로 FormView_ItemUpdating 이벤트에서 e.NewValues은 비어 있습니다.

그래서 :

  1. 은의 ContentPlaceHolder 내부의 데이터 바인딩 된 컨트롤을 통해 볼 수있는 마스터 페이지의 FormView을 자극 할 수있는 방법이 있습니까?

  2. 데이터 봉인 <%#Bind(...)%>으로 제어되는 컨트롤을 식별 할 수 있도록 직접 값 봉지에 추가 할 수있는 방법이 있습니까?

+0

데이터 소스는 어디에 있습니까? – Jon

+0

@ 존 - 데이터 소스는 마스터 페이지의 FormView 옆에 있습니다. 실제로는 SqlDatasource에서 상속 한 사용자 지정 데이터 소스입니다. 페이지는 대화 할 테이블을 알려주고 그에 따라 자체 select, update, insert 및 delete를 빌드합니다. –

답변

0

나는 이것이 불가능하다고 판단된다고 생각합니다. 사실 데이터 바인딩이 전혀 작동하지 않는다는 것에 놀랐습니다!

FormView 컨트롤을 캡슐화하는 다른 방법을 시도 할 수 있습니다.

이제 ContentPlaceHolder가있는 PlaceHolder를 사용하여 .ascx 컨트롤에 FormView 컨트롤을 배치 할 수 있습니다.

각 ASPX 페이지에서 자리 표시 자에 필러가 포함 된 미러 ASCX 페이지를 가질 수 있습니다. 당신은 그들에게 동일한 이름 (Page1.aspx는 Page1.ascx를 사용합니다)을 주거나 Page1-Content.ascx와 같은 명명 규칙을 설정하여 FormView ascx가 필러 컨트롤의 이름을 알아 내고 Page.LoadControl()을 사용하도록 할 수 있습니다. 경로로 컨트롤을로드하고 Init 단계에서 해당 내용을 플러그 인합니다.

이제 콘텐트 컨트롤은 공용 속성을 가질 수 있다는 장점이있어서 공용 속성에 바인딩하고 필러 .ascx 파일의 적절한 서버 컨트롤간에 데이터를 왕복하게 할 수 있습니다.

은 불행하게도하지만 상당히 일 - unintensive (모든 코드를 복제) 대안 물론

, 당신은 우리에게하지 않은 비교 (때문에 ASPX 및 ASCX 각 페이지에 필요한의) 이중 파일을 무엇 모든 일반 마크 업은 있지만 공통 마크 업은 CommonMarkupHeader.ascx 및 CommonMarkupFooter.ascx로 이동하여 각 페이지의 고유 한 FormView에 포함될 수 있습니다.

+0

감사합니다. 나는 그 길로 갈 생각이 없습니다.하지만 당신은 그 문제를 이해하고 그것에 대해 생각해 봤습니다. 현재 솔루션을 별도의 응답으로 요약 해 보겠습니다. –

0

어디서 서버 양식 태그가 있습니까? 마스터 페이지의 콘텐츠 위치 홀더에있을 수 있으므로 제출 후 서버 페이지로 값을 보내지 마십시오.

+0

아니요, 양식 태그가 마스터 페이지에 있습니다. –

2

이 설정이 작동하지 않으며 마크 업보다 더 많은 코드로 이어질 수있는 몇 가지 사항이 있습니다.

쿼리를 변경하려면 마스터 페이지에 더 많은 로직을 추가하지 않고는 각 페이지에서 컨트롤을 바인딩 된 다른 데이터를 처리하지 않습니다 마스터 페이지에 정의 된 데이터 소스가있는 경우 등

모든 형태의 뷰

가 결합됩니다 함께

변경 그냥 내 두 센트에 내가 코드를 디버깅의 복잡성과 능력을 감소 각 FormView에 대한 별도의 페이지로 갈 것

도로의 아래 변화의 복잡성을 증가

+0

나는 Jon과 동의한다. –

0

그런 다음

public interface IFormViewChild { 
    IEnumerable GetFormData(); 
} 

을 가질 수 있습니다 ..

는 바인딩 데이터 소스를 반환하는 메서드 서명이 당신의 "데이터 페이지"에 대한 인터페이스를 정의 ... 이런 식으로 뭔가를 할 수있을 것 귀하의 "데이터 페이지"는 해당 인터페이스를 구현합니다 ...

public class ChildDataPage : Page, IDataPage { 
    public IEnumerable GetFormData() { 
     // code to return stuff here 
    } 
} 

마지막으로, 귀하의 마스터 페이지의 Load() 이벤트에서 ...

if (Page is IFormViewChild) { 
    myFormViewControl.DataSource = ((IFormViewChild)Page).GetFormData(); 
    myFormViewControl.DataBind(); 
} 

이것은이 웹 양식 편집기에 직접 입력 한 모든 psudo 코드입니다. 그러므로 잘못되었습니다. 하지만 그렇지 않을 수도 있습니다 :)

+0

문제는 엄밀히 말하자면 마스터 페이지 경계를 통해 FormView를 데이터 바인딩하는 것이 아닙니다. 데이터 바인딩은 적어도 한 방향으로 (데이터 표시) 작동합니다. 문제가있는 곳에서는 <% # Bind (...) %>로 묶인 데이터를 컨트롤에서 다시 가져옵니다. –

0

다음은 임시 해결책입니다. 우아하지는 않지만 작동합니다.

  • 이를

    Private Sub FormView1_ItemInserting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.FormViewInsertEventArgs) Handles FormView1.ItemInserting 
         ManuallyAddValues(e.Values) 
        End Sub 
    
        Private Sub FormView1_ItemUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.FormViewUpdateEventArgs) Handles FormView1.ItemUpdating 
         ManuallyAddValues(e.NewValues) 
        End Sub 
    
        Private Sub ManuallyAddValues(ByRef Values As IOrderedDictionary) 
         For Each Field As Core.Field In FormView1.DataSourceControl.IncludedFields 
          If Values(Field.Name) Is Nothing Then 
           Dim DataboundControl As Control = FormView1.FindControl("FormRows").FindControl(Field.Name) 
           Values.Add(Field.Name, GetValue(DataboundControl)) 
          End If 
         Next 
        End Sub 
    

    이 너무 우아하지 않다 나는 모든 데이터 바인딩의 이름을 알 필요가

    1. 때문에 제어합니다 다음에서 코드 숨김 Form.Master에 나는이 라인을 따라 뭔가를 각 컨트롤의 ID가 필드 이름과 일치한다고 가정합니다.
    2. 'GetValue'함수 (여기에 포함되지 않음)는 다양한 유형 (텍스트 상자, 드롭 다운 목록, 체크 상자 등)을 확인하고 문자열을 가져옵니다 해당 속성의 값 (textbox.te xt, dropdownlist.selectedvalue, checkbox.checked 등).

    는 아직도 적어도 '<% 번호 바인드 ("푸") %>'구문을 사용하여 바인딩 무엇을 알고 직접 정보를 얻는 방법을 가지고 싶어요.