How does one access a control from a static method

2020-01-27 08:08发布

I have an application in C# .NET which has a MainForm and a few classes.

One of these classes receives incoming data messages from a network. I need to get these message's text appended into a multi-line textbox on the MainForm.

I can send the message to a method in the MainForm by making the method static, but then the static method cannot access the MainForm's controls.

TheIncomingDataClass.cs

namespace TheApplicationName
{
     class TheIncomingDataClass
     {

     public void IncomingMessage(IncomingMessageType message)
     {
          TheApplicationName.MainForm.ReceiveMSG(message);
     }

MainForm.cs

public static void ReceiveMSG(string message)
{
     txtDisplayMessages.AppendText(message); //This line causes compile error
}

The compile error:

An object reference is required for the nonstatic field, method, or property 'TheApplicationName.MainForm.txtDisplayMessages'

标签: c# .net winforms
10条回答
等我变得足够好
2楼-- · 2020-01-27 08:41

To continue the way you've been doing it, your "TheIncomingDataClass" should have a reference to the MainForm object with which it should interface. When you create an instance of this class (presumably from an instance method of MainForm), you will need to pass in a reference to this MainForm object.

class TheIncomingDataClass{
    MainForm form;

    public TheIncomingDataClass(MainForm form){
        this.form = form;
    }
}

class MainForm : Form{
    MainForm(){
        new TheIncomingDataClass(this);
    }
}

However, as suggested by Bugs, you probably would be better off making this an event on TheIncomingDataClass and subscribing to it from MainForm.

class IncomingMessageEventArgs : EventArgs{
    IncomingMessageType message;

    public IncomingMessageType Message{get{return message;}}

    public IncomingMessageEventArgs(IncomingMessageType message){
        this.message = message;
    }
}

class TheIncomingDataClass{
    public event EventHandler<IncomingMessageEventArgs> MessageReceived;

    protected virtual void OnMessageReceived(IncomingMessageEventArgs e){
        if(MessageReceived != null)
            MessageReceived(this, e);
    }

    public void IncomingMessage(IncomingMessageType message){
        OnMessageReceived(new IncomingMessageEventArgs(message));
    }
}

class MainForm : Form{
    MainForm(){
        new TheIncomingDataClass().MessageReceived +=
            (s, e)=>txtDisplayMessages.AppendText(e.Message.ToString());
    }
}
查看更多
祖国的老花朵
3楼-- · 2020-01-27 08:42

You can solve this problem by removing the static keyword.

When you see "static", think: without an instance of this type.

When you call a non-static method, you must explicitly use some instance. The method can access that instance using the "this" keyword.

When you call a static method, there is no instance - you have abandoned the boundaries of OO and are now in a structural or functional programming context. If you want an instance of something, you need to bring it in as a parameter.

查看更多
在下西门庆
4楼-- · 2020-01-27 08:42

I think you might be taking the wrong approach on this. It sounds like you are trying to push messages to a client from an external process. There are ways to do this, but it will get complicated. My suggestion would be to have the client poll whatever process has the data periodically - maybe every 10 seconds depending on your needs. This is going to be a heck of a lot easier than pushing from server to client.

查看更多
一纸荒年 Trace。
5楼-- · 2020-01-27 08:44

Its possible to pass in a reference to the current form like this:

public static void ReceiveMSG(string message, MainForm mainform)
{
     mainform.txtDisplayMessages.AppendText(message); 
}

Although as suggested an event is probably a better way of doing it.

查看更多
登录 后发表回答