tags:

views:

56

answers:

4

Hi,

I'm doing a stack, I have an input box, every time I input a number that number is inserted into stack, and displayed in a label, I keep adding numbers and labels, then whenever I pop a number, the last created label (representing the stack) needs to disappear and so forth until the stack is empty.

In short, I add a number to the stack, a label is created, I pop a number, the corresponding label disappears.

My problem is that whenever I keep popping numbers, the only labels that disappears is the last one, the other ones do not disappear.

Let's say these are my lables

8 7 6 5 4 3 2 1

I pop 8 7 6 5 ... and the only label that disappear is the last one, number 8

7 6 5 4 3 2 1

Here is the code where I create the labels

            if (token != "+" && token != "-" && token != "*" && token != "/")
            {
                problem.push(Convert.ToDouble(token));

                lstbxStack.Items.Add("Pushed: " + token);
                MessageBox.Show("Pushed: " + token);

                lblPush = new Label();
                lblPush.BorderStyle = BorderStyle.Fixed3D;
                lblPush.Location = new Point(290, labelY);
                lblPush.Name = "lblPush";
                lblPush.Size = new Size(100, 20);
                lblPush.Text = token;
                Controls.Add(lblPush);
                lblPush.BringToFront();

                labelY -= 21;
            }

And here is where I hide the labels

                    operand2 = problem.pop();
                    .
                    .
                    lblPush.Hide();

                    operand1 = problem.pop();
                    .
                    .
                    lblPush.Hide();

This is inside a for loop and switch cases

Thanks

A: 

The problem appears to be that after you pop an element out, lblPush needs to then refer to the label associated with the now top-most item on the stack, so that the next pop operation will then hide the correct label. But I don't observe a reassignment of lblPush following a "pop" operation, so I assume that it in the current code, this variable always refers to the last item pushed onto the stack, rather than to the item on the top of the stack, which is what I think you need.

One way to do this would be to associate the operands with the labels in the stack itself.

For example:

Stack<Tuple<double, Label>> problem = ..

//Push:
double operand = ..
Label label = ..
problem.Push(Tuple.Create(operand, label));

...

//Pop:
var tuple = problem.Pop();
double operand = tuple.Item1;
Label label = tuple.Item2;
label.Hide();

You could of course rely on the order of the labels in the ControlCollection itself instead, but I wouldn't recommend that. Alternatively, you could come up with something more MVC, but for an isolated issue like this, the Tuple solution is fine, IMO.

Ani
A: 

Something like:

Controls.OfType<Label>().Where(...).ToList().ForEach(l => l.Hide());

In the Where, you should have a condition over the name of the label, but for that you need to give each one a specific name.

Johann Blais
A: 

As I can see you just have one label lblPush = new Label(); so you have just one label instance and the results you gain is true, define a Stack of Labels, add labels to their stack and remove them from your control (in push and pop), everything will be ok.

SaeedAlg
A: 

I would recommend maintaining both a stack of numbers and a stack of Label controls, and synchronizing their pushes/pops. Alternately, you could create a class to contain both the number and the label, and just use one stack - that would greatly reduce the amount of code to maintain. Something like so:

public class NumberLabel
{
    public int Number { get; set; }
    public Label Label { get; set; }
}

...

var stack = new Stack<NumberLabel>();
Ben