Acessar componente de formulário de outra class

Espero que o título e este exemplo simples digam tudo.

public partial class Form1 : Form { public Form1() { InitializeComponent(); } public void UpdateLabel(string str) { label1.Text = str; MessageBox.Show("Hello"); } private void buttonIn_Click(object sender, EventArgs e) { UpdateLabel("inside"); } private void buttonOut_Click(object sender, EventArgs e) { MyClass Outside = new MyClass(); Outside.MyMethod(); } } public class MyClass { public void MyMethod() { Form1 MyForm1 = new Form1(); MyForm1.UpdateLabel("outside"); } } 

Quando estou tentando mudar o lable1 do MyClass, ele não faz nada. Mas eu posso chegar ao método UpdateLable de fora, ele diz Olá para mim, isso simplesmente não muda o label.

Use um delegado para definir seu label

 public class MyClass { Action labelSetter; public MyClass(Action labelSetter) { this.labelSetter = labelSetter; } public void MyMethod() { labelSetter("outside"); } } 

.

 public void buttonOut_Click(object sender, EventArgs e) { var outside = new MyClass(UpdateLabel); outside.MyMethod(); } 

Ou vá com o caminho de Yahia (ele foi atualizado e funcionará corretamente) ou tente o seguinte (provavelmente um exagero para o que você está tentando fazer … o que quer que seja).

ATUALIZAR:

Com base no seu comentário na pergunta, você também está fazendo o trabalho no MyClass em um tópico diferente. A mudança de código está abaixo.

 public partial class Form1 : Form { // keep a reference to a MyClass object for your Form's lifetime private MyClass _myClass; public Form1() { InitializeComponent(); // Intstantiate your MyClass object so you can use it. _myClass = new MyClass(); // Register to the MyClass event called UpdateLabel. // Anytime MyClass raises the event, your form will respond // by running the UpdateLabelFromMyClass method. _myClass.UpdateLabel += UpdateLabelFromMyClass; } private void button1_Click(object sender, EventArgs e) { // Call MyMethod in your MyClass object. It will raise // the UpdateLabel event. // update, you are calling this on a background thread? _myClass.MyMethod(); } void UpdateLabelFromMyClass(string message) { // Update your label with whatever message is passed in // from the MyClass.UpdateLabel event. // UPDATE: If called from a background thread you'll need this: this.BeginInvoke( (Action) (()=> { label1.Text = message; })); } } public class MyClass { // An event that can be raised, allowing other classs to // subscribe to it and do what they like with the message. public event Action UpdateLabel; public void MyMethod() { // Raise the UpdateLabel event, passing "Outside" as // the message. UpdateLabel("Outside"); } } 

um pouco inseguro porque o exemplo realmente deixa alguns bits incertos … mas aqui está uma tentativa:

 public class MyClass { public void MyMethod(Form1 F) { F.UpdateLabel("outside"); } } 

isso funciona desde que o MyClass NÃO esteja sendo executado em um thread diferente – caso contrário, a chamada para UpdataLabel deve ser sincronizada com o thread da interface do usuário …

EDITAR:

 private void buttonOut_Click(object sender, EventArgs e) { MyClass Outside = new MyClass(); Outside.MyMethod(this); } 

Depois de desperdiçar uma tonelada de tempo no que deveria ser uma tarefa simples e tentar todas as respostas no estouro da pilha, eu disse, se C # quiser tornar estúpido a dificuldade de mudar o texto de um label simples, eu vou criar uma estúpida consertar.

Aqui está o que você faz:

  1. No Form1 ou em qualquer formulário que tenha o label que você deseja adicionar: public void setStatus () {lblStatus.Text = status; }

     public static string status; 
  2. Agora, adicione um timer ao Form1 e execute “setStatus ();” em cada carrapato

  3. Agora, em qualquer class, basta escrever: Form1.status = “Alterar label para este texto”;

você precisa tornar o método MyMethod e o label em questão estáticos. Mas se você fizer isso, você não pode acessar MyMethod através de uma nova instância do formulário em vez disso, você tem que acessá-lo diretamente como Form1.MyMethod (). Mas se você fizer o label, o estúdio visual estático fará com que seja um não-estático, você acessará o label do designer, assim você terá que mantê-lo estático a partir de form1.designer.cs. Além disso, se você fizer o label estático alterar cada linha que se refere a qualquer uma das suas propriedades, se ele diz this.label1.Text alterá-lo para label1.Text. Isso deve lhe dar o efeito desejado