简体   繁体   English

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

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

I've found similar answers to my question before, but not quite to what I'm trying to do...我之前已经找到了与我的问题类似的答案,但并不完全符合我想要做的......

In Visual Basic (last I used it, in 06/07) there was an "Index" property you could assign to multiple controls with the same name.在 Visual Basic 中(我最后一次使用它,是在 06/07)有一个“索引”属性,您可以将它分配给多个具有相同名称的控件。 I used this primarily to loop through controls, ie:我主要用它来循环控制,即:

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

Is there a way to do this in C#?有没有办法在 C# 中做到这一点? I know there is a .IndexOf() , but would that really help for what I'm doing?我知道有一个.IndexOf() ,但这对我正在做的事情真的有帮助吗? I want to have multiple controls with the same name, just different index.我想要多个具有相同名称的控件,只是索引不同。 If I'm not being clear, please ask, don't downvote .如果我不清楚,请提问,不要投反对票

EDIT: This is a Windows Form Application, and I'm using Visual Studio 2012. I am talking about controls, not arrays/lists;编辑:这是一个Windows窗体应用程序,我使用的Visual Studio 2012年说的控制,而不是数组/列表; this was possible in VB and I was wondering if it was possible at all in C#.这在 VB 中是可能的,我想知道在 C# 中是否可能。 So I want to have, say, 30 seats in a theatre.所以我想在剧院里有 30 个座位。 I want to have each seat represented by a picturebox named "picSeat".我想让每个座位都由一个名为“picSeat”的图片框表示。 VB would let me name several objects the exact same, and would assign a value to a control property "Index". VB 会让我给几个完全相同的对象命名,并为控件属性“索引”分配一个值。 That way, I could use the above loop to print "Hello" in every picture box with only 3 lines of code.这样,我可以使用上面的循环在每个图片框中只用 3 行代码打印“Hello”。

No, this feature does not exist in C#, and was never implemented in the transition from classic VB to VB.Net.不,此功能在 C# 中不存在,并且从未在从经典 VB 到 VB.Net 的过渡中实现。

What I normally do instead is put each of the controls in question in a common parent container.我通常做的是将每个有问题的控件放在一个公共父容器中。 The Form itself can work, but if you need to distinguish these from others of the same type a GroupBox or Panel control will work, too. Form 本身可以工作,但是如果您需要将它们与其他相同类型的控件区分开来,GroupBox 或 Panel 控件也可以工作。 Then, you access the controls like this:然后,您可以像这样访问控件:

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

If you want to use a specific control, just write by name:如果要使用特定控件,只需按名称写入:

pictureBox6.SomeProperty = someValue;

If you need to change a specific control determined at run-time, normally this is in response to a user event:如果您需要更改在运行时确定的特定控件,通常这是为了响应用户事件:

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

If you really really want the Control Arrays feature, you can do it by adding code to create the array to your form's Load event:如果你真的想要的控件数组功能,您可以通过添加代码来创建数组到窗体的Load事件中做到这一点:

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

Are we talking WinForms here?我们在这里谈论的是 WinForms 吗? I'm not sure, but I don't think you can have multiple controls in winforms with same name.我不确定,但我不认为你可以在同名的 winform 中拥有多个控件。 But I vaguely recall doing something similar and the solution was to name them Button_1, Button_2 etc. Then you can iterate through all controls and get your own index.但我依稀记得做过类似的事情,解决方案是将它们命名为 Button_1、Button_2 等。然后您可以遍历所有控件并获得自己的索引。

Beware though that if you want to instanciate a separate control for each seat in a theatre, you might run into some serious performance issues :) I've done something similar to that as well and ended up drawing the whole thing on a canvas and using mouse coordinates to handle the events correctly.但请注意,如果您想为剧院中的每个座位实例化一个单独的控件,您可能会遇到一些严重的性能问题:) 我也做过类似的事情,最终在画布上绘制了整个内容并使用鼠标坐标以正确处理事件。

You may want to check out the Uid property of controls.您可能需要查看控件的 Uid 属性。

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

You can access Control through Uid property with the following您可以使用以下 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;
}

And simply use并简单地使用

var control = FindUid("someUid");

I copied code from this post我从这篇文章中复制了代码

If you create an indexed dictionary of your user control, it will behave pretty much the same as in VB6, though you'll not see it on the VS C# GUI.如果您创建用户控件的索引字典,它的行为将与 VB6 中的几乎相同,尽管您不会在 VS C# GUI 上看到它。 You'll have to get around the placement issues manually.您必须手动解决放置问题。 Still - and most importantly -, you'll be able to refer to any instance by the index.仍然 - 最重要的是 - 您将能够通过索引引用任何实例。

The following example is for 3 pieces for clarity, but of course you could automate every step of the process with appropriate loops.为清楚起见,以下示例分为 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]);
        }

        ...

    }  

I like using Tags to apply any type of meta data about the controls我喜欢使用标签来应用有关控件的任何类型的元数据

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

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

相关问题 使用 LINQ,我可以像在 C# 中那样给 VB.NET 中的“分组”命名吗? - Using LINQ, can I give the "grouping" a name in VB.NET like I can in C#? C#不像我告诉它那样处理控件 - C# Not Disposing controls like I told it to C#winform,是否可以像这样访问GroupBox中的控件:myGroupBox.InnerTextBox.Text“ someText” ;? - C# winform, Can I access Controls Inside a GroupBox like this: myGroupBox.InnerTextBox.Text “someText”;? 我可以在C#MessageBox中添加控件吗? - Can I add controls to the C# MessageBox? 我如何给我的应用程序数据文件夹卡巴斯基像安全一样? - c# How can I give my app data folder Kaspersky like security? C# activeform控件属性 - C# activeform controls property 我可以给Shape或其他对象一个自定义属性,例如“ MyCustomID”吗? - Can I give a Shape or other object a custom property, like “MyCustomID”? 有没有办法像C#一样从Visual Studio 2008的VB中的类中提取接口代码? - Is there a way I can extract an interface code from a class in VB on visual studio 2008 like C# does? 使用C#,如何使用参数访问VB类的默认属性的getter / setter? - Using C#, how can I access the getter/setter of a VB class's default property with parameter? 我怎样才能使c ++中的函数成为C#中的属性? - How can i make that the function in c++ will be like a property in C#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM