2011-05-14 33 views
2

我正在构建一个涉及控件层次结构的小问题控制台应用程序 - 有屏幕,并且屏幕内部可以组合控件。你如何迭代对象的成员变量?

您可以通过声明成员变量(全部从AresControl继承)来将控件添加到屏幕上。控件构造函数需要一个简单的坐标对。它看起来像这样:

Public Class IntroScreen : Inherits AresScreen 
    'Controls 
    Private LabelSelect As New LabelControl(72, 0) 
    Private Stats As New StatAreaControl(2, 2) 
    Private Messages As New MessageAreaControl(22, 45) With {.ListeningForKeys = True}  

然后,在onload事件中,你必须对所有这些控件添加到集合,所以我们可以通过他们后来迭代并做渲染等:

Public Sub Screen_Load() Handles MyBase.OnLoad 
    MyBase.Controls.Add(LabelSelect) 
    MyBase.Controls.Add(Stats) 
    MyBase.Controls.Add(Messages) 
End Sub 

我想处理自动将控件添加到基类中的集合。这是我脑子里想的:

  • 使用反射来遍历成员变量
  • 拉,从AresControl
  • 继承者将它们添加到收藏

这将导致更清洁,基于约定的代码。但尽可能地尝试,我不能让它工作 - 我可以走一个类型的成员变量,但我需要走一个活动对象的成员变量。

This is possible,right?

回答

2

您可以使用反射。在基类:

Public Sub DoLoad() 

     Dim controls = Me.GetType.GetFields(BindingFlags.Instance Or BindingFlags.NonPublic) _ 
      .Where(Function(f) f.FieldType.IsSubclassOf(GetType(AresControl))) _ 
      .Select(Function(f) f.GetValue(Me)).Cast(Of AresControl)() 

     For Each c In controls 
      Me.Controls.Add(c) 
     Next 
End Sub 
+0

+1:真棒,这让我的地方,我需要去。我做了一个编辑,而且比我通常会做得更远,希望你不要介意 - 代码需要对GetType的使用进行一些调整,并且一些括号关闭。当我在它的时候,我做到了这一点,所以它可以在基础班上工作。 – 2011-05-14 14:40:02

0

当然 - 将方法添加到该对象以允许你想要什么并隐藏细节。我认为这是封装是你的朋友的地方。