Как создать форму интерфейса Windows, которая позволяет пользователю выбирать между 3 типами объектов? - PullRequest
0 голосов
/ 04 февраля 2011

Итак, вот идея: базовый класс - Animal, а производные классы - Bird и Dog. У меня есть ComboBox для пользователя, чтобы выбрать, какое животное он хотел бы создать. Как мне объединить и соединить все это вместе на уровне формы (frmAnimal.cs - публичный частичный класс frmAnimal: Form).

В зависимости от этого решения, это также повлияет на другие кнопки в форме, такие как кнопка, которая вызывает .Move (), переопределенный метод Animal, который будет вызывать правильный метод Move () в зависимости от того, является ли Bird или Dog выбран в качестве типа объекта.

Это имеет смысл?

Ответы [ 2 ]

0 голосов
/ 04 февраля 2011

Мой пример на vb.net (я работаю над изучением C #, но пока не «там» - различия не настолько велики, что это не имеет смысла, хотя ...), но суть не удаласьуниверсальный.У вас есть базовый класс Animal и некоторые классы, которые происходят от животных.Определите метод .Move для вашего базового класса.Затем создайте ваши производные классы, которые наследуют методы и открытый интерфейс вашего базового класса.Определите свойство AnimalType, чтобы различать типы на животных.Для этого очень простого примера я использовал Enum.В действительности это может быть Enum, или база данных PK, или другой уникальный идентификатор.Обратите внимание, что на практике я бы, вероятно, НЕ сделал superType Animal членом того же перечисления, что и производные классы.В базе данных я бы, вероятно, сделал производные объекты «дочерними» записями, связанными, например, с «родительской» записью животного):

Public Enum AnimalTypes
    Animal = 1
    Pig = 2
    Human = 3
End Enum

Public Class AnimalBase

    Public Overridable ReadOnly Property AnimalType() As AnimalTypes
        Get
            Return AnimalTypes.Animal
        End Get
    End Property

    Public Sub Move(ByVal X As Integer, ByVal Y As Integer)
        ' . . . You movement code
    End Sub
End Class

Теперь ваши производные классы:

Public Class Pig
    Inherits AnimalBase

    Public Overrides ReadOnly Property AnimalType() As AnimalTypes
        Get
            Return AnimalTypes.Pig
        End Get
    End Property

    'A property spcific to the pig class:
    Public ReadOnly Property PigOnEquality() As String
        Get
            Return "Some pigs are more equal!"
        End Get
    End Property
End Class

Public Class Human
    Inherits AnimalBase

    Public Overrides ReadOnly Property AnimalType() As AnimalTypes
        Get
            Return AnimalTypes.Human
        End Get
    End Property

    'A property specific to the Human class:
    Public ReadOnly Property Shotgun() As String
        Get
            Return "Boom!"
        End Get
    End Property
End Class

Теперь класс AnimalFactory, который запускает экземпляры животных и классов, производных от типа животных, как (еще раз ... типа животных):

Public Class AnimalFactory

    Public Shared Function NewAnimal(ByVal AnimalType As AnimalTypes) As AnimalBase
        Select Case AnimalType
            Case AnimalTypes.Animal
                Return New AnimalBase
            Case AnimalTypes.Pig
                Return New Pig
            Case AnimalTypes.Human
                Return New Human
            Case Else
                Return New AnimalBase
        End Select
    End Function

End Class

Хитрость в том, что производные классы,как возвращено AnimalFacorty, относятся к типу animal, но реализуют все свойства своего истинного типа и, если необходимо, могут быть приведены к их истинному типу.Теперь ваша форма.Ваша форма не обязательно должна заботиться о том, какой тип животного возвращается, если вы используете только общие методы, определенные в базовом классе.Если вам нужен доступ к методу, специфичному для производного класса, вам нужно будет выполнить операцию приведения (которая должна быть такой же (или очень похожей) в C #, как и в VB.net.

Я бросил несколькодействительно глупые примеры в этой форме. Есть также, вероятно, способы избежать Select Case (что, я полагаю, вы бы знали как выражение Switch), но я понятия не имею, что вы делаете с вашим кодом, так что это просто ацедемное упражнение.

 Public Class AnimalFarm ' My hilarious name for the FORM

     'Member variable for the currently selected instance of AnimalBase
     Private SelectedAnimal As AnimalBase

     Private Sub AnimalFarm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

         'Using the enum to populate the comboBox:
         With Me.ComboBox1.Items
             .Add(AnimalTypes.Animal)
             .Add(AnimalTypes.Pig)
             .Add(AnimalTypes.Human)
         End With

     End Sub

     Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
         Dim AnimalType As AnimalTypes = Me.ComboBox1.SelectedItem
         Me.OnNewAnimalSelected(AnimalType)
     End Sub

     Private Sub OnNewAnimalSelected(ByVal AnimalType As AnimalTypes)
         SelectedAnimal = AnimalFactory.NewAnimal(AnimalType)

         'The form doesn't case what type of animal is being instantiated, so long
         'as the methods required are defined on the base class:
         MsgBox(SelectedAnimal.AnimalType.ToString)

         'Move the animal a bit, just for kicks:
         SelectedAnimal.Move(NewX, NewY)

         '  . . . But if you NEED the specific TYPE of animal:

         Select Case SelectedAnimal.AnimalType
             Case AnimalTypes.Human
                 Dim NewHuman As Human = CType(SelectedAnimal, Human)
                 MsgBox(NewHuman.Shotgun)

             Case AnimalTypes.Pig
                 Dim Piggy As Pig = CType(SelectedAnimal, Pig)
                 MsgBox(Piggy.PigOnEquality)
             Case Else
                 MsgBox("This Animal has nothing to say . . .")

         End Select
     End Sub

     Private Sub OnMoveAnimal(ByVal X As Integer, ByVal Y As Integer)
         SelectedAnimal.Move(X, Y)
     End Sub

 End Class
0 голосов
/ 04 февраля 2011

Хотите создать и показать новую форму отдельно от формы выбора?Если это так, вы можете сделать класс формы универсальным, ограниченным объектами типа Animal:

public abstract partial class AnimalFormBase<T>:Form where T:Animal {...}

Затем вы можете извлечь из этой формы для создания форм, специфичных для животных:* Если вам нужна та же форма, но разные элементы управления, я бы сделал вышеупомянутые классы производными от UserControl.Затем, когда пользователь изменил переключатель, вы можете удалить и заменить элемент управления для старого типа животного элементом управления для нового животного.В любом случае, общий предок AnimalFormBase может содержать функциональность, относящуюся к любому животному.Технически он может содержать элементы управления, но я обнаружил, что пользовательское наследование в классах, визуализируемых дизайнером, может запутаться.Затем три производные формы могут использовать базовую функциональность, добавлять свои собственные и размещать элементы управления, которые каждый из них предоставит пользователю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...