Использование многих классов в GUI, которые наследуются от базы - PullRequest
0 голосов
/ 20 октября 2010

У меня есть настройки классов, подобные этой:

<DataContract()> _
Public MustInherit Class SystemTaskProcessBase

    Public MustOverride ReadOnly Property Name() As String
    Public MustOverride ReadOnly Property Description() As String

    Public MustOverride Property Result() As SystemTaskResult

    <DataMember()> _
    Private _TaskID As Integer = 0
    Public Property TaskID() As Integer
        Get
            Return _TaskID
        End Get
        Set(ByVal value As Integer)
            _TaskID = value
        End Set
    End Property

End Class

<DataContract()> _
Public Class RebootSystemTaskProcess
    Inherits SystemTaskProcessBase

    Private _Name As String = "Reboot System"
    Public Overrides ReadOnly Property Name() As String
        Get
            Return _Name
        End Get
    End Property

    Private _Description As String = "Task for the client to reboot itself internally."
    Public Overrides ReadOnly Property Description() As String
        Get
            Return _Description
        End Get
    End Property

    <DataMember()> _
    Public _Result As SystemTaskResult = SystemTaskResult.NotProcessed
    Public Overrides Property Result() As SystemTaskResult
        Get
            Return _Result
        End Get
        Set(ByVal value As SystemTaskResult)
            _Result = value
        End Set
    End Property

End Class

<DataContract()> _
Public Class DeleteFileSystemTaskProcess
    Inherits SystemTaskProcessBase

    Private _Name As String = "Delete File"
    Public Overrides ReadOnly Property Name() As String
        Get
            Return _Name
        End Get
    End Property

    Private _Description As String = "Task for the client to delete a local file."
    Public Overrides ReadOnly Property Description() As String
        Get
            Return _Description
        End Get
    End Property

    <DataMember()> _
    Public _Result As SystemTaskResult = SystemTaskResult.NotProcessed
    Public Overrides Property Result() As SystemTaskResult
        Get
            Return _Result
        End Get
        Set(ByVal value As SystemTaskResult)
            _Result = value
        End Set
    End Property

    <DataMember()> _
    Private _File As FileInfo
    Public Property File() As FileInfo
        Get
            Return _File
        End Get
        Set(ByVal value As FileInfo)
            _File = value
        End Set
    End Property

End Class

Мне нужно использовать эти классы в клиентской системе, но я также должен иметь возможность создавать эти "задачи" через интерфейс управления.Каждый класс (Task), который наследует основу, может иметь свои собственные свойства, которые являются уникальными для каждого класса, но в то же время совместно использовать одни и те же общие свойства базового класса.Например, приведенное выше показывает задачу перезагрузки и задачу удаления файла, задача удаления файла должна знать, какой файл удалить, поэтому имеет свойство для этого.Но задача перезагрузки не нуждается в этом свойстве.Поэтому, когда приложение управления создает эти задачи, оно не должно предоставлять текстовое поле для свойства файла для задачи перезагрузки.Позже может быть создано больше задач с совершенно другими свойствами.

Как бы я предоставил приложению управления WinForms способ перечисления каждого класса в ListView, например, и позволить пользователю создавать этиЗадачи и заполнение динамических свойств, которые будет иметь каждый класс?

Желаемой функциональностью будет создание формы задачи, которая создает динамические элементы управления, доступные для свойств по мере необходимости, в зависимости от открытых свойств в каждом классе, но вв то же время доступны свойства базового класса.

Любые идеи приветствуются.

Спасибо, Скотт

1 Ответ

0 голосов
/ 20 октября 2010

Если вам нужно настраиваемое и расширяемое решение, то одним из способов сделать это будет подход, основанный на дате.В одной из моих предыдущих работ мы должны были создать динамический пользовательский интерфейс, основанный на предпочтениях клиента, где поле 1 было применимо к одному клиенту, но другое не требовалось.Расширяя этот подход к вашему вопросу, вам понадобятся таблицы БД

TasksTable with following columns
1.TaskId
2.TaskName
3.ClassName  (you will use reflection to create an instance of it)

Другая таблица с фактическими полями для задач.Давайте пока назовем это TaskFields.

TaskFields Table 
1. TaskFieldId
2. Property   (You can create another field to store the Name if you need to)
3. Enabled (bit)
4. SpecialFormat   <if you need to apply this and customize it based on some preference)

Это довольно маленькие таблицы.Загрузите их при запуске приложения.В вашем приложении свяжите свой ListBox с полем TaskName в TasksTable.Когда выбран конкретный элемент, динамически создавайте элементы управления на основе значений в таблице TaskFields для выбранного элемента.Создайте класс на основе поля ClassName и свяжите привязки создания с сгенерированными элементами управления.

Это сложно, но преимущество, которое вы получаете, заключается в том, что вы можете включить или выключить элементы управления для отображения.

РЕДАКТИРОВАТЬ: Если вы планируете использовать подход атрибутов, может быть полезно следующее.Исходя из ваших примеров, вы уже отмечаете нужные свойства как Datamember.Поэтому вам не нужно определять какой-либо пользовательский атрибут, если только у вас нет других свойств, которые не будут использоваться для пользовательского ввода, но сами помечены как DataMember для других целей.

Dim type As Type = GetType(yourClass)
Dim properties As PropertyInfo() = type.GetProperties()
Dim neededProperties = (From [property] In propertiesLet attributes = DirectCast([property].GetCustomAttributes(GetType(DataMemberAttribute), False), Attribute()) Where attributes.Count() > 0[property]).ToList()
...