简体   繁体   中英

Can I use arrays of WinForm controls without VS getting its panties in a twist?

I have a grid of labels. In order to access them in a programmatically sensible manner, I changed them from:

gridLabel1
gridLabel2
...
gridLabelN

To:

gridLabel[0]
gridLabel[1]
...
gridLabel[N-1]

But now the designer is complaining that

The variable 'gridLabel' is either undeclared or was never assigned.

Despite the fact that I also changed this:

private System.Windows.Forms.Label gridLabel1 = new System.Windows.Forms.Label;
private System.Windows.Forms.Label gridLabel2 = new System.Windows.Forms.Label;
...
private System.Windows.Forms.Label gridLabelN = new System.Windows.Forms.Label;

To:

private System.Windows.Forms.Label[] gridLabel = new System.Windows.Forms.Label[N];

What have I missed?

Don't mess around with generated code yourself. The designer.cs file is supposed to be managed by the forms-designer itself, not by the user. In particular, it's easy to test that the designer does not tolerate the procedure you appear to be following:

  1. Declaring a field of an array of controls to the designer file.
  2. Using this field to populate the form's control-collection by modifying the generated InitializeComponent method.

When I do so, I get the same error that you do.

The usual solution for this sort of requirement is to use a programmatic technique to add a number of controls to a parent-control's control-collection. Ideally, create your own user-control that can hold a number of Labels (which it populates programmatically). Then, you can use this control on your form with full designer support.

EDIT :

For example (sketch only, without the user-control), add a FlowLayoutPanel to the form via the designer.

Then change the form's constructor to:

public MyForm()
{
    InitializeComponent();

    var labels = Enumerable.Range(0, 100)
                           .Select(i => new Label { Text = i.ToString() })
                           .ToArray();

    flowLayoutPanel1.Controls.AddRange(labels);
}

Obviously, such a solution may not be appropriate if you don't want the labels organized in a flow-layout.

Create the array of labels after the InitializeComponent call, and populate it with the designer generated instances, like so:

Label[] labels;

MyControl() {
  InitializeComponent();
  labels = new[] { label1, label2, label3 };
}

This will let you keep designer functionality and access them sequentially.

Are you trying to dynamicaly create labels? Or are you trying to access multiple static labels?

For first case, you are left with manual creation and manupulation outside the designer. Just like Ani proposes.

In second case, you can get controls based on name from Form.Controls collection. This name can contain index of the labels. Then you can crete either method or indexer to return specific label based on index.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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