Search code examples
c#winformstimerlabel

How to link 2 labels in 2 different forms


I have a timer running on form 1 with a label called "timenumber" showing the time, i also have a second form that has a label "timer". How do i link these in a way that they both so the same value at the same time. Form 1 is used as a controller and the form 2 is the one that is displayed in another monitor.


Solution

  • Option 1
    Pass a reference to the Count Down Label in Form1 to Form2 using its constructor, then use this reference to subscribe to the Label's TextChanged event:

    In Form1:

    private int CountDown = 100;
    
    private void button1_Click(object sender, EventArgs e)
    {
        Form2 form2 = new Form2(this.[The Counter Label]);
        form2.Show();
        this.timer1.Enabled = true;
    }
    
    private void timer1_Tick(object sender, EventArgs e)
    {
        this.[The Counter Label].Text = CountDown.ToString();
        if (CountDown == 0)
            this.timer1.Enabled = false;
        CountDown -= 1;
    }
    

    In Form2:

    public form2() : this(null) { }
    
    public form2(Control timerCtl)
    {
        InitializeComponent();
        if (timerCtl != null) {
            timerCtl.TextChanged += (s, evt) => { this.[Some Label].Text = timerCtl.Text; };
        }
    }
    

    Option 2
    Use a Public Property of Form2 that can be set to a Control reference. Set this property in Form1 right after a new instance of Form2 has beed created.
    This, however, implies that Form1 needs to know about this property in Form2:

    In Form1:

    private int CountDown = 100;
    
    private void button1_Click(object sender, EventArgs e)
    {
        Form2 form2 = new Form2();
        form2.Show();
        form2.CountDownControl = this.[The Counter Label];
        this.timer1.Enabled = true;
    }
    
    private void timer1_Tick(object sender, EventArgs e)
    {
        this.[The Counter Label].Text = CountDown.ToString();
        if (CountDown == 0)
            this.timer1.Enabled = false;
        CountDown -= 1;
    }
    

    In Form2:

    private Control timerCtl = null;
    
    public Control CountDownControl {
        set { this.timerCtl = value;
            if (value != null) {
                this.timerCtl.TextChanged += (s, evt) => { this.[Some Label].Text = timerCtl.Text; };
            }
        }
    }
    

    Many other options exist.

    You could also use a Public Property in Form2 and set this property directly from the Timer.Tick event. The public property, as in the second example, could set the Text property of one of its controls to the value of the property.
    I don't like this option very much, nonetheless it's available.

    In Form1:

    private int CountDown = 100;
    
    private void button1_Click(object sender, EventArgs e)
    {
        Form2 form2 = new Form2();
        form2.Show();
        this.timer1.Enabled = true;
    }
    
    private void timer1_Tick(object sender, EventArgs e)
    {
        this.[The Counter Label].Text = CountDown.ToString();
        form2?.CountDownValue = CountDown;
        if (CountDown == 0)
            this.timer1.Enabled = false;
        CountDown -= 1;
    }
    

    In Form2:

    public int CountDownValue {
        set { this.[Some Label].Text = value.ToString(); }
        }
    }
    

    You could also have a custom event in Form1 that Form2 could subscribe, or implement INotifyPropertyChange. But this is, give or take, the same thing as Option1.