C# Can';t引用在方法中创建的标签

C# Can';t引用在方法中创建的标签,c#,winforms,C#,Winforms,我们刚刚开始学习winforms,我们必须制作一个模拟GUI。有了contextMenuStrip,我可以制作看起来像文件夹的新标签 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_f

我们刚刚开始学习winforms,我们必须制作一个模拟GUI。有了contextMenuStrip,我可以制作看起来像文件夹的新标签

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
}
对于这些文件夹使用的另一个contextMenuStrip,例如,我想删除右键单击的文件夹,但我无法访问lbl_文件夹

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

当前上下文中不存在名称lbl_文件夹。如何修复此问题?

您在本地范围(方法内)中声明了
lbl\u文件夹
,因此只能在其中使用该变量。您有两个选择:

  • 在窗体范围内声明变量。因此,移动行
    Label lbl_folder=new Label()
    makeFolder
    之外

    private Label lbl_folder = null;
    
    private void makeFolder(int x, int y)
    {
        lbl_folder = new Label();
    
  • deleteToolStripMenuItem\u单击
    ,通过表单检索对同一控件的新引用,例如


  • 这是关于标签范围的问题。如果它们是在
    makeFolder
    方法中声明的,则无法从方法外部访问它们

    如果不想使用容器的
    FindControls
    方法。然后,可以保留对在
    哈希表
    或字典中创建的标签的引用,该字典在表单本身中声明为实例属性

    然后,在
    makeFolder
    中添加标签

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

    从表单中的任何位置,您都可以从哈希表中获取标签并修改其属性。

    由于您是在动态创建标签并将上下文菜单附加到每个标签上,我怀疑您真正想要的是“删除”菜单项来引用右键单击的标签

    在这种情况下,您可以使用ContextMenuStrip的SourceControl来提供:

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

    您也可以在
    makeFolder
    方法中执行此操作:

    lbl_folder.Click += (s, e) => lbl_folder.Hide();
    
    我知道这不是你试图回应的事件,但它应该帮助你理解如何做到这一点

    因此,您的方法如下所示:

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

    无论您调用此方法多少次以及创建了多少文件夹,此方法都有效。

    声明变量的位置决定了变量的范围。如果在方法中声明它,它只存在于方法中。(控件当然会存在于表单上,但是
    lbl\u文件夹
    仅在方法中引用)为标签命名:
    lbl\u文件夹。name=“lbl\u文件夹”然后您可以通过该键进行引用:
    canvas.Controls[“lbl\u folder”]。Visible=false我的移动问题
    标签lbl_folder=new Label()是指如果它在外部,则不会在每次运行时创建新文件夹
    makeFolder
    。它只是重新创建文件夹,删除前一个而不是放下第二个。@cheesy-将变量的声明移到外部;将
    new
    语句保存在内部。我将编辑答案以向您演示如何操作。
    private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
    {
      ((Label)folderMenuStrip.SourceControl).Visible = false;
    }
    
    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;
    }
    
    lbl_folder.Click += (s, e) => lbl_folder.Hide();
    
    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;
    }