cheesy
cheesy

Reputation: 99

Can't reference a label created in a method

We just started learning winforms and we have to make a mock GUI. With a contextMenuStrip I can make new labels which look like folders.

private void makeFolder(int x, int y)
{
    Label lbl_folder = new Label();
    lbl_folder.Location = new Point(x, y);
    lbl_folder.Width = 75;
    lbl_folder.Height = 75;
    lbl_folder.BackColor = Color.Transparent;
    lbl_folder.Image = Properties.Resources.folder;
    lbl_folder.Text = "New Folder" + folderindex;
    lbl_folder.TextAlign = ContentAlignment.BottomCenter;

    canvas.Controls.Add(lbl_folder);

    folderindex++;

    lbl_folder.ContextMenuStrip = folderMenuStrip; //so I can use another contextMenuStrip on them
}

With another contextMenuStrip used on these folders, I would like for example to delete the right-clicked folder but I can't reach lbl_folder.

//I would like to do something like this
private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
{
    lbl_folder.Hide();
}

The name lbl_folder doesn't exists in the current context. How can I fix this?

Upvotes: 2

Views: 158

Answers (5)

Enigmativity
Enigmativity

Reputation: 117164

You can also do this inside the makeFolder method:

lbl_folder.Click += (s, e) => lbl_folder.Hide();

I understand that this isn't the event that you're trying to respond to, but it should help you to understand how it can be done.

So your method would look like:

private void makeFolder(int x, int y)
{
    Label lbl_folder = new Label();
    lbl_folder.Location = new Point(x, y);
    lbl_folder.Width = 75;
    lbl_folder.Height = 75;
    lbl_folder.BackColor = Color.Transparent;
    lbl_folder.Image = Properties.Resources.folder;
    lbl_folder.Text = "New Folder" + folderindex;
    lbl_folder.TextAlign = ContentAlignment.BottomCenter;

    lbl_folder.Click += (s, e) => lbl_folder.Hide();

    canvas.Controls.Add(lbl_folder);

    folderindex++;

    lbl_folder.ContextMenuStrip = folderMenuStrip;
}

This works no matter how many time you call this method and how many folder are created.

Upvotes: 0

John Wu
John Wu

Reputation: 52290

You declared lbl_folder in local scope (within a method) so you can only use that variable within it. You have two options:

  1. Declare the variable at form scope. So move the line Label lbl_folder = new Label(); outside of makeFolder.

    private Label lbl_folder = null;
    
    private void makeFolder(int x, int y)
    {
        lbl_folder = new Label();
    
  2. Inside of deleteToolStripMenuItem_Click, retrieve a new reference to the same control, via the form's ControlCollection, e.g.

    var lbl = this.Controls.Find("NameOfControl", true)[0] as Label;
    

    or

    var lbl = this.Controls.Find("NameOfControl", true).OfType<Label>().Single();
    

    ...depending how comfortable you are with LINQ.

    You might also be able to get it from canvas more efficiently, depending how you have canvas scoped.

    var lbl = canvas.Controls.Find("NameOfControl")[0] as Label.
    

Upvotes: 2

Matthew Whited
Matthew Whited

Reputation: 22443

private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
{
    var menuItem = sender as ToolStripMenuItem;
    var menu = menuItem.GetCurrentParent() as ContextMenuStrip;
    var label = menu.SourceControl as Label;

    label.Visible = false;
}

Upvotes: 0

LarsTech
LarsTech

Reputation: 81675

Since you are creating labels dynamically and attaching the context menu to each label, I suspect what you really want is the delete menu item to reference the label you are right clicking.

In that case, you can use the SourceControl of the ContextMenuStrip to provide that:

private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
{
  ((Label)folderMenuStrip.SourceControl).Visible = false;
}

Upvotes: 0

Hussein Salman
Hussein Salman

Reputation: 8256

Its an issue about the scopes of your labels. If they were declared in your makeFolder method they you cannot be accessed from outside the method.

If you don't want to use the FindControls method of the Container. Then, you can keep references to your labels created in a hashtableor dictionary which is declared as instance property in the form itself.

Then, in your makeFolder add the label to it.

lbl_folder.Name = folderindex;
hashtable.Add(lbl_folder.Name, lbl_folder);

From anywhere in the form you can get the label from you hashtable and modify its properties.

Upvotes: 0

Related Questions