ASP.NET의 사용자 정의 합성물의 아동 제어 초기화
-
02-07-2019 - |
문제
내가 작업하고있는 일련의 컨트롤의 일부는 분명히 복합재에 그들 중 일부를 함께 모으는 것과 관련이 있습니다. 나는 이것이 고려가 필요하다는 것을 빠르게 배우기 시작했다 (이것은 나에게 모두 새로운 것입니다!) :)
나는 기본적으로 a StyledWindow
본질적으로 영광스러운 제어 Panel
다른 비트를 할 수있는 능력 (예 : 경계 등).
다음은 자식 제어를 인스턴스화하는 코드입니다. 이 시점까지는 평범한 정적 컨트롤로 올바르게 작동 한 것 같습니다.
protected override void CreateChildControls()
{
_panel = new Panel();
if (_editable != null)
_editable.InstantiateIn(_panel);
_regions = new List<IAttributeAccessor>();
_regions.Add(_panel);
}
오늘 문제는 더 복잡한 제어를 시도했을 때 문제가 발생했습니다. 이 컨트롤은 페이지에 대한 참조를 사용하여 JavaScript를 주입하여 좀 더 칙칙하고 반응이 좋게 만듭니다 ( RegisterClientScriptBlock
내가 페이지 심판이 필요한 유일한 이유입니다).
이제 이것은 "객체 null"오류를 일으켰지 만, 이것을 렌더 메소드에 국한했는데, 물론 [null]에 대한 방법을 호출하려고했습니다. Page
물체.
나를 혼란스럽게하는 것은 컨트롤이 독립형으로 잘 작동한다는 것입니다. StyledWindow
그것은 모두 끔찍하게 틀렸다!
그래서, 나는 내에서 무언가를 놓치고있는 것 같습니다. StyledWindow
또는 ChildControl
. 어떤 아이디어?
업데이트
처럼 브래드 윌슨 꽤 지적하면, 당신은 컨트롤이 Controls
수집. 이것이 바로 _panel
이것은 나를 위해 그것을 처리하기 위해 거기에 있었기 때문에 기본적으로 무시했습니다. Controls
(어딘가에 가이드에서 이것을 얻었습니다) :
Panel _panel; // Sub-Control to store the "Content".
public override ControlCollection Controls
{
get
{
EnsureChildControls();
return _panel.Controls;
}
}
나는 그것이 사물을 명확히하는 데 도움이되기를 바랍니다. 사과.
다음 업데이트 Longhorn213의 답변
맞아, 나는 컨트롤을 가지고 놀면서 복합재 내에 하나를 배치하고있다. 그런 다음 제어 라이프 사이클에서 이벤트 메이저 이벤트에서 페이지 상태를 얻었고 페이지로 렌더링했습니다.
독립형은 잘 작동하고 페이지는 예상대로 입증됩니다. 그러나 복합재에 중첩 된 것은 다릅니다. 이것의 OnLoad
이벤트는 전혀 해고되지 않습니다! 그래서 브래드가 제어 계층을 올바르게 설정하지 않는다는 점에서 브래드가 옳다고 생각합니다. 누구든지 내가 놓친 것에 대한 조언을 제공 할 수 있습니까? 패널 방법이 충분하지 않습니까? (글쎄, 분명히 그렇지 않습니까?!) : D
도움을 주셔서 감사합니다. 감사합니다 :)
해결책 3
해결되었다!
맞아, 나는 오늘이 금이 가기로 결심했다! 여기 내 생각이있었습니다.
- 나는 사용을 생각했다
Panel
약간의 해킹 이었으므로 제거하고 실제로 어떻게 수행되는지 알아 내야합니다. - 나는 같은 일을하고 싶지 않았다
MyCtl.Controls[0].Controls
복합재에 추가 된 컨트롤에 액세스합니다. - 나는 망할 것이 일하기를 원했다!
그래서 나는 검색하고 쳤다 MSDN, 이 artcle ~였다 진짜 도움이된다 (즉, 거의 복사 'n'페이스트를 좋아하고 잘 설명했다 - MSDN이 전통적으로 나쁜 것은). 멋진!
그래서 나는 사용을 찢었다 Panel
그리고 거의 Artcle을 따라 가서 복음으로 가져 가서 내가 갔을 때 메모를했습니다.
지금 내가 가진 것들은 다음과 같습니다.
- 나는 잘못된 용어를 사용하고 있다는 것을 알게되었습니다. 나는 그것을 a라고 부르고 있었어야했다 템플릿 제어. 템플릿 컨트롤은 기술적으로 복합재이지만 뚜렷한 차이가 있습니다. 템플릿 컨트롤은 추가 된 항목의 인터페이스를 정의 할 수 있습니다.
- 템플릿 컨트롤은 매우 강력하고 실제로 머리를 돌면 매우 빠르고 쉽게 설정할 수 있습니다!
- 나는 디자이너 지원으로 더 많은 것을 플레이하여 모든 것을 완전히 이해하고 블로그 게시물을 얻을 것입니다 :)
- "템플릿"컨트롤은 템플릿 데이터의 인터페이스를 지정하는 데 사용됩니다.
예를 들어 다음은 템플릿 컨트롤을위한 ASPX 마크 업입니다.
<cc1:TemplatedControl ID="MyCtl" runat="server">
<Template>
<!-- Templated Content Goes Here -->
</Template>
</cc1:TemplatedControl>
그녀는 내가 지금 가지고있는 코드입니다
public class DummyWebControl : WebControl
{
// Acts as the surrogate for the templated controls.
// This is essentially the "interface" for the templated data.
}
templatecontrol.cs에서 ...
ITemplate _template;
// Surrogate to hold the controls instantiated from
// within the template.
DummyWebControl _owner;
protected override void CreateChildControls()
{
// Note we are calling base.Controls here
// (you will see why in a min).
base.Controls.Clear();
_owner = new DummyWebControl();
// Load the Template Content
ITemplate template = _template;
if (template == null)
template = new StyledWindowDefaultTemplate();
template.InstantiateIn(_owner);
base.Controls.Add(_owner);
ChildControlsCreated = true;
}
그런 다음 [대리] 객체의 컨트롤에 쉽게 액세스 할 수 있도록 :
(이것이 바로 기지에 지우거나 추가 해야하는 이유입니다.
public override ControlCollection Controls
{
get
{
EnsureChildControls();
return _owner.Controls;
}
}
그리고 그것은 당신이 방법을 알면 쉽습니다! :)
다음: 디자인 시간 영역 지원!
다른 팁
컨트롤 컬렉션에 귀하의 컨트롤을 추가하는 것을 보지 못합니다. 이는 페이지에 액세스 할 수없는 이유를 설명합니다 (공식적으로 페이지에 배치 된 적이 없기 때문에).
나는 항상 JavaScript 호출을 ONLOAD 기능에 넣었습니다. 아래와 같은.
protected override void OnLoad(EventArgs e)
{
// Do something to get the script
string script = GetScript();
this.Page.ClientScript.RegisterClientScriptBlock(this.Page.GetType(), "SomeJavaScriptName", script);
// Could also use this function to determine if the script has been register. i.e. more than 1 of the controls exists
this.Page.ClientScript.IsClientScriptBlockRegistered("SomeJavaScriptName");
base.OnLoad(e);
}
여전히 렌더링을하고 싶다면 응답에 스크립트를 작성할 수 있습니다. RegisterScriptBlock이하는 일이므로 스크립트를 페이지에 인라인으로 표시합니다.
맞아, 나는 연주를했고 나는 롱혼이 옳았 기 때문에 내 통제 인스턴스화에 문제가 있다고 생각했다. OnLoad
(그리고 나는 할 수 없었습니다), 브래드는 내가 내 Controls
계층 구조는 다음에 추가하여 유지되었습니다 Controls
복합재 수집.
그래서 여기에는 두 가지가있었습니다.
- 나는 그것을 우선했다
Controls
컴포지트가이를 반환하기위한 속성 액세서Panel
가고 싶지 않기 때문에의 컨트롤 컬렉션ctl.Controls[0].Controls[0]
내가 원하는 실제 컨트롤에 도달하기 위해. 나는 이것을 제거했지만 이런 분류를 받아야한다. - 나는 추가하지 않았다
Panel
~로Controls
수집, 나는 지금 이것을했다.
그러나 이제는 작동하지만 어떻게 얻을 수 있습니까? Controls
복합재가 Panel
, Panel
그 자체?