1. Trang chủ
  2. » Công Nghệ Thông Tin

Professional ASP.NET 3.5 in C# and Visual Basic Part 130 ppsx

10 223 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 116,74 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Listing 26-38: Creating the templated control’s default template class VB Friend Class DefaultMessageTemplate Implements ITemplate Public Sub InstantiateInByVal container As System.Web.U

Trang 1

[DefaultValue("")]

public string Name

{

get { return _name;}

set { _name = value;}

}

[Bindable(true)]

[DefaultValue("")]

public string Text

{

get { return _text;}

set { _text = value;}

}

public override void DataBind()

{

CreateChildControls();

ChildControlsCreated = true;

base.DataBind();

}

protected override void CreateChildControls()

{

this.Controls.Clear();

_message = new Message(Name,Text);

if (this.MessageTemplate == null) {

this.MessageTemplate = new DefaultMessageTemplate();

} this.MessageTemplate.InstantiateIn(_message);

Controls.Add(_message);

}

protected override void RenderContents(HtmlTextWriter writer)

{

EnsureChildControls();

ChildControlsCreated = true;

base.RenderContents(writer);

}

}

}

To start to dissect this sample, first notice theMessageTemplateproperty This property allows Visual

Studio to understand that the control can contain a template, and allows it to display the IntelliSense

for that template The property has been marked with thePersistanceModeattribute indicating that

the template control should be persisted as an inner property within the control’s tag in the ASPX page Additionally, the property is marked with theTemplateContainerattribute, which helps ASP.NET figure out what type of template control this property represents In this case, it’s the Message template control you created earlier

1251

Trang 2

The container control exposes two public properties, Name and Text These properties are used to

popu-late theNameandTextproperties of the Message control since that class does not allow developers to set

the properties directly

Finally, theCreateChildControlsmethod, called by theDataBindmethod, does most of the heavy

lifting in this control It creates a newMessageobject, passing the values ofNameandTextas constructor

values Once theCreateChildControlsmethod completes, the base DataBind operation comtinues to

execute This is important because that is where the evaluation of the Name and Text properties occurs,

which allows you to insert these properties values into the template control

After the control and template are created, you can drop them onto a test Web page Listing 26-37

shows how the control can be used to customize the display of the data

Listing 26-37: Adding a templated control to a Web page

VB

<%@ Page Language="VB" %>

<%@ Register Assembly="WebControlLibrary1" Namespace="WebControlLibrary1"

TagPrefix="cc1" %>

<script runat="server">

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

Me.TemplatedControl1.DataBind() End Sub

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title>Templated Web Controls</title>

</head>

<body>

<form id="form1" runat="server">

<div>

<cc1:TemplatedControl Name="John Doe" Text="Hello World!"

ID="TemplatedControl1" runat="server">

<MessageTemplate>The user ’<%# Container.Name %>’

has a message for you: <br />"<%#Container.Text%>"

</MessageTemplate>

</cc1:TemplatedControl>

</div>

</form>

</body>

</html>

C#

<script runat="server">

protected void Page_Load(object sender, EventArgs e)

{

this.TemplatedControl1.DataBind();

}

</script>

As you can see in the listing, the<cc1:TemplatedControl>control contains aMessageTemplatewithin

it, which has been customized to display theNameandTextvalues Figure 26-16 shows this page after it

Trang 3

Figure 26-16

One item to consider when creating templated controls is what happens if the developer does not include

a template control inside of the container control In the previous example, if you removed the

Mes-sageTemplate control from the TemplateContainer, a NullReferenceException would occur when you

tried to run your Web page because the container control’s MessageTemplate property would return

a null value In order to prevent this, you can include a default template class as part of the container

control An example of a default template is shown in Listing 26-38

Listing 26-38: Creating the templated control’s default template class

VB

Friend Class DefaultMessageTemplate

Implements ITemplate

Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) _

Implements System.Web.UI.ITemplate.InstantiateIn

Dim l As New Literal()

l.Text="No MessageTemplate was included."

container.Controls.Add(l)

End Sub

End Class

C#

internal sealed class DefaultMessageTemplate : ITemplate

{

public void InstantiateIn(Control container)

{

Literal l = new Literal();

l.Text="No MessageTemplate was included.";

container.Controls.Add(l);

}

}

Notice that the DefaultMessageTemplate implements the ITemplate interface This interface requires that theInstantiateInmethod be implemented, which we use to provide the default template content

To include the default template, simply add the class to theTemplatedControlclass You will also

need to modify theCreateChildControlsmethod to detect the null MessageTemplate and instead create

an instance of and use the default template

1253

Trang 4

If template = Nothing Then

template = New DefaultMessageTemplate()

End If

C#

if (template == null)

{

template = new DefaultMessageTemplate();

}

Creating Control Design-Time Experiences

So far in this chapter, you concentrated primarily on what gets rendered to the client’s browser, but

the browser is not the only consumer of server controls Visual Studio and the developer using a server

control are also consumers, and you need to consider their experiences when using your control

Note that beginning with Visual Studio 2008, the Web Page Design Surface used to provide Web page

designers with a WYSIWYG design experience has been completely rewritten The design-surface, which

in prior versions was derived from the core Internet Explorer rendering engine has been replaced by a

completely independent and new rendering engine This is good news for Web page developers because

they are no longer subject to the quirks of IE rendering If you have existing controls you should be

sure to test them thoroughly on the new design-surface to ensure compatibility From a control design

perspective, all of the previous functionality has been retained Therefore, any controls you have written

to take advantage of design-time tools such as SmartTags or Designer regions should function normally

on the new design surface.

ASP.NET offers numerous improvements in the design-time experience you give to developers using

your control Some of these improvements require no additional coding, such as the WYSIWYG

ren-dering of user controls and basic server controls; but for more complex scenarios, ASP.NET includes a

number of tools that give the developer an outstanding design-time experience

When you write server controls, a priority should be to give the developer a design-time experience

that closely replicates the runtime experience This means altering the appearance of the control on the

design surface in response to changes in control properties and the introduction of other server controls

onto the design surface Three main components are involved in creating the design-time behaviors of a

server control:

❑ Type Converters

❑ UI Type Editors

Because a chapter can be written for each one of these topics, in this section I attempt to give you only

an overview of each, how they tie into a control’s design-time behavior, and some simple examples of

their use

Type Converters

TypeConverteris a class that allows you to perform conversions between one type and another Visual

Studio uses type converters at design time to convert object property values to String types so that they

Trang 5

can be displayed on the Property Browser, and it returns them to their original types when the developer changes the property

ASP.NET includes a wide variety of type converters you can use when creating your control’s design-time behavior These range from converters that allow you to convert most number types, to converters that let you convert Fonts, Colors, DataTimes, and Guids The easiest way to see what type converters are

available to you in the NET Framework is to search for types in the framework that derive from the

TypeConverterclass using the MSDN Library help

After you have found a type converter that you want to use on a control property, mark the property

with aTypeConverterattribute, as shown in Listing 26-39

Listing 26-39: Applying the TypeConverter attribute to a property

VB

<Bindable(True)> _

<Category("Appearance")> _

<DefaultValue("")> _

<TypeConverter(GetType(GuidConverter))> _

Property BookId() As System.Guid

Get

Return _bookid End Get

Set(ByVal Value As System.Guid)

_bookid = Value End Set

End Property

C#

[Bindable(true)]

[Category("Appearance")]

[DefaultValue("")]

[TypeConverter(typeof(GuidConverter))]

public Guid BookId

{

get

{

return _bookid;

}

set

{

_bookid = value;

}

}

In this example, a property is exposed that accepts and returns an object of type Guid The Property

Browser cannot natively display a Guid object, so you convert the value to a string so that it can be

displayed properly in the property browser Marking the property with theTypeConverterattribute

and, in this case, specifying the GuidConverter as the type converter you want to use, allows complex

objects like a Guid to display properly in the Property Browser

1255

Trang 6

Custom Type Converters

It is also possible to create your own custom type converters if none of the in-box converters fit into your

scenario Type converters derive from the System.ComponentModel.TypeConverterclass

Listing 26-40 shows a custom type converter that converts a custom object calledNameto and from

a string

Listing 26-40: Creating a custom type converter

VB

Imports System

Imports System.ComponentModel

Imports System.Globalization

Public Class Name

Private _first As String

Private _last As String

Public Sub New(ByVal first As String, ByVal last As String)

_first = first _last = last End Sub

Public Property First() As String

Get Return _first End Get

Set(ByVal value As String) _first = value

End Set End Property

Public Property Last() As String

Get Return _last End Get

Set(ByVal value As String) _last = value

End Set End Property

End Class

Public Class NameConverter

Inherits TypeConverter

Public Overrides Function CanConvertFrom(ByVal context As _

ITypeDescriptorContext, ByVal sourceType As Type) As Boolean

If (sourceType Is GetType(String)) Then Return True

End If

Return MyBase.CanConvertFrom(context, sourceType) End Function

Trang 7

Public Overrides Function ConvertFrom( _

ByVal context As ITypeDescriptorContext, _

ByVal culture As CultureInfo, ByVal value As Object) As Object

If (value Is GetType(String)) Then

Dim v As String() = (CStr(value).Split(New [Char]() {" "c}))

Return New Name(v(0), v(1))

End If

Return MyBase.ConvertFrom(context, culture, value)

End Function

Public Overrides Function ConvertTo( _

ByVal context As ITypeDescriptorContext, _

ByVal culture As CultureInfo, ByVal value As Object, _

ByVal destinationType As Type) As Object

If (destinationType Is GetType(String)) Then

Return (CType(value, Name).First + " " + (CType(value, Name).Last))

End If

Return MyBase.ConvertTo(context, culture, value, destinationType)

End Function

End Class

C#

using System;

using System.ComponentModel;

using System.Globalization;

public class Name

{

private string _first;

private string _last;

public Name(string first, string last)

{

_first=first;

_last=last;

}

public string First

{

get{ return _first;}

set { _first = value;}

}

public string Last

{

get { return _last;}

set { _last = value;}

}

}

public class NameConverter : TypeConverter

{

public override bool CanConvertFrom(ITypeDescriptorContext context,

Type sourceType) {

1257

Trang 8

if (sourceType == typeof(string)) {

return true;

}

return base.CanConvertFrom(context, sourceType);

}

public override object ConvertFrom(ITypeDescriptorContext context,

CultureInfo culture, object value) {

if (value is string) {

string[] v = ((string)value).Split(new char[] {’ ’});

return new Name(v[0],v[1]);

}

return base.ConvertFrom(context, culture, value);

}

public override object ConvertTo(ITypeDescriptorContext context,

CultureInfo culture, object value, Type destinationType) {

if (destinationType == typeof(string)) {

return ((Name)value).First + " " + ((Name)value).Last;

}

return base.ConvertTo(context, culture, value, destinationType);

}

}

TheNameConverter class overrides three methods, CanConvertFrom, ConvertFrom, and

ConvertTo TheCanConvertFrommethod allows you to control what types the converter can convert

from TheConvertFrommethod converts the string representation back into aName object, and

ConvertToconverts theNameobject into a string representation

After you have built your type converter, you can use it to mark properties in your control with the

TypeConverterattribute, as you saw in Listing 26-35

Control Designers

Controls that live on the Visual Studio design surface depend on control designers to create the design-time

experience for the end user Control designers, for both WinForms and ASP.NET, are classes that derive

from theSystem.ComponentModel.Design.ComponentDesignerclass .NET provides an abstracted

base class specifically for creating ASP.NET control designers called theSystem.Web.UI.Design

.ControlDesigner In order to access these classes you will need to add a reference to the System

.Design.dll assembly to your project

.NET includes a number of in-box control designer classes that you can use when creating a custom

control; but as you develop server controls, you see that NET automatically applies a default designer

The designer it applies is based on the type of control you are creating For instance, when you created

your first TextBox control, Visual Studio used theControlDesignerclass to achieve the WYSIWYG

design-time rendering of the text box If you develop a server control derived from theControlContainer

class, NET automatically use theControlContainerDesignerclass as the designer

Trang 9

You can also explicitly specify the designer you want to use to render your control at design time using theDesignerattribute on your control’s class, as shown in Listing 26-41

Listing 26-41: Adding a Designer attribute to a control class

VB

<DefaultProperty("Text")> _

<ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")> _

<Designer(GetType(System.Web.UI.Design.ControlDesigner))> _

Public Class WebCustomControl1

Inherits System.Web.UI.WebControls.WebControl

C#

[DefaultProperty("Text")]

[ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")]

[Designer(typeof(System.Web.UI.Design.ControlDesigner))]

public class WebCustomControl1 : WebControl

Notice that theDesignerattribute has been added to theWebCustomControl1class You have specified that the control should use theControlDesignerclass as its designer Other in-box designers you could have specified are

❑ CompositeControlDesigner

❑ TemplatedControlDesigner

❑ DataSourceDesigner

Each designer provides a specific design-time behavior for the control, and you can select one that is

appropriate for the type of control you are creating

Design-Time Regions

As you saw earlier, ASP.NET allows you to create server controls that consist of other server controls

and text In ASP.NET 1.0, a server control developer could use theReadWriteControlDesignerclass

to enable the user of the server control to enter text or drop other server controls into a custom server

control at design time An example of this is the ASP.NET Panel control, which enables developers to

add content to the panel at design time

Since ASP.NET 2.0, however, creating a control with this functionality has changed TheReadWrite

ControlDesignerclass was marked as obsolete, and a new and improved way was included to

allow the developer to create server controls that have design-time editable portions The new technique,

called designer regions, is an improvement over theReadWriteControlDesignerin several ways First,

unlike theReadWriteControlDesignerclass, which allowed only a single editable area, designer regions enable you to create multiple, independent regions defined within a single control Second, designer

classes can now respond to events raised by a design region This might be the designer drawing a

control on the design surface or the user clicking an area of the control or entering or exiting a template edit mode

1259

Trang 10

To show how you can use designer regions, create a container control to which you can apply a custom

control designer (as shown in Listing 26-42)

Listing 26-42: Creating a composite control with designer regions

VB

<Designer(GetType(MultiRegionControlDesigner))> _

<ToolboxData("<{0}:MultiRegionControl runat=server width=100%>" & _

"</{0}:MultiRegionControl>")> _

Public Class MultiRegionControl

Inherits CompositeControl

’ Define the templates that represent 2 views on the control

Private _view1 As ITemplate

Private _view2 As ITemplate

’ These properties are inner properties

<PersistenceMode(PersistenceMode.InnerProperty), DefaultValue("")> _

Public Overridable Property View1() As ITemplate

Get Return _view1 End Get

Set(ByVal value As ITemplate) _view1 = value

End Set End Property

<PersistenceMode(PersistenceMode.InnerProperty), DefaultValue("")> _

Public Overridable Property View2() As ITemplate

Get Return _view2 End Get

Set(ByVal value As ITemplate) _view2 = value

End Set End Property

’ The current view on the control; 0= view1, 1=view2, 2=all views

Private _currentView As Int32 = 0

Public Property CurrentView() As Int32

Get Return _currentView End Get

Set(ByVal value As Int32) _currentView = value End Set

End Property

Protected Overrides Sub CreateChildControls()

MyBase.CreateChildControls()

Controls.Clear()

Dim template As ITemplate = View1

Ngày đăng: 05/07/2014, 19:20

TỪ KHÓA LIÊN QUAN