마스터 페이지의 FormView는 ContentPlaceHolder 경계를 통해 데이터 바인딩된 컨트롤을 볼 수 없습니다.

StackOverflow https://stackoverflow.com/questions/791572

  •  16-09-2019
  •  | 
  •  

문제

비슷한 구조의 FormView가 여러 개 있습니다.중복된 태그를 피하기 위해 FormView가 포함된 마스터 페이지를 만들고 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>

해당 마스터 페이지를 사용하는 페이지는 다음과 같습니다.

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

기존 레코드를 사용하여 FormView는 데이터 바인딩된 컨트롤(Field1 등)을 확인하고 올바른 데이터로 채웁니다.그러나 삽입 또는 업데이트할 때는 해당 항목이 표시되지 않으며 삽입 또는 업데이트에 포함되지 않습니다.에서 FormView_ItemInserting 이벤트, e.Values 비었다;에서도 마찬가지로 FormView_ItemUpdating 이벤트, e.NewValues 비었다.

그래서:

  1. ContentPlaceholder 내부의 데이터 바인딩된 컨트롤을 확인하기 위해 마스터 페이지에서 FormView를 호출하는 방법이 있습니까?

  2. 이것이 실패하면 데이터 바인딩된 컨트롤을 식별하는 간단한 방법이 있습니까? <%#Bind(...)%> 값 가방에 수동으로 추가할 수 있도록 하시겠습니까?

도움이 되었습니까?

해결책

나는 이것이 불가능하다면 어려울 것이라고 생각한다. 사실 나는 데이터베인딩이 전혀 작동한다는 것에 놀랐습니다!

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

Contentploseholder가있는 자리 표시 자와 함께 Formview 컨트롤을 .ASCX 컨트롤에 배치 할 수 있습니다.

그런 다음 각 ASPX 페이지에는 자리 표시자를위한 필러가 포함 된 미러 ASCX 페이지가있을 수 있습니다. 동일한 이름을 제공 할 수 있습니다 (Page1.aspx는 Page1.ascx를 사용) 또는 Page1-Content.ascx와 같은 이름 지정 규칙을 설정하여 FormView ASCX가 필러 제어의 이름을 파악할 수 있도록 Page.LoadControl () 경로별로 제어를로드하고 초기 단계에서 해당 컨텐츠를 연결하십시오.

이제 컨텐츠 컨트롤은 공개 속성을 가질 수 있다는 이점이 있으므로 해당 공개 속성에 바인딩 할 수 있으며 속성이 필러 .ASCX 파일의 적절한 서버 컨트롤과의 데이터를 셔틀하게 할 수 있습니다.

불행히도 파일의 두 배입니다 (각 페이지에 필요한 ASPX 및 ASCX로 인해) 대안 (모든 코드를 복제)에 비해 상당히 작동하지 않습니다.

물론, 당신은 당신의 모든 일반적인 마크 업이 무엇인지 말하지 않았지만, 당신의 공통 마크 업은 CommonMarkupHeader.ascx와 CommonMarkupfooter.ASCX로 들어갈 수 있으며 각 페이지의 고유 한 Formview에 포함될 수 있습니다.

다른 팁

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

마스터 페이지에 DataSource가 정의 된 경우 쿼리 등을 변경하기 위해 마스터 페이지에 더 많은 로직을 추가하지 않고 각 페이지의 다른 데이터 바운드 컨트롤을 처리하지 않습니다.

모든 형태의 견해는 함께 결합되어 도로 아래의 변화의 복잡성을 증가시킵니다.

코드의 복잡성, 디버깅 및 변경 기능을 줄이는 각 Formview에 대해 별도의 페이지를 사용합니다.

내 두 센트

서버 양식 태그는 어디에 있습니까? 마스터 페이지에 컨텐츠 장소 홀더에있을 수 있으므로 제출 후 값이 서버 페이지로 보내지 않습니다.

이런 짓을 할 수도 있겠네요...

바인딩 가능한 데이터 소스를 반환하는 메서드 서명이 있는 "데이터 페이지"에 대한 인터페이스를 정의합니다.

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();
}

이는 모두 이 웹 양식 편집기에 직접 입력한 유사 코드라는 점을 명심하세요.그래서 아마 틀렸을 겁니다.하지만 그렇지 않을 수도 있습니다 :)

잠정 솔루션은 다음과 같습니다. 우아하지는 않지만 작동합니다. Form.master의 Code-Behind에서 나는이 라인을 따라 무언가를 가지고 있습니다.

    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. 모든 데이터 컨트롤의 이름을 알아야합니다.
  2. 이것은 각 컨트롤의 ID가 필드 이름과 일치한다는 가정에 의존합니다.
  3. 'GetValue'기능 (여기에 포함되지 않음)은 서투른 솔루션입니다. 다양한 유형 (TextBox, DropdownList, Checkbox 등)을 확인하고 적절한 속성 (TextBox.Text, DropDownList.SelectedValue, Checkbox에서 문자열 값을 가져옵니다. 확인 등).

나는 여전히 '<%#bind ( "foo")%>'구문에 묶인 것을 아는 방법을 가지고 있고 그 정보를 직접 얻는 방법을 가지고 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top