我可以像在VB中那样在C#中给控件一个索引属性吗?

我可以像在VB中那样在C#中给控件一个索引属性吗?,c#,winforms,controls,C#,Winforms,Controls,我以前也找到过类似的答案,但不完全是我想做的 在VisualBasic中(我上次使用它是在06/07年),有一个“Index”属性可以分配给多个同名控件。我主要使用它来循环控制,即: For i = 1 to 500 picSeat(i).Print "Hello" Next i 有没有办法在C#中做到这一点?我知道有一个.IndexOf(),但这真的对我的工作有帮助吗?我希望有多个控件具有相同的名称,只是不同的索引。如果我不清楚,请问,不要投反对票 编辑:这是一个Windows窗体应

我以前也找到过类似的答案,但不完全是我想做的

在VisualBasic中(我上次使用它是在06/07年),有一个“Index”属性可以分配给多个同名控件。我主要使用它来循环控制,即:

For i = 1 to 500
    picSeat(i).Print "Hello"
Next i
有没有办法在C#中做到这一点?我知道有一个
.IndexOf()
,但这真的对我的工作有帮助吗?我希望有多个控件具有相同的名称,只是不同的索引。如果我不清楚,请问,不要投反对票


编辑:这是一个Windows窗体应用程序,我正在使用Visual Studio 2012。我说的是控件,而不是数组/列表;这在VB中是可能的,我想知道在C#中是否可能。所以我想要,比如说,剧院里的30个座位。我希望每个座位都有一个名为“picSeat”的图片框。VB允许我对几个对象进行完全相同的命名,并为控件属性“Index”指定一个值。这样,我可以使用上面的循环在每个图片框中打印“Hello”,只需3行代码

我们是在谈论WinForms吗?我不确定,但我认为winforms中不能有多个同名控件。但我隐约记得做过类似的事情,解决方法是将它们命名为Button_1、Button_2等。然后你可以遍历所有控件并获得自己的索引


但要注意,如果您想为剧院中的每个座位实例化一个单独的控件,您可能会遇到一些严重的性能问题:)我也做了类似的事情,最终在画布上绘制了整个过程,并使用鼠标坐标正确处理事件。

您可能需要检查控件的Uid属性

()

您可以通过以下Uid属性访问控件

private static UIElement FindUid(this DependencyObject parent, string uid)
{
    var count = VisualTreeHelper.GetChildrenCount(parent);
    if (count == 0) return null;

    for (int i = 0; i < count; i++)
    {
        var el = VisualTreeHelper.GetChild(parent, i) as UIElement;
        if (el == null) continue;

        if (el.Uid == uid) return el;

        el = el.FindUid(uid);
        if (el != null) return el;
    }
    return null;
}

我从

复制了代码不,这个功能在C#中不存在,并且在从经典VB到VB.Net的转换中从未实现过

我通常做的是将每个有问题的控件放在一个公共父容器中。表单本身可以工作,但是如果需要将它们与其他相同类型的控件区分开来,GroupBox或Panel控件也可以工作。然后,您可以访问如下控件:

foreach (var picBox in parentControl.Controls.OfType<PictureBox>())
{
   // do something with each picturebox
}
如果需要更改运行时确定的特定控件,通常这是对用户事件的响应:

void PictureBox_Click(object sender, EventArgs e)
{
    var picBox = sender As PictureBox;
    if (picBox == null) return;

    //picBox is now whichever box was clicked
    // (assuming you set all your pictureboxes to use this handler)
}
如果确实需要控件数组功能,可以通过向窗体的加载事件添加代码来创建数组:

PictureBox[] pictureBoxes = Me.Controls.OfType<PictureBox>().ToArray();
PictureBox[]pictureBoxes=Me.Controls.OfType().ToArray();

如果创建用户控件的索引字典,它的行为与VB6中的行为几乎相同,尽管在VS C#GUI上看不到它。你必须手动解决安置问题。不过,最重要的是,您可以通过索引引用任何实例

为了清晰起见,下面的示例是针对3个部分的,但当然,您可以使用适当的循环自动执行流程的每个步骤

public partial class Form1 : Form
    {
    ...

        Dictionary<int, UserControl1> NameOfUserControlInstance = new Dictionary<int, UserControl1>()
        {
            { 1, new UserControl1 {}},
            { 2, new UserControl1 {}},
            { 3, new UserControl1 {}}
        };

        private void Form1_Load(object sender, EventArgs e)
        {

            NameOfUserControlInstance[1].Location = new System.Drawing.Point(0, 0);
            NameOfUserControlInstance[2].Location = new System.Drawing.Point(200, 0);
            NameOfUserControlInstance[3].Location = new System.Drawing.Point(400, 0);

            Controls.Add(NameOfUserControlInstance[1]);
            Controls.Add(NameOfUserControlInstance[2]);
            Controls.Add(NameOfUserControlInstance[3]);
        }

        ...

    }  
公共部分类表单1:表单
{
...
字典名称OfUserControlInstance=新字典()
{
{1,新的UserControl1{},
{2,新用户控制1{},
{3,新用户控制1{}
};
私有void Form1\u加载(对象发送方、事件参数e)
{
NameOfUserControlInstance[1]。位置=新系统。绘图。点(0,0);
NameOfUserControlInstance[2]。位置=新系统。绘图。点(200,0);
NameOfUserControlInstance[3]。位置=新系统。绘图。点(400,0);
Add(NameOfUserControlInstance[1]);
Add(NameOfUserControlInstance[2]);
Add(NameOfUserControlInstance[3]);
}
...
}  

我喜欢使用标签来应用关于控件的任何类型的元数据

for (int i = 0; i< 10; ++i)
{
  Button button = new Button();
  button.Tag = i;
}
for(int i=0;i<10;++i)
{
按钮按钮=新按钮();
标签=i;
}

您在谈论收藏吗<代码>变量pics=新列表()。。。var picOne=pics[0](注意C#中的括号而不是VB中的括号)控件必须具有唯一的名称。有些控件的属性是集合,您有时(实际上大部分时间)可以通过索引访问这些集合。但我甚至不确定我们在这里谈论的是控件……你是在谈论变量(数组?)@TimSchmelter我想是的,我记得在VB6中,你可以创建多个,比如说,具有相同名称的按钮,然后共享一个事件处理程序以及调用它的按钮的索引。我不知道你是否可以在.NET中再这样做。它是什么功能,我已经使用VB.NET 12年了,但我从未使用过这样的“索引属性”?它被称为控件数组,是VB6和更早版本的一部分。它们从未在VB.net中实现过(在我看来,这是件好事。我希望它们在默认表单实例中也能如此智能)。谢谢,Joel。我真的希望这是可能的,这将使我的作业更容易:P.如果我要使用你的其他建议,我有两个问题:1)如果我使用处理程序,我如何区分所选的每个框(发件人<代码>中包含的内容?)或者2)如何组织数组以控制哪个picBox获取数组中的哪个索引?@Daevin
sender
是启动事件的框。单击一个框,该框将成为发件人。它的索引将是无关的。我保证。对于(2),可以使用OrderBy()。。。但我想当你深入研究这个问题时,你会发现你不需要,或者,至少,如果你正在构建剧院座位的网格,为每个座位编写一行代码,在二维数组中为其指定一个特定的位置可能更合适。@Joel Coehoorn好的,谢谢。因此,使用您的处理程序,我可以将
var picBox=sneder设置为PictureBox
,然后执行
picBox.Name
,它将返回正确的
public partial class Form1 : Form
    {
    ...

        Dictionary<int, UserControl1> NameOfUserControlInstance = new Dictionary<int, UserControl1>()
        {
            { 1, new UserControl1 {}},
            { 2, new UserControl1 {}},
            { 3, new UserControl1 {}}
        };

        private void Form1_Load(object sender, EventArgs e)
        {

            NameOfUserControlInstance[1].Location = new System.Drawing.Point(0, 0);
            NameOfUserControlInstance[2].Location = new System.Drawing.Point(200, 0);
            NameOfUserControlInstance[3].Location = new System.Drawing.Point(400, 0);

            Controls.Add(NameOfUserControlInstance[1]);
            Controls.Add(NameOfUserControlInstance[2]);
            Controls.Add(NameOfUserControlInstance[3]);
        }

        ...

    }  
for (int i = 0; i< 10; ++i)
{
  Button button = new Button();
  button.Tag = i;
}