C# 如何跟踪特定元素是否存在?

C# 如何跟踪特定元素是否存在?,c#,winforms,C#,Winforms,我有一个按钮,可以动态创建一个TextBox,它是倒计时计时器的表示,如果(timerLife==0),它会删除该TextBox,还有一个按钮可以删除关联的TextBox。我如何跟踪哪个文本框仍然存在,以便用户可以删除不需要的计时器,并在其位置上添加一个新的计时器 int timerCount = 0; int timerLife = 300; int timerPos = 0; int delBtnPos = 0; public void StartTimer(int count, int

我有一个按钮,可以动态创建一个
TextBox
,它是倒计时计时器的表示,如果(timerLife==0),它会删除该TextBox
,还有一个按钮可以删除关联的TextBox。我如何跟踪哪个文本框仍然存在,以便用户可以删除不需要的计时器,并在其位置上添加一个新的计时器

int timerCount = 0;
int timerLife = 300;
int timerPos = 0;
int delBtnPos = 0;

public void StartTimer(int count, int life, TextBox container)
{
    Timer timer = new Timer
    {
        Tag = "timer" + Convert.ToString(count),
        Interval = 1000
    };

    Button delBtn = new Button()
    {
        Name = "delBtn" + Convert.ToString(timerCount),
        Width = 20,
        Height = 20,
        Text = "X",
        Location = new Point(67, delBtnPos),
    };

    delBtnPos += 24;

    delBtn.Click += (sender, e) =>
    {
        timer.Enabled = false;
        timer.Dispose();
        container.Dispose();
        delBtn.Dispose();
    };

    TimerContainer.Controls.Add(delBtn);

    int timerLife = new int();
    timerLife = life;
    timer.Enabled = true;
    timer.Tick += (sender, e) =>
    {
       if (timerLife > 0)
       {
           container.Text = Convert.ToString(timerLife);
           timerLife--;
       }
       else
       {
           timer.Enabled = false;
           timer.Dispose();
           container.Dispose();

           if (timerCount >= 6)
           {
               timerCount = 0;
               timerPos = 0;
           }
       }
    };
}


StartTimer
在文本框附近添加按钮,可以删除此文本框并启动计时器本身。

private void AddNewTimer_Click(object sender, EventArgs e)
{
    if (!timerExistence[timerCount])
    {
        timerExistance[timerCount] = true;
        TextBox txt = new TextBox()
        {
            Name = "timerBox" + Convert.ToString(timerCount),
            Width = 63,
            Location = new Point(0, timerPos)
        };

        timerPos += 24;
        timerCount++;

        TimerContainer.Controls.Add(txt);
        StartTimer(timerCount, timerLife, txt);
    }
}


AddNewTimer\u Click
是创建初始文本框的按钮的事件处理程序。我想我可以使用一个布尔数组并在数组上迭代检查是否有任何元素是
false
,因此创建一个文本框会将相应的布尔值设置为
true
,并删除为
false
,但这会产生另一个问题:

bool[] timerExistence = { false, false, false, false, false, false };

for (int i = 0; i < timerExistence.Length; i++)
{
    if (!timerExistence[i])
    {
        timerExistence[i] = true;
        TextBox txt = new TextBox()
        {
            Name = "timerBox" + Convert.ToString(i),
            Width = 63,
            Location = new Point(0, timerPos)
        };

            timerPos += 24;

            TimerContainer.Controls.Add(txt);
            StartTimer(timerCount, timerLife, txt);
        }
}

delBtn.Click += (sender, e) =>
    {
        timerExistence[count] = false;
        //...
    };
bool[]timerExistence={false,false,false,false,false};
for(int i=0;i
{
timerExistence[计数]=假;
//...
};


根据调试器,单击第一个按钮时,它会一次创建所有计时器,并按第一个按钮附近的删除按钮以某种方式设置最后一个数组元素。

如果问题或我尝试的解决方案不清楚,请告诉我。

正如我所说,您需要一个结构列表。这类似于节点的链接列表:

public struct Node {
    public Button btn;
    public TextBox txt;
    public IntPtr hwndTxtBox, hwndBtn;
    public int position, timerLife;
}
public List<Node> list = new List<Node>();
现在,您需要一些函数来添加和删除控件:

private int maxCtrls = 6;
private void Add() {
    //Find empty space, pos is basically the free line to add button and textbox
    //each line is seperated by 24 pixels
    int pos = FindPosition();

    if(pos < 0) {
        return; //no space
    }

    TextBox txt = new TextBox() {
        Name = "timerBox" + Convert.ToString( pos ),
        Width = 63,
        Location = new Point( 0, pos * 24 )
    };

    Button delBtn = new Button() {
        Name = "delBtn" + Convert.ToString( pos ),
        Width = 20,
        Height = 20,
        Text = "X",
        Location = new Point( 67, pos * 24 ),
    };

    delBtn.Click += ( sender, e ) =>
    {
        Remove( ( (Button)sender ).Handle );
    };

    TimerContainer.Controls.Add( txt );
    TimerContainer.Controls.Add( delBtn );

    Node node;

    node.btn = delBtn;
    node.txt = txt;
    node.hwndTxtBox = txt.Handle;
    node.hwndBtn = delBtn.Handle;
    node.position = pos;
    node.timerLife = 300;

    list.Add(node);
}

private void Remove(IntPtr hwnd) {
    int i;

    //find element in list to remove
    for( i = 0; i < list.Count; i++ ) {
        if( hwnd == list[ i ].hwndBtn ) {
            //delete button
            list[ i ].txt.Dispose();
            list[ i ].btn.Dispose();
            list.RemoveAt( i );

            return;
        }
    }

}

private int FindPosition() {
    int i, j;
    //check the first position that is empty 0 - (maxCntrs -1) lines
    for( i = 0; i < maxCtrls; i++ ) {
        //run all list
        for( j = 0; j < list.Count; j++ ) {
            if( i == list[ j ].position ) {
                break;
            }
        }

        if(j == list.Count ) { //position is found
            return i;
        }
    }

    return -1; //not found
}

private void timer1_Tick( object sender, EventArgs e ) {
    int i;

    //for all elements in list decrease timerLife. If timerLife is 0 then remove
    for( i = 0; i < list.Count; i++ ) {
        Node node;

        node = list[ i ];

        node.timerLife--;

        list[ i ] = node;

        if( list[ i ].timerLife == 0  ) {
            Remove( list[ i ].hwndBtn );
         }
        else {
            list[ i ].txt.Text = list[ i ].timerLife.ToString();
        }
    }
}

如果我理解正确,我建议使用结构列表。结构应该有文本框句柄、按钮句柄、位置和时间生命。使用一个计时器,对于每个勾号,遍历列表并减少计时器寿命。您还可以检查特定元素的timerLife是否为零,如果为零,您可以处理控件并从列表中删除结构。您可以提供一些代码示例吗?我还不太熟悉结构和列表。@γηράσκωδ'αεπολλάδδασκμε你所说的句柄是什么意思?你可以添加的最大文本框数是多少?位置是固定的吗?@γηρ∑κω′αεπ∑λλ∑δασ∑κμε总共六个框,都固定在
时间容器
面板中。这比我想象的更复杂,也比我自己能够写的更复杂。“我不完全明白,但谢谢你抽出时间,我会尽量把我的心思放在这上面。”盖尔曼相反。这是非常干净和容易。你不明白的部分。
if( list.Count == maxCtrls) {
    return;
}

Add();