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

时间:2013-11-22 14:58:44

标签: c# winforms controls

之前我的问题找到了类似的答案,但并不完全符合我的目标......

在Visual Basic中(最后我在06/07使用它),有一个“Index”属性,您可以将其分配给具有相同名称的多个控件。我主要使用它来循环控制,即:

For i = 1 to 500
    picSeat(i).Print "Hello"
Next i

有没有办法在C#中执行此操作?我知道有一个.IndexOf(),但这对我正在做的事情有帮助吗?我希望有多个具有相同名称的控件,只是不同的索引。如果我不清楚,请询问,不要downvote

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

5 个答案:

答案 0 :(得分:6)

不,这个功能在C#中不存在,从未在从经典VB到VB.Net的过渡中实现。

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

foreach (var picBox in parentControl.Controls.OfType<PictureBox>())
{
   // do something with each picturebox
}

如果您想使用特定控件,只需按名称编写:

pictureBox6.SomeProperty = someValue;

如果您需要更改在运行时确定的特定控件,通常这是对用户事件的响应:

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)
}

如果你真的真的想要控制阵列功能,你可以通过添加代码来为表单的Load事件创建数组:

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

答案 1 :(得分:0)

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

请注意,如果你想为剧院中的每个座位设置一个单独的控制器,你可能会遇到一些严重的性能问题:)我也做了类似的事情并最终将整个事情画上了画布并使用鼠标坐标来正确处理事件。

答案 2 :(得分:0)

您可能想要查看控件的Uid属性。

http://msdn.microsoft.com/en-us/library/system.windows.uielement.uid(v=vs.110).aspx

您可以使用以下

通过Uid属性访问Control
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;
}

只需使用

即可
var control = FindUid("someUid");

我从this post

复制了代码

答案 3 :(得分:0)

如果创建用户控件的索引字典,则它的行为与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]);
        }

        ...

    }  

答案 4 :(得分:0)

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

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