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.
问题:
回答1:
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.
回答2:
If form1
opens form2
, this is easy. In Form2
, define a property to set the text on the label:
public string TimerText
{
set => _timerLabel.Text = value;
}
You might also need to call _timerLabel.Invalidate();
to force the label to refresh.
Then, when the countdown timer in form1
updates, simply set that property in form2
:
private void Timer_Tick(object sender, EventArgs e)
{
// calculate remaining time
_form2.TimerText = remainingTime.ToString();
}
Here, _form2
is a reference to the Form2
object that form1
is showing.
You could have the property in Form2
be an int
or double
rather than a string
; which you choose may depend on whether you do anything else with the value in Form2
.