Доступ к компоненту формы из другого класса - PullRequest
2 голосов
/ 24 июля 2011

Я надеюсь, что название и этот простой пример говорят обо всем.

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");
    }
}

Когда я пытаюсь изменить lable1 с MyClass , это ничего не делает. Но я могу добраться до UpdateLable метода извне, он говорит: «Привет мне, он просто не меняет метку».

Ответы [ 5 ]

6 голосов
/ 24 июля 2011

Используйте делегата для настройки вашего ярлыка

public class MyClass {
    Action<String> labelSetter;

    public MyClass(Action<String> labelSetter) {
        this.labelSetter = labelSetter;
    }

    public void MyMethod() {
        labelSetter("outside");
    }
}

.

public void buttonOut_Click(object sender, EventArgs e) {
    var outside = new MyClass(UpdateLabel);
    outside.MyMethod();
}
3 голосов
/ 24 июля 2011

Либо используйте способ Яхии (он был обновлен и будет работать правильно), либо попробуйте следующее (возможно, излишнее то, что вы пытаетесь сделать ... что бы это ни было).

ОБНОВЛЕНИЕ:

Исходя из вашего комментария в вопросе, вы также выполняете работу в MyClass в другом потоке.Изменение кода ниже.

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 classes to
    // subscribe to it and do what they like with the message.
    public event Action<string> UpdateLabel;

    public void MyMethod()
    {
        // Raise the UpdateLabel event, passing "Outside" as
        // the message.
        UpdateLabel("Outside");
    }
}
2 голосов
/ 24 июля 2011

немного неуверенно, потому что пример фактически оставляет некоторые биты неясными ... но вот попытка:

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

это работает, пока MyClass НЕ работает в другом потоке - в противном случае вызов UpdataLabel должен быть синхронизирован с потоком пользовательского интерфейса ...

EDIT:

private void buttonOut_Click(object sender, EventArgs e)
{
    MyClass Outside = new MyClass();
    Outside.MyMethod(this);
}
0 голосов
/ 27 ноября 2013

Потратив кучу времени на то, что должно быть простой задачей, и попробовав каждый ответ на переполнение стека, я сказал, что если C # хочет сделать глупым трудным изменить текст простой метки, я собираюсь придуматьс глупым исправлением.

Вот что вы делаете:

  1. В форме 1 или любой другой форме есть метка, которую вы хотите добавить: public void setStatus () {lblStatus.Text= статус;}

    public static string status;
    
  2. Теперь добавьте таймер в Form1 и запустите его "setStatus ();"на каждом тике

  3. Теперь в любом классе просто напишите: Form1.status = "Изменить метку на этот текст";

0 голосов
/ 24 июля 2011

вам нужно сделать метод MyMethod и метку, о которой идет речь, статическими. Но если вы это сделаете, вы не сможете получить доступ к MyMethod через новый экземпляр формы, вместо этого вы должны получить к нему доступ напрямую, как Form1.MyMethod (). Но если вы сделаете ярлык статическим, то Visual Studio сделает его нестатичным, и вы получите доступ к ярлыку от дизайнера, поэтому вам придется продолжать делать его статичным из form1.designer.cs. Также, если вы сделаете метку статической, измените каждую строку, которая ссылается на любое из ее свойств, поэтому, если она говорит this.label1.Text, измените ее на label1.Text. Это должно дать вам желаемый эффект

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...