型コンバータの例
更新 : 2007 年 11 月
この例では、他のコントロールの作成例の Author オブジェクトと共に使用する AuthorConverter という型コンバータを作成する方法を示します。ASP.NET は、実行時に型コンバータを使用してコントロールの状態とビューステートに格納されているオブジェクトのシリアル化および逆シリアル化を行います。AuthorConverter の例は、Author オブジェクトを String に変換し、String の表現を Author オブジェクトに変換します。Author 型については、「サーバー コントロールのプロパティの例」を参照してください。
型コンバータは、TypeConverterAttribute を使用して型 (またはコンバータが定義されている型のプロパティ) に関連付けます。AuthorConverter によって、Book コントロールは Author プロパティをビューステートに格納できます。カスタム型は、専用の型コンバータが定義されて関連付けられている場合のみビューステートに格納できます。
AuthorConverter クラスは、ビジュアル デザイナのプロパティ ブラウザで、Author 型のサブプロパティを編集するための展開/折りたたみのユーザー インターフェイスを提供するために ExpandableObjectConverter から派生します。
AuthorConverter クラスのコード リスト
' AuthorConverter.vb
Imports System
Imports System.ComponentModel
Imports System.ComponentModel.Design.Serialization
Imports System.Globalization
Imports System.Reflection
Namespace Samples.AspNet.VB.Controls
Public Class AuthorConverter
Inherits ExpandableObjectConverter
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
Public Overrides Function CanConvertTo( _
ByVal context As ITypeDescriptorContext, _
ByVal destinationType As Type) As Boolean
If destinationType Is GetType(String) Then
Return True
End If
Return MyBase.CanConvertTo(context, destinationType)
End Function
Public Overrides Function ConvertFrom( _
ByVal context As ITypeDescriptorContext, _
ByVal culture As CultureInfo, ByVal value As Object) As Object
If value Is Nothing Then
Return New Author()
End If
If (TypeOf value Is String) Then
Dim s As String = CStr(value)
If s.Length = 0 Then
Return New Author()
End If
Dim parts() As String = s.Split(" ".ToCharArray)
' Determine if name is stored as first and last,
' first, middle, and last,
' or is in error.
If (parts.Length < 2) Or (parts.Length > 3) Then
Throw New ArgumentException( _
"Name must have 2 or 3 parts.", "value")
End If
If parts.Length = 2 Then
Return New Author(parts(0), parts(1))
End If
If parts.Length = 3 Then
Return New Author(parts(0), parts(1), parts(2))
End If
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 value IsNot Nothing Then
If Not (TypeOf value Is Author) Then
Throw New ArgumentException("Invalid Author", _
"value")
End If
End If
If destinationType Is GetType(String) Then
If value Is Nothing Then
Return String.Empty
End If
Dim auth As Author = CType(value, Author)
If auth.MiddleName <> String.Empty Then
Return String.Format("{0} {1} {2}", _
auth.FirstName, _
auth.MiddleName, _
auth.LastName)
Else
Return String.Format("{0} {1}", _
auth.FirstName, _
auth.LastName)
End If
End If
Return MyBase.ConvertTo(context, culture, value, _
destinationType)
End Function
End Class
End Namespace
// AuthorConverter.cs
using System;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Globalization;
using System.Reflection;
namespace Samples.AspNet.CS.Controls
{
public class AuthorConverter : ExpandableObjectConverter
{
public override bool CanConvertFrom(
ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(
ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext
context, CultureInfo culture, object value)
{
if (value == null)
{
return new Author();
}
if (value is string)
{
string s = (string)value;
if (s.Length == 0)
{
return new Author();
}
string[] parts = s.Split(' ');
// Determine if name is stored as first and
// last; first, middle, and last;
// or is in error.
if ((parts.Length < 2) || (parts.Length > 3))
{
throw new ArgumentException(
"Name must have 2 or 3 parts.", "value");
}
if (parts.Length == 2)
{
return new Author(parts[0], parts[1]);
}
if (parts.Length == 3)
{
return new Author(parts[0], parts[1], parts[2]);
}
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(
ITypeDescriptorContext context,
CultureInfo culture, object value, Type destinationType)
{
if (value != null)
{
if (!(value is Author))
{
throw new ArgumentException(
"Invalid Author", "value");
}
}
if (destinationType == typeof(string))
{
if (value == null)
{
return String.Empty;
}
Author auth = (Author)value;
if (auth.MiddleName != String.Empty)
{
return String.Format("{0} {1} {2}",
auth.FirstName,
auth.MiddleName,
auth.LastName);
}
else
{
return String.Format("{0} {1}",
auth.FirstName,
auth.LastName);
}
}
return base.ConvertTo(context, culture, value,
destinationType);
}
}
}
コードの説明
AuthorConverter クラスの実装は、Author のインスタンスを文字列に変換し、その逆の変換を行うための次のタスクを実行する必要があります。
Author インスタンスを特定の型から作成できるかどうかを判定する CanConvertFrom メソッドをオーバーライドします。このメソッドは、渡された型が String 型の場合に true を返します。
Author インスタンスを特定の型に変換できるかどうかを判定する CanConvertTo メソッドをオーバーライドします。このメソッドは、渡された型が String 型の場合に true を返します。
Author インスタンスの FirstName、MiddleName、および LastName の各プロパティを含む単一の文字列を返す ConvertFrom メソッドをオーバーライドします。
Author インスタンスの FirstName、MiddleName、および LastName の各プロパティを連結した文字列を解析する ConvertTo メソッドをオーバーライドします。このメソッドは、連結した文字列からのデータを含む Author クラスの新しいインスタンスを返します。
例のビルドと使用
「サーバー コントロールのプロパティの例」に説明されている Book コントロールおよびそれに関連するクラスと共に AuthorConverter クラスをコンパイルします。
カスタム コントロールの例のコンパイルと使用については、「カスタム サーバー コントロールの例のビルド」を参照してください。