C# WindowsForms中与VB6索引控件相当的选项

3

在VB6中,您可以使用索引为控件命名。

例如:cmdStartInterval(1), cmdStartInterval(2), ... .

然后您会有一个类似于这样的方法头:

Private Sub cmdStartInterval_Click(Index As Integer)
...
End Sub

在C#中是否也有类似的方法实现呢?

我猜测你正在使用winforms。你能确认吗? - Oded
VB6在.NET中的等效物始终是WinForms,据我所知它不能用于ASP.NET(在ASP中应该使用VBScript)。 - Abel
可能是以下问题的重复:What's the simplest .NET equivalent of a VB6 control array? - raven
虽然我同意这些问题是相等的,但那个帖子中的答案没有考虑索引或索引事件。 - Abel
2个回答

3
在C#中,您可以将所有按钮分配给一个事件处理程序。
protected void cmdButtons_Click(object sender, System.EventArgs e)

当按钮被点击时,会调用此事件,并通过发送器参数将该按钮的实例传递给此事件。
注(后来添加): 虽然上述方法是解决问题的一种有效方法,如果需要索引本身,则应注意它不是索引控件的等价物,正如标题所示,而是一种替代方法。VB6的索引控件在技术上是数组。因此,在C#中,一个等效的方式是只能通过代码访问而不能通过设计器访问的数组。

这基本上也是在VB6中发生的情况:所有被索引的按钮都自动获得了一个事件处理程序。 - Abel
我为后来的访问者添加了一条小注释,以澄清这个答案的优点和局限性。希望你不介意(你总是可以切换回去)。 - Abel

2

等价于使用控件数组。您将需要手动添加事件中的索引。如果您不需要索引,可以将事件分配给控件。

一个缺点是,无论是C#还是VB.NET:您不能使用设计器创建索引控件,您必须手动创建它们。

好处是:这为您提供了更多自由。

编辑:
这就是它看起来的样子:

// in your Form_Init:

Button [] buttons = new Button[10];    // create the array of button controls

for(int i = 0; i < buttons.Length; i++)
{

    buttons[i].Click += new EventHandler(btn_Click);
    buttons[i].Tag = i;               // Tag is an object, not a string as it was in VB6

    // a step often forgotten: add them to the form
    this.Controls.Add(buttons[i]);    // don't forget to give it a location and visibility
}

// the event:
void btn_Click(object sender, EventArgs e)
{
    // do your thing here, use the Tag as index:
    int index = (int) ((Button)sender).Tag;
    throw new NotImplementedException();
}

注意:如果你使用表单设计器,每个按钮将有自己的名称。如果像另一位用户建议的那样,为它们都使用相同的处理程序(如在VB6中所做的),你将不能轻松地通过索引区分控件,就像你过去常做的那样。为了克服这个问题,只需使用"标记"字段即可。通常最好不要使用名称字段,因为这会创建一个你不想要的依赖关系。


我已经阅读了您编辑过的答案,我认为您是正确的。我标记它为正确答案的原因是,我仍然可以使用有用的IDE,而不是在代码后面编写所有内容。是否有一种方法仍然可以使用IDE +您的“数组方法”? - Rookian
@Rookian:不行,不能直接这样做。微软的建议是使用设计器并为您的按钮命名。创建一个容器(类似于集合组件的数组),在 form_init 中初始化它,如果您编写代码,则它会自动找到您的控件。无论采取什么方法,都不可能再给对象相同的名称,因此无论如何,都需要更多的工作量(尽管看起来很奇怪,但可以提供更多的灵活性)。这里是微软的建议及代码 - Abel
我使用的方法是将事件委托到一个事件中,并编写一个通用的控件查找器类,该类使用命名约定ControlName_ProviderName。我不仅有具有相同含义的按钮控件,还有文本框、组合框等控件。 - Rookian
@Rookian,这是一种非常可怕的方法,编译器无法捕获其中的错误,而且它基本上将Demeter法则推向了无限。微软发明了属性来解决这个问题,它是类型安全的、智能感知的,并且可以在编译时捕获错误。或者使用我之前提到的直接、不完美的标签方法(每个控件都有一个“Tag”属性),但这只比可怕的名称绑定略好一些。 - Abel

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