【问题标题】:Inheritance: Cast (Child-)UserControl to the layout of its Base继承:将 (Child-)UserControl 转换为其 Base 的布局
【发布时间】:2014-05-23 13:35:11
【问题描述】:

抱歉,标题有点奇怪。让我概述一下情况:

我有一个名为 TrafficInfraction 的 general usercontrol。 来自该 TrafficInfraction 的 2 个其他用户控件 inherit。让他们称之为超速停车。 De方案如下:

TrafficInfraction
      Speeding (Inherits from TrafficInfraction + Has 2 extra buttons)
      Parking (Inherits from TrafficInfraction + Has 1 extra textbox & 1 extra button)

添加运行时我想将cast Speeding/Parking 用户控件添加到TrafficInfraction 类型的用户控件(在指定的表单上,我不需要额外的控件)。

我知道它可以使用如下的浅拷贝(fIntractionsflowlayoutpanel):

注意currTrafficInfractions 是 TrafficInfraction 的集合 (List Of)。它可以包含从trafficInfraction继承的普通trafficInfraction和用户控件:Speeding,Parking,....(可能进一步派生用户控件)。 currTrafficInfractions 是根据在 base-Control(TrafficInfraction) 上定义的属性填充的。该属性名为“Fine”,为double。将 Fine 大于 100(例如)的所有用户控件添加到列表中。

        For Each infra As TrafficInfraction In currTrafficInfractions
            fInfractions.Controls.Add(infra.Clone())
        Next

但我不想要浅拷贝(因为我显然失去了某些属性:工具提示,...)并且想要对象本身。所以我认为它会像这样工作:

        For Each infra As TrafficInfraction In currTrafficInfractions
            fInfractions.Controls.Add(Ctype(infra,TrafficInfraction))
        Next

        For Each infra As TrafficInfraction In currTrafficInfractions
            fInfractions.Controls.Add(infra)
        Next

但事实证明我错了。布局不会改变(与.Clone 的效果不同)。我仍然看到那些额外的控件。简单地隐藏它们是行不通的。因为在 Speeding & Parking 上控件的位置(继承自 TrafficInfraction)是不同的。

问题:如何将用户控件转换/转换为其基本用户控件的布局。并将其正确显示为TrafficInfraction 给用户(没有在SpeedingParking 中声明的额外控件)?

注意: TrafficInfraction 实现 IClonable 。这可能是.Clone 取得一些成功的原因。

【问题讨论】:

  • 什么是currTrafficInfractions
  • 更新了问题:currTrafficInfractions 是 Trafficinfractions 的集合。
  • 由谁拥有和填补?
  • 显示它的具体类型;什么样的收藏?是List(Of traffics) 还是Microsoft.VisualBasic.Collection
  • 抱歉:它是一个“列表(Of )”。 (很快就会用一些额外的信息更新“注释”!

标签: vb.net inheritance user-controls


【解决方案1】:

铸造 (CType) 和克隆不会改变对象的类型,只会改变对它的引用的类型,这就是为什么您仍然看到子类布局的原因。您必须在基类TrafficInfraction 上创建一个copy constructor(这篇文章是针对C#,但也适用于VB.NET)。

Public Class TrafficInfraction
    Public Sub New(copy As TrafficInfraction)
       Me.SomeProperty = copy.SomeProperty
       Me.OtherProperty = copy.OtherProperty
       etc.
    End Sub
End Class

然后使用它:

For Each infra As TrafficInfraction In currTrafficInfractions
    fInfractions.Controls.Add(new TrafficInfration(infra))
Next

更新

正如 cmets 中所讨论的,这个答案并不完全正确 - 仅在基类上实现的 Clone 将与用于将子类实例复制到新基类实例的复制构造函数一样工作。

【讨论】:

  • 然而 '.Clone' 确实部分起作用。它只拒绝复制/克隆一些基本属性(工具提示,...)。我知道我可以进行深度复制,但我担心它可能会对性能产生影响。
  • @svranken 嗯,我刚刚检查了文档,它看起来不像 UserControlICloneable,那么你的 TrafficInfraction 类上实现了吗?
  • 没错。我忘了在问题中提到这一点。我会尽快添加它(尽管努力+1!)
  • 哦,该死的,我现在看到了解决方案!如果我修改“子”控件中的“克隆”方法,那么我可以达到预期的结果。谢谢你!
  • @svranken 也许我又迷路了! :-) 我认为你想要的只是在基类中实现Clone,以便在子类上调用Clone - 例如aParking.Clone() 将返回一个新的 TrafficInfraction
猜你喜欢
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-15
  • 1970-01-01
  • 2019-12-28
相关资源
最近更新 更多