首页 文章

如何创建允许用户在3种对象类型之间进行选择的Windows界面表单?

提问于
浏览
0

所以这就是想法 - 基类是Animal,派生类是Bird和Dog . 我有一个ComboBox供用户选择他们想要创建的动物 . 如何在表单级别(frmAnimal.cs - 公共部分类frmAnimal:表单)中合并并连接所有这些内容 .

根据这个决定,它还会影响表单上的其他按钮,例如调用.Move()的按钮,一个重写的Animal方法,它将调用正确的Move()方法,具体取决于是选择Bird还是Dog作为对象类型 .

那有意义吗?

2 回答

  • 0

    您是否要创建并显示与选择表单分开的新表单?如果是这样,您可以使表单类通用,仅限于Animal类型的对象:

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

    然后,您可以从该表单派生以创建特定于动物的表单:

    public partial class AnimalForm:AnimalFormBase<Animal> {...}
    public partial class BirdForm:AnimalFormBase<Bird> {...}
    public partial class DogForm:AnimalFormBase<Dog> {...}
    

    如果你想要相同的形式但不同的控件,我会使上述类派生自UserControl . 然后,当用户更改单选按钮时,您可以删除旧动物类型的控件并将其替换为新动物的控件 . 无论哪种方式,通用祖先AnimalFormBase都可以保存与任何Animal相关的功能 . 它可以在技术上包含控件,但我发现设计器渲染类中的自定义继承可能会变得混乱 . 然后,三个派生形式可以使用基本功能,添加它们自己的,并布置每个将呈现给用户的控件 .

  • 0

    我的例子是在vb.net(我正在学习C#,但不是“那里” - 差异不是很大,以至于这没有意义,尽管......),但要点是失败的普遍性 . 你有一个基类Animal,还有一些派生自动物的类 . 在基类上定义.Move方法 . 然后创建派生类,继承基类的方法和公共接口 . 定义AnimalType属性以区分动物类型 . 对于这个非常简单的例子,我使用了一个Enum . 实际上,这可能是Enum,也可能是数据库PK或其他唯一标识符 . 请注意,在实践中,我可能不会使superType Animal成为与派生类相同枚举的成员 . 在DataBase中,我可能会将派生对象“子”记录与“父”动物记录相关联,例如:

    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返回的派生类是动物类型,但实现了所有类型的真实类型,如果需要,可以转换为它们的真实类型 . 现在,你的表格 . 如果您只访问基类上定义的常用方法,那么您的表单无需关心返回哪种类型的动物 . 如果需要访问特定于派生类的方法,则需要执行转换操作(在VB#中与C#中的操作相同(或非常相似)) .

    我在这种形式中抛出了一些非常愚蠢的例子 . 还有一些方法可以避免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
    

相关问题