2009-02-20 4 views
5

이것은 내 첫 번째 게시물입니다! 나는 필사적이어서 표준 검색을 뛰어 넘는다. 이 고급 또는 전문가 수준의 .NET 질문 믿습니다. 동적 컨트롤을 컨트롤 컬렉션 중간에 삽입하십시오.

문제

내가리스트의 중간에 동적으로 사용자 컨트롤을 삽입 할 수 필요가있는 .NET 웹 응용 프로그램을 구축한다는 것이다. 나는 동적 컨트롤에 상당히 익숙하다. 목록의 끝에 추가하기 만하면된다. (예 : 나는 다음과 같은 기사에 익숙하다 : http://msdn.microsoft.com/en-us/library/ms972976.aspx). 그러나 컨트롤 컬렉션의 앞 또는 중간에있는 UserControl을 추가해야하는 경우 컨트롤의 UniqueID가 제거 된 이후로 꽤 많이 손실됩니다.

간단한 예를 들어

, 이제 내가 MyControl.ascx이라는 된 UserControls의 목록을 추가하고 할 수있는 패널을 가정 해 봅시다. 또한 패널에서 Controls 컬렉션의 지정된 인덱스에 MyControl.ascx를 동적으로 삽입해야하는 페이지에서 해고 될 수있는 이벤트가 있습니다. 또한 MyControl.ascx에서 하나 이상의 이벤트를 구독해야합니다. 즉, 컨트롤의 이벤트가로드되기 전에 컨트롤을로드해야합니다. 그렇지 않으면 컨트롤이 실행되지 않습니다. 내가 무슨 말을하고 있는지 잘 모르겠다면 질문을 잘못 말했거나이 질문이 너무 어려울 수도 있습니다. :)

다음은 문제를 보여주기위한 몇 가지 C# 의사 코드입니다. 문제는 Controls.AddAt (index, control) 메서드가 그에 따라 컨트롤의 고유 값을 조정하지 않는다는 것입니다. 예를 들어, Controls 컬렉션의 다음 컨트롤을 고려하십시오.

실제로 UniqueID에 직접 의존하는 코드를 작성하는지 여부와 관계없이 .NET은 UniqueID를 사용하여 간접적으로 이전 포스트 백에서 발생한 이벤트를 연결합니다 컨트롤은 새 포스트 백에로드됩니다. 내가 다음 Controls.AddAt(0, newControl)을 할 경우

: 인덱스 0에있는 컨트롤을 삽입하고자하는 다른 컨트롤에서 포스트 백 (Page.IsPostback == false) 후 초기 Page Load (Page.IsPostback == false)

<table> 
    <tr> 
    <td width='100'>Control index</td> 
    <td width='75'>UniqueID</td> 
    <td>Value</td> 
    </tr> 
    <tr> 
    <td>0</td> 
    <td>ctl00</td> 
    <td>value1</td> 
    </tr> 
    <tr> 
    <td>1</td> 
    <td>ctl01</td> 
    <td>value2</td> 
    </tr> 
    <tr> 
    <td>2</td> 
    <td>ctl02</td> 
    <td>value3</td> 
    </tr> 
</table> 

: 내 앞의 예 촬영 Controls 컬렉션은 다음과 같습니다.

<table> 
    <tr> 
    <td width='100'>Control index</td> 
    <td width='75'>UniqueID</td> 
    <td>Value</td> 
    </tr> 
    <tr> 
    <td>0</td> 
    <td>ctl03</td> 
    <td>value0 <== the controls' unique IDs do not shift!</td> 
    </tr> 
    <tr> 
    <td>1</td> 
    <td>ctl00</td> 
    <td>value1</td> 
    </tr> 
    <tr> 
    <td>2</td> 
    <td>ctl01</td> 
    <td>value2</td> 
    </tr> 
    <tr> 
    <td>3</td> 
    <td>ctl02</td> 
    <td>value3</td> 
    </tr> 
</table> 

그래서 링크 버튼을 클릭하면 Value == value0 및 UniqueID == ctl03 인 컨트롤은 포스트 백에서 다음과 같이 정렬되며 UniqueID는 원하는 순서대로 정렬되지 않습니다. 이 클릭 이벤트가 잘못된 컨트롤에 연결하게됩니다 : 나는 이러한 동적 컨트롤에서 이벤트를 처리하지 않은 경우

<table> 
    <tr> 
    <td width='100'>Control index</td> 
    <td width='75'>UniqueID</td> 
    <td>Value</td> 
    </tr> 
    <tr> 
    <td>0</td> 
    <td>ctl00</td> 
    <td>value0 <== the control i wanted to throw the event</td> 
    </tr> 
    <tr> 
    <td>1</td> 
    <td>ctl01</td> 
    <td>value1</td> 
    </tr> 
    <tr> 
    <td>2</td> 
    <td>ctl02</td> 
    <td>value2</td> 
    </tr> 
    <tr> 
    <td>3</td> 
    <td>ctl03</td> 
    <td>value3 <== the actual control to which the event is attached</td> 
    </tr> 
</table> 

이 아마 문제가되지 않을 것입니다.

// on init i just need to pull the records from the DB, turn them 
// into a MyControl.ascx, and then add them to my panel 
protected override void OnInit(EventArgs e) 
{ 
    base.OnInit(e); 

    // get my List<SomethingFromDB> ordered by value and iterate through, 
    // adding controls to the control collection 
    List<SomethingFromDB> myList = remoteService.GetSomeListFromTheDB(); 
    foreach(SomethingFromDB something in List<SomethingFromDB>) 
    { 
     // load a new MyControl.ascx 
     MyControl myControl = (MyControl)LoadControl("~/Controls/MyControl .ascx"); 
     // populate the values of myControl with the "something" 
     this.populateMyControl(something); 
     // dynamically add the control to my panel 
     this.myPanel.Add(myControl);  
     // subscribe to event 
     myControl.SomeArbitraryEvent += new EventHandler(MyArbitraryHandler); 
    } 

    // This event gets fired by a magical control on the page and passes a 
    // new SomethingFromDB which needs to be inserted into the DB and then 
    // dynamically inserted into the Controls collection at the specified index 
    private void SomeOtherControl_ClickInsert(object sender, MyControlEventArgs e) 
    { 
     // insert this record into the DB    
     remoteService.InsertIntoDB(e.SomethingFromDB);  
     // dynamically load this control 
     MyControl myControl = (MyControl)LoadControl("~/Controls/MyControl .ascx"); 
     // get the index into which we will be inserting this control 
     int index = e.NewIndex;     
     //dynamically add the control to my panel at the specified index. 
     // THIS DOES NOT ADJUST THE UNIQUEID VALUES ACCORDINGLY 
     // AND IS THE SOURCE OF MY PROBLEM! 
     this.myPanel.AddAt(index, myControl); 
    } 

이 도와주세요 : 여기 내 코드입니다. 이 하나가 나를 죽이고있다. 더 많은 정보가 필요하거나 질문이 있으시면 알려 주시기 바랍니다. 자세한 정보를 제공해 드리겠습니다. 도와 주셔서 대단히 감사합니다!

+0

이제는 잘못된 방향으로 가고 있습니다. 원하는 것을 설명하기보다는 문제를 설명하는 것입니다. 특정 문제에 대한 더 나은 방법 (때로는 올바른 방법)을 제시하기가 어렵다는 점에서 차이가 있습니다. 질문을 수정하십시오! –

답변

5

자동 번호 매기기를 사용하려면 모든 포스트 백마다 동일한 순서로 패널에 컨트롤을 추가해야합니다. 분명히 포스트 백에서 컨트롤은 고유 한 ID가 할당되어야합니다. 그렇지 않으면 컨트롤 이벤트가 발생하지 않습니다.

UniqueID은 처음 사용할 때 Control.ID * 속성의 값으로 초기화됩니다.해당 속성이 설정되어 있지 않으면 관찰 한대로 자동으로 ctlxx으로 생성됩니다. 일단 할당되면 컨트롤 UniqueID은 읽기 전용입니다.

따라서 기본 키 형식을 사용하는 경우 해당 기본 키를 기반으로 컨트롤을 만들 때 컨트롤의 ID 속성을 설정할 수 있습니다. UniqueID은 페이지가 상태를로드 할 때 해당 값으로 설정됩니다.

  • 각주 다음 UniqueID 속성이 실제로 명명 컨테이너의 접두사의 조합과 ID 속성입니다.
+0

응답 주셔서 감사합니다, 햇빛. 고유 ID는 myPanel에 추가하는 즉시 설정됩니다. 문제는 "SomeOtherControl_ClickInsert"가 호출 될 때까지 컨트롤이 이미 패널에 있고 UniqueID가 할당되어 있다는 것입니다. 내 콘트롤을 넣을 때 이미 너무 늦었 어. – jakejgordon

+0

나는이 300 자 제한을 정말로 싫어한다. 어쨌든 UniqueID는 컨트롤 컬렉션의 컨트롤 색인뿐만 아니라 부모 컨트롤과 페이지의 조합이라는 것을 알고 있습니다. 난 그냥 컬렉션의 중간에 컨트롤을 넣을 수 및 오른쪽 이벤트에 후크 – jakejgordon

+0

... 동적 컨트롤 중 하나가 클릭하면 다시 게시 오른쪽 이벤트 후크를 볼 수 없습니다. 좀 더 자세히 설명해 주시겠습니까? 나는 내 질문에 대해 잘 말하지 않았을 지 모르겠다. – jakejgordon

0

페이지 지시문에서 다음 속성을 사용하십시오.

MaintainScrollPositionOnPostback = true 

이것은 도움이된다고 생각합니다.