사용자 정의 ASP.NET 컨테이너 컨트롤
-
08-07-2019 - |
문제
나는 몇 개의 div로 둘러싸인 것을 제외하고는 둥근 상자 모양을 만들기 위해 패널 컨트롤과 똑같이 작동하는 사용자 정의 컨트롤을 만들려고 노력했습니다. 나는 이것을하는 방법에 대한 괜찮은 예를 찾을 수 없었습니다.
텍스트와 컨트롤을 제어 내부에 배치하고 패널을 참조하지 않고 직접 액세스 할 수 있어야합니다 (패널 제어가 작동하는 방식).
누구든지 이것에 대한 예가 있습니까?
해결책
이를 수행하는 두 가지 방법이 있습니다. 하나는 귀하의 통제에 대한 InamingContainer를 구현하는 것이며 많은 노력이 필요합니다.
다른 방법은 패널에서 상속하고 RenderBegintag 및 RenderEndTag 메소드를 무시하여 사용자 정의 마크 업을 추가하는 것입니다. 이것은 쉬워요.
public class RoundedCornersPanel : System.Web.UI.WebControls.Panel
{
public override RenderBeginTag (HtmlTextWriter writer)
{
writer.Write("Your rounded corner opening markup");
base.RenderBeginTag(writer);
}
public override RenderEndTag (HtmlTextWriter writer)
{
base.RenderEndTag(writer);
writer.Write("Your rounded corner closing markup");
}
}
다른 팁
여기에는 이미 몇 가지 답변이 있지만 패널 클래스에서 상속하지 않고 가장 기본적인 구현을 붙여 넣고 싶었습니다. 그래서 여기는 다음과 같습니다.
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
[ToolboxData("<{0}:SimpleContainer runat=server></{0}:SimpleContainer>")]
[ParseChildren(true, "Content")]
public class SimpleContainer : WebControl, INamingContainer
{
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateContainer(typeof(SimpleContainer))]
[TemplateInstance(TemplateInstance.Single)]
public virtual ITemplate Content { get; set; }
public override void RenderBeginTag(HtmlTextWriter writer)
{
// Do not render anything.
}
public override void RenderEndTag(HtmlTextWriter writer)
{
// Do not render anything.
}
protected override void RenderContents(HtmlTextWriter output)
{
output.Write("<div class='container'>");
this.RenderChildren(output);
output.Write("</div>");
}
protected override void OnInit(System.EventArgs e)
{
base.OnInit(e);
// Initialize all child controls.
this.CreateChildControls();
this.ChildControlsCreated = true;
}
protected override void CreateChildControls()
{
// Remove any controls
this.Controls.Clear();
// Add all content to a container.
var container = new Control();
this.Content.InstantiateIn(container);
// Add container to the control collection.
this.Controls.Add(container);
}
}
그런 다음 다음과 같이 사용할 수 있습니다.
<MyControls:SimpleContainer
ID="container1"
runat="server">
<Content>
<asp:TextBox
ID="txtName"
runat="server" />
<asp:Button
ID="btnSubmit"
runat="server"
Text="Submit" />
</Content>
</MyControls:SimpleContainer>
그리고 CodeBehind에서 당신은 다음과 같은 일을 할 수 있습니다.
this.btnSubmit.Text = "Click me!";
this.txtName.Text = "Jack Sparrow";
System.web.ui.control을 상속하는 클래스를 작성하고 Render (htmltextWriter) 메소드를 과대 평가하십시오. 이 방법에서는 주변 시작 태그를 렌더링 한 다음 어린이를 렌더링 한 다음 엔드 태그를 렌더링합니다.
protected override void Render ( HtmlTextWriter output )
{
output.Write ( "<div>" );
RenderChildren ( output );
output.Write ( "</div>" );
}
둥근 모서리는 일반적으로 왼쪽 상단, 오른쪽 상단, 왼쪽 하단 및 오른쪽 하단에 CSS 및 코너 이미지를 사용하여 달성됩니다. 4 개의 중첩 된 divs를 사용하여 수행 할 수 있으며, 각각의 층으로 작용하며 각각은 배경 이미지로서 하나의 코너 이미지를 갖습니다.
코드 프로젝트에는 관심이있는 것이 있습니다. 패널 곡선 컨테이너 - ASP.NET 사용자 정의 제어 너겟. 나는 당신이 코드를 가지고 놀고 당신이 원하는 행동과 모습을 가질 수 있다고 확신합니다.
패널 대신 WebControl에서 직접 상속하지 않으려면 가장 쉬운 방법은 속성으로 클래스를 장식하는 것입니다. [ParseChildren(false)]
. 언뜻보기에 이것은 당신이 아이들을 구문 분석하고 싶지 않다는 것을 암시 할 수 있습니다. false
실제로 아이들이 속성으로 취급되기를 원하지 않는다는 것을 나타냅니다. 대신, 당신은 그들이 컨트롤로 취급되기를 원합니다.
이 속성을 사용하면 상자 밖에서 거의 모든 기능을 얻을 수 있습니다.
[ToolboxData("<{0}:RoundedBox runat=server></{0}:RoundedBox>")]
[ParseChildren(false)]
public class RoundedBox : WebControl, INamingContainer
{
public override void RenderBeginTag(HtmlTextWriter writer)
{
writer.Write("<div class='roundedbox'>");
}
public override void RenderEndTag(HtmlTextWriter writer)
{
writer.Write("</div>");
}
}
이렇게하면 페이지에 Roundedbox 컨트롤을 추가하고 DIV 내부에 렌더링 될 어린이 (ASP.NET 컨트롤 또는 RAW HTML)를 추가 할 수 있습니다.
물론 CSS는 라운드 박스 클래스를 올바르게 스타일링하기 위해 추가됩니다.
당신이 사용할 수있는 또 다른 것, 둥근 코너 익스텐더 ASP.NET AJAX 툴킷에서.
나는 그것이 당신이 요청한 것이 아니라는 것을 알고 있지만, 당신은 사용자 정의 코드를 작성할 필요가 없습니다.
도움이되기를 바랍니다!
2 열 레이아웃 패널을 생성하고 싶었 기 때문에이 질문을 보았습니다. (내가 필요로하는 것의 훨씬 간단한 예입니다. 나는 내가 상처를 입은 솔루션을 공유하고 있습니다.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Syn.Test
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:MultiPanel runat=server></{0}:MultiPanel>")]
[ParseChildren(true)]
[PersistChildren(false)]
public class MultiPanel : WebControl, INamingContainer
{
public ContentContainer LeftContent { get; set; }
public ContentContainer RightContent { get; set; }
protected override void CreateChildControls()
{
base.CreateChildControls();
}
protected override void Render(HtmlTextWriter output)
{
output.AddStyleAttribute("width", "600px");
output.RenderBeginTag(HtmlTextWriterTag.Div);
output.AddStyleAttribute("float", "left");
output.AddStyleAttribute("width", "280px");
output.AddStyleAttribute("padding", "10px");
output.RenderBeginTag(HtmlTextWriterTag.Div);
LeftContent.RenderControl(output);
output.RenderEndTag();
output.AddStyleAttribute("float", "left");
output.AddStyleAttribute("width", "280px");
output.AddStyleAttribute("padding", "10px");
output.RenderBeginTag(HtmlTextWriterTag.Div);
RightContent.RenderControl(output);
output.RenderEndTag();
output.RenderEndTag();
}
}
[ParseChildren(false)]
public class ContentContainer : Control, INamingContainer
{
}
}
내가 아직도 가지고있는 문제는이 시나리오에서 Intellisense가 작동하지 않는다는 것입니다. 왼쪽 및 오른쪽 콘텐츠 태그를 제안하지는 않습니다.
public class myCustomPanel : Panel
{
public override void RenderBeginTag(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Class, "top_left_corner");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
base.RenderBeginTag(writer);
}
public override void RenderEndTag(HtmlTextWriter writer)
{
base.RenderEndTag(writer);
writer.RenderEndTag();
}
}