연습: 웹 서버 컨트롤의 기본 컨트롤 디자이너 만들기
업데이트: 2007년 11월
이 연습에서는 기본 컨트롤 디자이너를 만들어 웹 서버 컨트롤에 디자인 타임 UI(사용자 인터페이스)를 제공하는 방법을 보여 줍니다.
사용자 지정 ASP.NET 서버 컨트롤을 만들 경우에는 연결된 디자이너를 만들어 Microsoft Visual Studio 2005 같은 비주얼 디자인 도구에서 컨트롤을 렌더링할 수 있습니다. 이 디자이너를 사용하면 호스트 환경에서 컨트롤의 디자인 타임 UI를 렌더링하여 개발자가 컨트롤의 속성과 내용을 쉽게 구성할 수 있도록 할 수 있습니다. 디자이너 기능에 대한 정보나 사용자 지정 컨트롤과 연결할 수 있는 다양한 디자이너 클래스에 대한 자세한 내용을 보려면 ASP.NET 컨트롤 디자이너 개요를 참조하십시오.
이 연습을 통해 다음과 같은 작업 방법을 배웁니다.
표준 합성 컨트롤 디자이너를 만들어 합성 컨트롤과 연결합니다.
크기 조정 가능한 합성 컨트롤 디자이너를 만들어 합성 컨트롤과 연결합니다.
편집 가능한 영역이 있는 기본 컨테이너 컨트롤 디자이너를 만들어 WebControl 컨트롤과 연결합니다. 이 디자이너를 사용하면 디자인 화면의 편집 가능한 영역에 텍스트를 추가하거나 추가 컨트롤을 끌어 올 수 있습니다.
웹 페이지에서 사용자 지정 컨트롤 및 연결된 디자이너를 참조합니다.
Visual Studio 2005의 디자인 뷰에서 웹 페이지로 작업합니다.
사전 요구 사항
이 연습을 따라 하려면 다음과 같은 요건을 갖추어야 합니다.
사용자 지정 컨트롤 및 연결된 디자이너를 호스팅할 웹 페이지를 만드는 데 사용할 Visual Studio 2005
컨트롤을 호스팅할 페이지가 속한 ASP.NET 웹 사이트 사이트가 이미 구성되어 있으면 이 연습의 시작 지점으로 해당 사이트를 사용할 수 있습니다. 사이트가 구성되지 않은 경우에는 방법: IIS 5.0 및 6.0에서 가상 디렉터리 만들기 및 구성에서 가상 디렉터리나 사이트를 만드는 방법에 대한 자세한 내용을 확인하십시오.
사용자 지정 컨트롤 및 디자이너 만들기
이 단원에서는 기본 웹 서버 컨트롤 세 개와 해당 컨트롤 각각에 대해 연결된 사용자 지정 컨트롤 디자이너를 만듭니다.
코드를 작성할 파일을 만들려면
편집기에서 SimpleControlDesigners와 현재 사용 중인 언어에 적합한 확장명을 조합하여 새 파일을 만듭니다. 예를 들어, Visual Studio 2005에서 SimpleControlDesigners.vb 또는 SimpleControlDesigners.cs라는 새 클래스 파일을 만듭니다.
디자이너 클래스로 작업하는 데 필요한 다음과 같은 네임스페이스 참조를 추가합니다. 컨트롤 및 연결된 디자이너를 포함할 네임스페이스도 추가합니다.
Imports System Imports System.ComponentModel Imports System.ComponentModel.Design Imports System.Drawing Imports System.Web.UI Imports System.Web.UI.Design Imports System.Web.UI.Design.WebControls Imports System.Web.UI.WebControls Namespace Samples.AspNet.VB.Controls End Namespace
using System; using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing; using System.Web.UI; using System.Web.UI.Design; using System.Web.UI.Design.WebControls; using System.Web.UI.WebControls; namespace Samples.AspNet.CS.Controls { }
파일을 저장합니다.
이제 합성 웹 서버 컨트롤 및 연결된 디자이너를 만들 수 있습니다. 디자이너와 컨트롤은 동일한 어셈블리에 있을 수도 있고 다른 어셈블리에 있을 수도 있지만 이 연습에서는 편의를 위해 컨트롤과 디자이너를 동일한 코드 파일 및 어셈블리에 만듭니다.
합성 컨트롤 및 연결된 디자이너를 만들려면
다음 코드 예제와 같이, SimpleControlDesigners 파일에 선언한 네임스페이스 안에 CompositeControl에서 상속되는 합성 컨트롤 클래스의 공용 선언을 만듭니다.
Public Class SimpleCompositeControl Inherits CompositeControl End Class
public class SimpleCompositeControl : CompositeControl { }
다음 코드 예제의 public 속성을 클래스에 추가합니다. 이러한 속성은 웹 페이지에 UI의 일부를 만드는 데 사용됩니다.
Dim _prompt As String = "Please enter your date of birth: " Overridable Property Prompt() As String Get Dim o As Object o = ViewState("Prompt") If o Is Nothing Then Return _prompt Else Return CType(o, String) End If End Get Set(ByVal value As String) ViewState("Prompt") = value End Set End Property Overridable Property DOB() As DateTime Get Dim o As Object o = ViewState("DOB") If o Is Nothing Then Return DateTime.Now Else Return CType(o, DateTime) End If End Get Set(ByVal value As DateTime) ViewState("DOB") = value End Set End Property
private String _prompt = "Please enter your date of birth: "; public virtual String Prompt { get { object o = ViewState["Prompt"]; return (o == null) ? _prompt : (string)o; } set { ViewState["Prompt"] = value; } } public virtual DateTime DOB { get { object o = ViewState["DOB"]; return (o == null) ? DateTime.Now : (DateTime)o; } set { ViewState["DOB"] = value; } }
합성 컨트롤에 자식 컨트롤을 추가하는 메서드를 만듭니다. 다음 메서드는 웹 페이지에 표시되는 텍스트 상자 두 개와 줄 바꿈 하나를 추가합니다.
Protected Overrides Sub CreateChildControls() Dim lab As New Label lab.Text = Prompt lab.ForeColor = System.Drawing.Color.Red Me.Controls.Add(lab) Dim lit As New Literal() lit.Text = "<br />" Me.Controls.Add(lit) Dim tb As New TextBox() tb.ID = "tb1" tb.Text = DOB.ToString() Me.Controls.Add(tb) MyBase.CreateChildControls() End Sub
protected override void CreateChildControls() { Label lab = new Label(); lab.Text = Prompt; lab.ForeColor = System.Drawing.Color.Red; this.Controls.Add(lab); Literal lit = new Literal(); lit.Text = "<br />"; this.Controls.Add(lit); TextBox tb = new TextBox(); tb.ID = "tb1"; tb.Text = DOB.ToString(); this.Controls.Add(tb); base.CreateChildControls(); }
CompositeControlDesigner에서 파생하여 방금 만든 합성 컨트롤과 연결할 간단한 합성 컨트롤 디자이너 클래스를 만듭니다.
디자이너에는 여러 가지 UI 렌더링 기능을 추가할 수 있지만 다음 코드 예제에서는 디자이너를 만든 후 디자인 뷰에서 컨트롤의 크기를 조정하지 못하도록 기본 클래스의 주요 속성만 재정의합니다.
Public Class SimpleCompositeControlDesigner Inherits CompositeControlDesigner ' Set this property to prevent the designer from being resized. Public Overrides ReadOnly Property AllowResize() As Boolean Get Return False End Get End Property End Class
public class SimpleCompositeControlDesigner : CompositeControlDesigner { // Set this property to prevent the designer from being resized. public override bool AllowResize { get { return false; } } }
다음 코드 예제와 같이, 방금 만든 디자이너 클래스를 컨트롤과 연결하는 Designer 메타데이터 특성을 합성 컨트롤의 클래스 선언 바로 위에 추가합니다.
<Designer(GetType(SimpleCompositeControlDesigner))> _ Public Class SimpleCompositeControl Inherits CompositeControl
[Designer(typeof(SimpleCompositeControlDesigner))] public class SimpleCompositeControl : CompositeControl
파일을 저장합니다.
사용자 지정 합성 웹 서버 컨트롤 및 연결된 디자이너를 만들었으므로 이제 첫 번째 컨트롤에서 파생되는 두 번째 컨트롤을 만들 수 있습니다. 두 번째 컨트롤은 디자인 화면에서 연결된 디자이너의 크기를 조정할 수 있다는 점만 다릅니다.
크기 조정 가능한 합성 컨트롤 및 연결된 디자이너를 만들려면
SimpleControlDesigners 파일에 선언한 네임스페이스 안에, 앞에서 만든 SimpleCompositeControl 컨트롤에서 상속되는 새 합성 컨트롤 클래스의 공용 선언을 만듭니다. 다음 코드 예제에서는 새 선언을 보여 줍니다.
Public Class SimpleCompositeControl2 Inherits SimpleCompositeControl End Class
public class SimpleCompositeControl2 : SimpleCompositeControl { }
이 컨트롤을 CompositeControlDesigner 기본 클래스와 연결합니다.
기본적으로 이 예제에서는 합성 컨트롤에 대해 크기 조정 가능한 기본 디자이너를 만듭니다.
<Designer(GetType(CompositeControlDesigner))> _ Public Class SimpleCompositeControl2 Inherits SimpleCompositeControl End Class
[Designer(typeof(CompositeControlDesigner))] public class SimpleCompositeControl2 : SimpleCompositeControl { }
파일을 저장합니다.
앞에서는 합성 컨트롤 디자이너와 연결한 합성 컨트롤 두 개를 만들었습니다. 이번에는 WebControl에서 파생되는 간단한 컨트롤을 만들어 ContainerControlDesigner 클래스와 연결합니다. 이 디자이너 형식은 디자이너를 사용자 지정 웹 서버 컨트롤 하나와 연결하고 디자인 화면에 편집 가능한 단일 영역을 제공하려는 경우 유용합니다. 여기서 만드는 사용자 지정 컨트롤은 아무 기능을 구현하지 않으며 ContainerControlDesigner 클래스의 기능을 표시하는 데만 사용됩니다.
참고: |
---|
앞에서 만든 합성 컨트롤과 디자이너를 사용하여 동일한 기능을 제공할 수도 있습니다. 이 예제는 ContainerControlDesigner 클래스 사용 방법과 WebControl 컨트롤에 대한 연결 방법을 보여 주기 위해 제공됩니다. |
웹 서버 컨트롤과 편집 가능한 영역이 있는 컨테이너 디자이너를 만들려면
다음 코드 예제와 같이, SimpleControlDesigners 파일에 선언한 네임스페이스 안에 새 웹 서버 컨트롤 클래스의 공용 선언을 만듭니다.
Public Class SimpleContainerControl Inherits WebControl Implements INamingContainer End Class
public class SimpleContainerControl : WebControl, INamingContainer { }
사용자 지정 컨트롤과 연결할 컨테이너 컨트롤 디자이너 클래스를 만듭니다. 디자이너의 프레임 스타일을 포함할 FrameStyle 속성과 프레임의 머리글 텍스트를 포함할 FrameCaption 속성을 하나씩 구현합니다. 이 두 속성은 디자인 화면에서 컨트롤을 시각적으로 렌더링하고 선택할 수 있는 프레임을 제공합니다. 디자이너와 속성에 대한 코드는 다음 코드 예제에 나옵니다.
참고: ContainerControlDesigner 클래스는 디자인 타임에 사용자 지정 컨트롤을 렌더링하고 편집 가능한 단일 영역을 제공하는 것과 관련된 다른 모든 사항을 자동으로 처리합니다.
Public Class SimpleContainerControlDesigner Inherits ContainerControlDesigner Dim _style As Style ' Add the caption by default. Public Overrides ReadOnly Property FrameCaption() As String Get Return "A Simple ContainerControlDesigner" End Get End Property Public Overrides ReadOnly Property Framestyle() As Style Get If _style Is Nothing Then _style = New Style() _style.Font.Name = "Verdana" _style.Font.Size = New FontUnit("XSmall") _style.BackColor = Color.LightBlue _style.ForeColor = Color.Black End If Return _style End Get End Property End Class
public class SimpleContainerControlDesigner : ContainerControlDesigner { private Style _style = null; // Add the caption by default. Note that the caption // will only appear if the Web server control // allows child controls rather than properties. public override string FrameCaption { get { return "A Simple ContainerControlDesigner"; } } public override Style FrameStyle { get { if (_style == null) { _style = new Style (); _style.Font.Name = "Verdana"; _style.Font.Size = new FontUnit ("XSmall"); _style.BackColor = Color.LightBlue; _style.ForeColor = Color.Black; } return _style; } } }
디자이너를 컨트롤과 연결합니다. 웹 서버 컨트롤의 클래스 선언 바로 위에 Designer 메타데이터 특성을 추가합니다. 이 경우에는 다음 코드 예제와 같이 false 매개 변수와 함께 ParseChildren 특성도 추가합니다. 이렇게 하면 디자인 타임 파서가 컨트롤의 내부 내용을 속성이 아니라 자식 컨트롤로 처리합니다. 이 경우에는 디자인 타임에 다른 서버 컨트롤을 편집 가능한 영역으로 끌어 올 수 있도록 이 컨트롤의 내부 내용을 자식 컨트롤로 처리하고 해당 컨트롤의 속성도 편집합니다.
<Designer(GetType(SimpleContainerControlDesigner))> _ <ParseChildren(False)> _ Public Class SimpleContainerControl Inherits WebControl Implements INamingContainer End Class
[Designer (typeof(SimpleContainerControlDesigner))] [ParseChildren (false)] public class SimpleContainerControl : WebControl, INamingContainer { }
파일을 저장합니다.
지금까지 사용자 지정 컨트롤 세 개를 만들어 각 컨트롤에 컨트롤 디자이너를 연결했습니다. 이제 컨트롤을 어셈블리로 컴파일하여 비주얼 디자인 도구에서 사용하면 됩니다.
사용자 지정 컨트롤 및 디자이너를 컴파일하려면
명령 프롬프트를 열어 SimpleControlDesigners 파일을 만든 폴더로 이동합니다. 이 프롬프트에서 소스 코드를 어셈블리로 컴파일할 수 있습니다.
참고: 이 위치에서 .NET Framework 컴파일러를 실행하려면 .NET Framework 설치 경로가 컴퓨터의 PATH 변수에 추가되어 있어야 합니다. 일반적으로 이 경로는 Windows 설치 디렉터리 아래의 \Microsoft.NET\Framework\<version number>에 있습니다. PATH 변수를 아직 업데이트하지 않았으면 내 컴퓨터를 마우스 오른쪽 단추로 클릭하고 속성을 선택한 다음 고급 탭을 클릭하고 환경 변수 단추를 클릭합니다. 시스템 변수 목록에서 PATH 변수를 두 번 클릭합니다. 변수 값 텍스트 상자에서 기존 값의 맨 끝에 세미콜론을 추가한 다음 .NET Framework 설치 경로를 입력합니다. 확인을 클릭하여 각 대화 상자를 닫습니다.
다음 컴파일 명령을 사용하여 SimpleControlDesigners 파일에 있는 컨트롤을 어셈블리로 컴파일합니다.
csc /r:System.dll /r:System.Design.dll /r:System.Drawing.dll /debug+ /r:System.Web.dll /t:library /out:SimpleControlDesignersCS.dll simplecontroldesigners.cs
vbc /r:System.dll /r:System.Design.dll /r:System.Drawing.dll /debug+ /r:System.Web.dll /t:library /out:SimpleControlDesignersVB.dll SimpleControlDesigners.vb
컨트롤을 호스팅할 페이지가 속한 웹 사이트의 \Bin 폴더로 결과 어셈블리 파일을 이동합니다.
참고: Visual Studio에서 컨트롤 및 디자이너를 컴파일하려면 System.Design.dll에 대한 참조를 추가해야 합니다. 자세한 내용은 방법: 웹 사이트의 .NET 또는 COM 구성 요소에 대한 참조 추가를 참조하십시오.
컨트롤을 호스팅할 웹 페이지 만들기
사용자 지정 컨트롤 및 연결된 컨트롤 디자이너를 사용하여 어셈블리를 만들었으므로 이제 Visual Studio 2005에서 컨트롤을 참조할 웹 페이지를 만들고, 컨트롤이 디자인 뷰에 어떻게 표시되는지 확인하고, 페이지를 브라우저에 로드합니다.
컨트롤을 호스팅할 웹 페이지를 만들려면
Visual Studio 2005에 웹 사이트가 열려 있는 상태에서 ControlDesigners.aspx라는 새 페이지를 만듭니다. 다음 코드 예제와 같이, 페이지 선언 바로 아래의 페이지 상단에 앞에서 만든 어셈블리와 컨트롤을 참조하는 Register 지시문을 추가합니다.
<%@ Page Language="VB" %> <%@ register tagprefix="aspSample" assembly="SimpleControlDesignersVB" namespace="Samples.AspNet.VB.Controls" %>
<%@ Page Language="C#" %> <%@ register tagprefix="aspSample" assembly="SimpleControlDesignersCS" namespace="Samples.AspNet.CS.Controls" %>
다음 코드 예제와 같이, 앞에서 만든 컨트롤 세 개(SimpleCompositeControl, SimpleCompositeControl2 및 SimpleContainerControl)를 각각 참조하도록 페이지의 나머지 부분을 완성합니다. 각 컨트롤을 참조하려면 Register 지시문에 지정된 aspSample 접두사를 사용합니다.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head > <title>Designers Page</title> </head> <body> <form id="form1" > <div> <p style="font-family:tahoma;font-size:large; font-weight:bold"> Simple Control Designers </p> <div style="font-family:tahoma;font-size:x-small;"> <span style="font-size: 14pt"> Composite, no-resize</span> </div> <aspSample:SimpleCompositeControl id="SimpleControl1" /> <br /><br /> <div style="font-family:tahoma;font-size:x-small;"> <span style="font-size: 14pt"> Composite, resize</span> </div> <aspSample:SimpleCompositeControl2 id="SimpleControl2" height="87px" width="238px" /> <br /><br /> <div style="font-family:tahoma;font-size:x-small;"> <span style="font-size: 14pt"> Container</span> </div> <aspSample:SimpleContainerControl id="SimpleControl3" height="57px"> Type some content here. </aspSample:SimpleContainerControl> <br /><br /> </div> </form> </body> </html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head > <title>Designers Page</title> </head> <body> <form id="form1" > <div> <p style="font-family:tahoma;font-size:large; font-weight:bold"> Simple Control Designers </p> <div style="font-family:tahoma;font-size:x-small;"> <span style="font-size: 14pt"> Composite, no-resize</span> </div> <aspSample:SimpleCompositeControl id="SimpleControl1" /> <br /><br /> <div style="font-family:tahoma;font-size:x-small;"> <span style="font-size: 14pt"> Composite, resize</span> </div> <aspSample:SimpleCompositeControl2 id="SimpleControl2" height="87px" width="238px" /> <br /><br /> <div style="font-family:tahoma;font-size:x-small;"> <span style="font-size: 14pt"> Container</span> </div> <aspSample:SimpleContainerControl id="SimpleControl3" height="57px"> Type some content here. </aspSample:SimpleContainerControl> <br /><br /> </div> </form> </body> </html>
페이지를 저장합니다.
이제 디자인 뷰에서 페이지를 테스트하여 컨트롤 디자이너의 작동 방식을 확인할 수 있습니다.
컨트롤의 디자인 타임 렌더링을 보려면
페이지의 디자인 뷰로 전환합니다.
컨트롤은 다음 스크린 샷과 같이 표시되어야 합니다. 여기서 두 번째 합성 컨트롤의 크기는 조정할 수 있지만 첫 번째 컨트롤의 크기는 조정할 수 없습니다.
디자인 뷰의 ControlDesigners.aspx 페이지
컨테이너 컨트롤의 내용 영역을 클릭하고 컨트롤에 대한 텍스트 내용을 입력합니다.
소스 뷰로 전환하여 컨테이너 컨트롤의 소스 코드를 찾습니다. 영역 안에 입력한 텍스트가 소스 코드에 표시되는지 확인합니다.
디자인 뷰로 다시 전환합니다.
컨트롤의 프레임을 클릭하고 크기 조정 아이콘 중 하나에 마우스 포인터를 가져간 후 컨테이너 컨트롤의 크기를 조정합니다.
컨트롤의 편집 가능한 영역에서 텍스트 내용 맨 끝을 클릭한 후 Enter 키를 눌러 줄 바꿈을 추가합니다.
도구 상자로부터 Button 컨트롤을 편집 가능한 영역의 입력한 텍스트 아래쪽으로 끌어 옵니다. 도구 상자로부터 Label 컨트롤을 단추 옆으로 끌어 옵니다. 즉, 편집 가능한 영역으로 자식 컨트롤을 끌어 올 수 있습니다. 필요한 경우, 디자인 타임에 자식 컨트롤에 속성을 설정하고, Label 컨트롤의 Text 속성을 런타임에 업데이트하도록 Button 컨트롤에 코드를 추가할 수 있습니다.
컨트롤이 추가된 페이지는 다음 스크린 샷과 같습니다.
자식 컨트롤이 포함된 컨테이너 컨트롤
페이지를 저장합니다.
런타임에 페이지를 보려면
브라우저에서 페이지를 로드합니다.
디자인 뷰에서 사용자 지정한 대로 컨트롤이 표시됩니다. 페이지는 다음 스크린 샷과 같습니다.
완성된 컨트롤 디자이너 웹 페이지
다음 단계
이 연습에서는 합성 또는 컨테이너 컨트롤 디자이너와 연결된 사용자 지정 컨트롤을 만드는 기본적인 작업을 보여 줬습니다. Visual Studio 2005의 디자인 뷰에서 편집 가능한 영역 안에 텍스트를 추가하고 컨트롤의 크기를 조정할 수 있도록 하는 디자이너와 함께 사용자 지정 컨트롤을 만들었습니다. 다음과 같은 추가 설명을 따르는 것이 좋습니다.
컨트롤 디자이너에서 사용할 수 있는 다른 강력한 새 기능을 검토합니다. 자세한 내용은 ASP.NET 컨트롤 디자이너 개요를 참조하십시오.
특수화된 디자인 타임 렌더링을 만들고 작업 목록 같은 기능을 활용하는 고급 수준의 디자이너 시나리오를 만들어 봅니다. 자세한 내용은 작업 목록과 서비스가 있는 샘플 컨트롤 디자이너를 참조하십시오.