什么是最简单的.NET等效于VB6控件数组?

10

或许我对.NET还不够了解,但我还没有看到一个令人满意的方法来轻松地在.NET中实现这个简单的VB6代码(假设这个代码是在一个带有N个CommandButton数组Command1()和N个TextBox数组Text1()的表单上):

Private Sub Command1_Click(Index As Integer)

   Text1(Index).Text = Timer

End Sub

我知道这不是非常有用的代码,但它演示了在VB6中如何轻松使用控件数组。在C#或VB.NET中最简单的等效方法是什么?


请参阅 http://stackoverflow.com/questions/5497403/control-array-in-vb-net 和 https://dev59.com/l1bTa4cB1Zd3GeqP-m1t。 - MarkJ
也许你可以在未来查看我的想法:https://dev59.com/l1bTa4cB1Zd3GeqP-m1t#42627033,我认为它提供了这个棘手问题的解决方案。 - Federico Navarrete
9个回答

5

创建一个通用的文本框列表:

var textBoxes = new List<TextBox>();

// Create 10 textboxes in the collection
for (int i = 0; i < 10; i++)
{
    var textBox = new TextBox();
    textBox.Text = "Textbox " + i;
    textBoxes.Add(textBox);
}

// Loop through and set new values on textboxes in collection
for (int i = 0; i < textBoxes.Count; i++)
{
    textBoxes[i].Text = "New value " + i;
    // or like this
    var textBox = textBoxes[i];
    textBox.Text = "New val " + i;
}

4

VB .NET 的另一个好处是具有处理多个控件的单个事件处理程序:

Private Sub TextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ 
        Handles TextBox1.TextChanged, _

        TextBox2.TextChanged, _

        TextBox3.TextChanged

End Sub

3
在 .Net 中没有真正的一对一模拟。当然,你可以创建特定类型的控件数组或列表,但没有任何东西会自动为你完成这项工作。
然而,在 .Net 中,我从未见过无法重构成更好的东西的控件数组。就以你的例子为例,在你所发布的场景中,你正在使用控件数组将按钮与文本框配对。在 .Net 中,你可能会使用自定义控件来完成此操作。自定义控件将包含一个按钮、一个文本框,以及可能是共享/静态计时器。表单使用多个此自定义控件的实例。你只需实现一次所需控件的逻辑,并将其隔离到自己的源文件中,该文件可通过源代码控制进行跟踪和编辑,无需合并大型表单类,也可轻松地在多个表单甚至多个项目中重复使用。你也不必担心确保命令按钮索引与文本框索引相匹配。
使用自定义控件而不是控件数组,与使用类来分组数据而不是数组 loosley 相似,因为你可以得到名称而不是索引。

2
有两个方面。
.NET轻松支持控件数组,VB6只能使用解决方法,因为否则动态绑定事件非常困难。在.NET中,动态绑定事件很容易。
但是,.NET表单设计器不支持控件数组,原因很简单:控件数组是在运行时创建/扩展的。如果您在编译时知道需要多少个控件(推理是这样的),那么您会给它们不同的名称并且不将它们放在一个数组中。

我知道这不是非常有用的代码

这正是关键所在。如果一个功能没有用处,为什么要有它呢?
如果需要,您还可以通过名称访问控件,结果可能如下所示:
Private Sub Command_Click(sender As Object, e As EventArgs) Handles Command1.Click, Command2.Click …
    Dim name As String = DirectCast(sender, Control).Name
    Dim index As Integer = Integer.Parse(name.Substring("Command".Length))
    Controls(String.Format("Text {0}", index)).Text = Timer.Value.ToString()
End Sub

当我说“这不是很有用的代码”时,我是在参考我的例子。在VB6中,我发现控件数组非常有用,这就是为什么我提出了这个问题。我认为你提出的解决方案相当聪明,但它似乎有点笨拙。 - raven

1
VisualBasic .NET 的兼容性库包含强类型控件数组。这是升级向导用来替换当前 VB6 控件数组的方法。
然而,VB6 中的控件数组只是一组对象集合,VB6 在表面上进行了一些语法魔法。在 .NET 世界中,通过移除这个功能,它们可以强制执行更好的实践。
最后,随着泛型的出现,没有什么能阻止你使用 VisualBasic .NET。
List<YourControl> MyControlArray.

1
VB6中控制数组的两个主要好处是: (1) 它们提供了一种通过控件集合进行迭代的方式 (2) 它们允许您在控件之间共享事件
(1) 在.Net中可以使用控件数组来实现 (2) 可以通过一个事件处理多个控件来实现(语法略有不同,因为您使用sender参数而不是myArray(index))。
.Net的一个好处是这些功能是解耦的。例如,即使控件不是数组的一部分并且具有不同的名称甚至不同的类型,您也可以拥有共享事件的控件。并且即使它们具有完全不同的事件,您也可以遍历控件集合。

0
创建一个控件数组。
TextBox[] textboxes = new TextBox[] {
    textBox1,
    textBox2,
    textBox3
};

0

在 .Net 中,同一个点击事件可以处理多个按钮的按下操作。然后,您可以将文本框添加到标记属性中以查找?

Private Sub AllButton_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click, Button3.Click
  Dim c As Control = CType(sender, Control)
  Dim t As TextBox = FindControl(CType(c.Tag, String))
  If t Is Not Nothing Then
     t.Text = "Clicked"
  End If
End Sub

0

我知道我的回答有点晚,但我认为我找到了解决方案。我不是唯一一个曾经遇到VS这个限制而苦苦挣扎的VB6开发人员。很久以前,我尝试迁移我设计的一个CRM,但失败了,因为我在一个表单中有数百个控件数组的严重依赖。我阅读了许多论坛,并能够编写出这个简单的代码:

VB.NET:

'To declare the List of controls
Private textBoxes As List(Of TextBox) = New List(Of TextBox)()

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
    'To get all controls in the form
    For Each control In Controls

        'To search for the specific type that you want to create the array 
        If control.[GetType]() = GetType(TextBox) Then
            textBoxes.Add(CType(control, TextBox))
        End If
    Next

    'To sort the labels by the ID
    textBoxes = textBoxes.OrderBy(Function(x) x.Name).ToList()
End Sub

C#:

//To declare the List of controls
private List<TextBox> textBoxes = new List<TextBox>();
private void Form1_Load(object sender, EventArgs e)
{
    //To get all controls in the form
    foreach (var control in Controls)
    {
        //To search for the specific type that you want to create the array 
        if (control.GetType() == typeof(TextBox))
        {
            //To add the control to the List
            textBoxes.Add((TextBox)control);
        }
    }

    //To sort the labels by the ID
    textBoxes = textBoxes.OrderBy(x => x.Name).ToList();
}

有三个要点需要考虑:

  1. List将帮助您模拟大量控件的集合。
  2. typeof(Control)将帮助您定义要添加到列表中的控件类型。
  3. 当您将"index"保留为最后一个字符(textBox1, textBox2, ..., textBoxN)时,您可以创建一个逻辑顺序。

设计模式下的示例:

Many textboxes in one window

运行中:

running example

类似的逻辑可能在其他技术中使用,如WPF、ASP.NET(Web Forms)或Xamarin(Forms)-在我看来。我希望这段代码能够帮助更多的程序员。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接