C#,删除所有具有相同.Tag的控件

时间:2018-04-13 23:37:22

标签: c# winforms controls

我的问题是,当我比较两个,绝对相同的标签时,它们会变得不同。

代码描述:我创建3个控件(按钮,标签和文本框)并为它们全部分配相同的标签(比如说,0)。当我按下这个新创建的按钮时,我想删除所有具有相同标签的3个控件。

添加按钮的代码(简化):

int Count = 0; // This var changes, but for the example it is 0

Button newButton = new Button();
newButton.Tag = Count;
newButton.Click += new EventHandler(DeleteName);
Controls.Add(newButton);

Label newLabel = new Label();
newLabel.Tag = Count;
Controls.Add(newLabel);

对于TextBox也一样。

删除后面的编码:

private void DeleteName(object sender, EventArgs e)
        {
            List<Control> toDelete = new List<Control>();

            Button btn = sender as Button;

            foreach (Control c in Controls) 
            {
                if (c.Tag == btn.Tag)
                toDelete.Add(c);
            }

            int tmp = toDelete.Count;

            for (int i = 0; i < tmp; i++)
            {
                Controls.Remove(toDelete[i]);
            }
        }

之前我做过相同的逻辑时,它曾经很好地工作,但现在它只是删除按钮而没有其他控件(文本框和标签保持不变)。当我替换&#34; if(c.Tag == btn.Tag)&#34;例如,&#34; if(c是TextBox)&#34;,它将所有TextBox添加到列表中并删除它们,所以我认为问题出在这个Tag的比较中。

1 个答案:

答案 0 :(得分:0)

您遇到此问题的可能原因是Tagobject,因此相等比较会进行参考比较,但您需要将其设置为值类型。即使您将其设置为引用类型,如果它们指向完全相同的对象,则只会返回true

解决此问题的一种方法是将Tag强制转换为适当的类型,或者更常见的是,使用ToString()方法进行比较。我们还应该在检查中添加空条件运算符,以防Tag为空,以避免NullReferenceException

if (c.Tag?.ToString() == btn.Tag?.ToString())

您可能会考虑做的另一件事是创建一个单独的方法来删除具有特定标记的所有控件,另一个方法是以递归方式查找具有该标记的所有控件。如果您处于使用&#34;删除&#34;的某些控件的情况下,这将有所帮助。标记是不同容器的子标记。

例如:

// Returns all controls under the parent with the specified tag
private List<Control> GetTaggedControls(string tag, Control parent)
{
    var taggedControls = new List<Control>();

    foreach (Control control in parent.Controls)
    {
        if (control.Tag?.ToString() == tag)
        {                
            taggedControls.Add(control);
        }

        // Recursively call this method in case this is a container
        taggedControls.AddRange(GetTaggedControls(tag, control));
    }

    return taggedControls;
}

// Deletes all controls with the specified tag
private void DeleteControlsWithTag(string tag)
{
    foreach (Control control in GetTaggedControls(tag, this))
    {
        Controls.Remove(control);
    }
}

例如,如果您将以下代码添加到新的WinForm项目中,则会创建10个标签,每个标签包含Tag "deleteMe"。它还会创建一个按钮,单击该按钮会调用上面的DeleteControlsWithTag方法:

private void Form1_Load(object sender, EventArgs e)
{
    var padSpace = 5;
    var height = 15;

    // Add 10 labels, with a common tag on every other one
    for (int i = 0; i < 10; i++)
    {
        Controls.Add(new Label
        {
            Text = $"Label {i}",
            Top = padSpace * (i + 1) + height * i,
            Height = height,
            Visible = true,
            Tag = i % 2 == 0 ? "deleteMe" : "saveMe"
        });
    }

    // Add a button that will delete controls with deleteMe tag
    var btn = new Button
    {
        Text = "Delete Even Labels",
        Height = 20,
        Width = 150,
        Top = padSpace * 11 + height * 10,
        Visible = true
    };

    btn.Click += (o, ea) => { DeleteControlsWithTag("deleteMe"); };

    Controls.Add(btn);
}