Reputation: 316
I have different Labels on my Form1 and want to change the text of a single Label using the same method.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Class1 change = new Class1();
change.ChangeLabelText();
}
public void ChangeLabel(string msg, Label label)
{
if (label.InvokeRequired)
label.Invoke(new MethodInvoker(delegate { label.Text = msg; }));
else
label.Text = msg;
}
}
how can i pass label1 or label2 as i need?
class Class1
{
public void ChangeLabelText()
{
Form1 frm1 = new Form1();
frm1.ChangeLabel("Surname", label2);
}
}
label2 is underlined of red: NOT EXIST IN THE ACTUAL CONTEST
Upvotes: 0
Views: 4480
Reputation: 39152
Another approach is to make Class1 raise an Event with the Name of the Label and the String to change it to. Your Form will receive the event, find the Label itself, and update the value. This way Class1 never needs a reference to Form1 or any of the Labels. It's still a bad design as you need to know the name of the Label, but this is the direction you went down anyways.
Here's what Class1 would look like:
public class Class1
{
public delegate void dlgChangeLabel(string lblName, string newValue);
public event dlgChangeLabel ChangeLabel;
public void ChangeLabelText()
{
if (ChangeLabel != null)
{
ChangeLabel("label2", "SurName");
}
}
}
Back in Form1, we need to subscribe to the ChangeLabel() event when we create our instance of Class1:
public partial class Form1 : Form
{
private void button1_Click(object sender, EventArgs e)
{
Class1 change = new Class1();
change.ChangeLabel += Change_ChangeLabel;
change.ChangeLabelText();
}
private void Change_ChangeLabel(string lblName, string newValue)
{
// see if we have a Label with the desired name:
Control[] matches = this.Controls.Find(lblName, true);
if (matches.Length > 0 && matches[0] is Label)
{
Label lbl = (Label)matches[0];
ChangeLabel(newValue, lbl); // update it in a thread safe way
}
}
private void ChangeLabel(string msg, Label label)
{
if (label.InvokeRequired)
label.Invoke(new MethodInvoker(delegate { label.Text = msg; }));
else
label.Text = msg;
}
}
Alternate version showing the creation of Class1 and wiring up of its Event during Form Load() so it's not attached to the Button handler:
public partial class Form1 : Form
{
private Class1 change = new Class1();
private void Form1_Load(object sender, EventArgs e)
{
change.ChangeLabel += Change_ChangeLabel;
}
private void Change_ChangeLabel(string lblName, string newValue)
{
Control[] matches = this.Controls.Find(lblName, true);
if (matches.Length > 0 && matches[0] is Label)
{
Label lbl = (Label)matches[0];
ChangeLabel(newValue, lbl);
}
}
private void ChangeLabel(string msg, Label label)
{
if (label.InvokeRequired)
label.Invoke(new MethodInvoker(delegate { label.Text = msg; }));
else
label.Text = msg;
}
}
Now you simply need to raise that event somehow in Class1. Just make sure it has a subscriber (is not null) before you raise it:
// in Class1
private void Foo()
{
if (ChangeLabel != null)
{
ChangeLabel("label2", "SurName");
}
}
Upvotes: 1
Reputation: 539
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Class1 change = new Class1();
change.ChangeLabelText(this);
}
public void ChangeLabel(string msg, Label label)
{
if (label.InvokeRequired)
label.Invoke(new MethodInvoker(delegate { label.Text = msg; }));
else
label.Text = msg;
}
}
class Class1
{
public void ChangeLabelText(System.Windows.Forms.Form form)
{
if(form != null)
{
var labelIdWhoseTextNeedsToChange = "label2"; // Or any dynamic logic to determine which label will have to be updated.
var labelControl = form.Controls.Find(labelIdWhoseTextNeedsToChange, false);
if(labelControl != null)
{
form.ChangeLabel("Surname", labelControl);
}
}
}
}
Upvotes: 1
Reputation: 176
I dont know what is the context in which you are trying to change the label... however I have a few observations seeing your sample code.
First of all, to your question, one of the approaches could be as follows,
private void button1_Click(object sender, EventArgs e)
{
Class1 change = new Class1(this);
change.ChangeLabelText();
}
public void ChangeLabel(string msg, Label label)
{
if (label.InvokeRequired)
label.Invoke(new MethodInvoker(delegate { label.Text = msg; }));
else
label.Text = msg;
}
// dont allow UI elements to be accessed directly from outide
public string Fullname
{
get
{
return label1.Text;
}
set
{
label1.Text = value;
}
}
// dont allow UI elements to be accessed directly from outide
public string Surname
{
get
{
return label2.Text;
}
set
{
label2.Text = value;
}
}
You see that object of Class1 gets reference to the Form1. Inside Class1.ChangeLabelText you may do something like the following,
class Class1
{
Form1 _mainForm;
public Class1(Form1 form)
{
_mainForm = form;
}
public void ChangeLabelText()
{
//Form1 frm1 = new Form1();
//frm1.ChangeLabel("Surname", label2);
_mainForm.Surname = "Surname";
}
}
Observations after seeing your sample
Hope this helps you.
Upvotes: 2
Reputation: 6793
You need to pass label as a parameter in your method
class Class1
{
public void ChangeLabelText(Label lbl)
{
Form1 frm1 = new Form1();
frm1.ChangeLabel("Surname", lbl);
}
}
And in your button click -
change.ChangeLabelText(label2);
Upvotes: 1