繁体   English   中英

我可以像在 VB 中一样在 C# 中为控件提供索引属性吗?

[英]Can I give controls an index property in C# like in VB?

我之前已经找到了与我的问题类似的答案,但并不完全符合我想要做的......

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

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

有没有办法在 C# 中做到这一点? 我知道有一个.IndexOf() ,但这对我正在做的事情真的有帮助吗? 我想要多个具有相同名称的控件,只是索引不同。 如果我不清楚,请提问,不要投反对票

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

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

我通常做的是将每个有问题的控件放在一个公共父容器中。 Form 本身可以工作,但是如果您需要将它们与其他相同类型的控件区分开来,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();

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

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

您可能需要查看控件的 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");

我从这篇文章中复制了代码

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

        ...

    }  

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM