[英]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");
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.