C# 如何从静态方法访问控件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/952023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:05:44  来源:igfitidea点击:

How does one access a control from a static method?

c#.netwinforms

提问by timmyg

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

我在 C# .NET 中有一个应用程序,它有一个MainForm和几个类。

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.

这些类之一从网络接收传入的数据消息。我需要将这些消息的文本附加到MainForm.

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

我可以MainForm通过将方法设为静态来将消息发送到 中的方法,但是静态方法无法访问MainForm的控件。

TheIncomingDataClass.cs

传入数据类.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'

非静态字段、方法或属性“TheApplicationName.MainForm.txtDisplayMessages”需要对象引用

采纳答案by Annath

A static method doesn't have access to members like txtDisplayMessages because it is not a part of that instance. I suggest you do some reading on the concepts of static methods and whatnot, because that is a fairly language agnostic concept. That method would best be served by removing the static modifier, because it doesn't need to be static - it appears that it would need to be called by that particular instance of that object.

静态方法无权访问像 txtDisplayMessages 这样的成员,因为它不是该实例的一部分。我建议你阅读一些关于静态方法和诸如此类的概念的书,因为这是一个与语言无关的概念。该方法最好通过删除 static 修饰符来提供,因为它不需要是静态的 - 它似乎需要由该对象的特定实例调用。

回答by Bugs

raise an event from class which the form can subscribe to.

从表单可以订阅的类中引发事件。

回答by Bob

Just remove the static modifier, you don't need it for your purposes. Read about statics here.

只需删除静态修饰符,您不需要它来满足您的目的。在此处阅读有关静态的信息

回答by Peter C

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.

尽管正如建议的那样,事件可能是一种更好的方式。

回答by Amy B

You can solve this problem by removing the static keyword.

您可以通过删除 static 关键字来解决此问题。

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.

当您调用非静态方法时,您必须显式使用某个实例。该方法可以使用“this”关键字访问该实例。

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.

当您调用静态方法时,没有实例 - 您已经放弃了面向对象的边界,现在处于结构或函数式编程上下文中。如果你想要一个东西的实例,你需要把它作为参数引入。

回答by Rob

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.

我认为你可能在这方面采取了错误的方法。听起来您正在尝试从外部进程向客户端推送消息。有办法做到这一点,但它会变得复杂。我的建议是让客户端定期轮询任何拥有数据的进程——根据您的需要,可能每 10 秒轮询一次。这将比从服务器推送到客户端要容易得多。

回答by P Daddy

To continue the way you've been doing it, your "TheIncomingDataClass" should have a reference to the MainFormobject 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 MainFormobject.

为了继续你一直在做的事情,你的“ TheIncomingDataClass”应该有一个MainForm对它应该与之交互的对象的引用。当您创建此类的实例时(大概来自 的实例方法MainForm),您将需要传入对此MainForm对象的引用。

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 TheIncomingDataClassand subscribing to it from MainForm.

但是,正如Bugs所建议的那样,您最好将此事件TheIncomingDataClass设为on并从 订阅它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());
    }
}

回答by bobbyalex

Ok here goes. Static methods can access only static members. Your ReceiveMSG method is static. txtDisplayMessages is not and hence you cant access it. Why does your method need to be static? Needless to say, if you remove the static keyword that will fix your problem.

好的,这就去。静态方法只能访问静态成员。您的 ReceiveMSG 方法是静态的。txtDisplayMessages 不是,因此您无法访问它。为什么你的方法需要是静态的?不用说,如果您删除可以解决问题的 static 关键字。

Just make ReceiveMSG part of a class, create an instance of the class and then call the method on the instance.

只需使 ReceiveMSG 成为类的一部分,创建该类的一个实例,然后在该实例上调用该方法。

I think you should post the kind the solution you are expecting.

我认为您应该发布您期望的解决方案。

回答by Jonathan C Dickinson

Seeing as you are new to C# I will keep this as simple as possible. You should have a Program.cs file that has a single method Main (this would have been generated by Visual Studio). You will need to make it look like the following:

鉴于您是 C# 的新手,我会尽可能地保持简单。您应该有一个 Program.cs 文件,其中包含一个 Main 方法(这本来是由 Visual Studio 生成的)。你需要让它看起来像下面这样:

class Program
{
    public static readonly MainForm MainForm;

    static void Main()
    {
        Application.EnableVisualStyles();
        MainForm = new MainForm(); // These two lines
        Application.Run(MainForm); // are the important ones.
    }
}

Now in your incoming message you will have a way to access that form.

现在,在您收到的消息中,您将可以访问该表单。

 public void IncomingMessage(IncomingMessageType message)
 {
      Program.MainForm.RecieveMSG(message);
 }

That method in the form would then be a instance (not static) method. E.g.

表单中的该方法将是一个实例(非静态)方法。例如

 public void RecieveMSG(IncomingMessageType message) // NB: No static
 {
     txtDisplayMessages.Text = message.Text; // Or whatever.
 }

There are better ways to do it - but as a beginner I think this would be the best approach.

有更好的方法可以做到这一点 - 但作为初学者,我认为这将是最好的方法。

The difference between static and instance (instance is when you don't say static) is huge. To get to an instance method, field or property (which are collectively called members in C#) you need to have the containing instance. So:

静态和实例(实例是当你不说静态的时候)之间的区别是巨大的。要访问实例方法、字段或属性(在 C# 中统称为成员),您需要拥有包含实例。所以:

 Person p = new Person(); // You now have an instance.
 p.Name = "Fred"; // You are using an instance property.

Static are the opposite, they are the same anywhere in your application (more technically within the same AppDomain - but if you are a beginner you won't need to worry about that for a while). You don't need an instance to get to them (props to codewidgets "Static methods can access only static members"). For example:

静态则相反,它们在您的应用程序中的任何地方都是相同的(从技术上讲,在同一个 AppDomain 内 - 但如果您是初学者,您暂时无需担心)。您不需要实例来访问它们(代码小部件的道具“静态方法只能访问静态成员”)。例如:

 // Where Planet is a class and People is a static property.
 // Somewhat confusingly the Add method is an instance - best left for the student :).
 Planet.People.Add(new Person("Fred")); 

Hopefully that gives you a good indication of what static and instance is and where to use them. The most important thing though is to try and avoid static members as best as you can - they can cause maintenance nightmares.

希望这能让您很好地了解静态和实例是什么以及在哪里使用它们。但最重要的是尽量避免静态成员——它们可能会导致维护噩梦。

Microsoft has a whole write-upon the important concepts in regard to this.

微软有一个整体的写了对重要概念对于这一点。

回答by ngthna

private void FormMain_Load(object sender, EventArgs e)
{
    TheIncomingDataClass.SetupControl(textBox1);
}

public class TheIncomingDataClass
{
    public static TextBox textbox = new TextBox();
    public static void SetupControl(TextBox txt)
    {
        textbox = txt;
    }
    public void IncomingMessage(string message)
    {
        textbox.Text = message;
    }
}