Пример преобразователя типов

Обновлен: Ноябрь 2007

В этом примере демонстрируется создание преобразователя типов с именем AuthorConverter, используемоговместе с объектом Author из других примеров создания элемента управления. В ASP.NET преобразователи типов используются во время выполнения для сериализации и десериализации объектов, хранящихся в состоянии элемента управления и состоянии просмотра. Приведенный в примере преобразователь типов AuthorConverter преобразует объект Author в представление String, а представление String — в объект Author. Тип Author описан в разделе Пример использования свойств серверного веб-элемента управления.

Связь преобразователя типов с типом (или свойством типа, для которого задан преобразователь) с помощью объекта TypeConverterAttribute. AuthorConverter позволяет элементу управления Book хранить свойство Author в состоянии просмотра. Настраиваемый тип можно хранить в состоянии просмотра только в том случае, если для него задан преобразователь типов, связанный с этим типом.

Класс AuthorConverter является производным от класса ExpandableObjectConverter, поэтому в обозревателе свойств визуального конструктора можно изменять вложенные свойства типа Author, сворачивая и разворачивая их.

Листинг кода для класса 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 в строку и обратно.

  • Переопределите метод CanConvertFrom, определяющий, можно ли создать экземпляр класса Author из конкретного типа. Если переданный аргумент имеет тип String, метод возвращает значение true.

  • Переопределите метод CanConvertTo, определяющий, можно ли преобразовать экземпляр класса Author в конкретный тип. Если переданный аргумент имеет тип String, метод возвращает значение true.

  • Переопределите метод ConvertFrom, возвращающий одну строку, содержащую свойства FirstName, MiddleName и LastName экземпляра класса Author.

  • Переопределите метод ConvertTo, разбирающий строку, в которой объединены свойства FirstName, MiddleName и LastName экземпляра класса Author. Этот метод возвращает новый экземпляр класса Author с данными из объединенной строки.

Построение и использование примера

Скомпилируйте класс AuthorConverter с элементом управления Book и связанными с ним классами, описанными в разделе Пример использования свойств серверного веб-элемента управления.

Дополнительные сведения о компиляции и использовании примеров пользовательских элементов управления см. в разделе Примеры связывания пользовательского серверного элемента управления.

См. также

Основные понятия

Типы значений в системе общих типов CTS

Другие ресурсы

Разработка пользовательских серверных элементов управления ASP.NET