【问题标题】:How to call method in other class from a static class如何从静态类调用其他类中的方法
【发布时间】:2019-12-15 23:14:14
【问题描述】:

我对 OOP 完全没有经验。我是大学一年级,我的实习项目要求我使用 C# 进行表单应用程序。

我有两个类,一个表单类 Form 和一个静态类“Port_Com”,我在其中编写了与 Raspberry 通信的函数。

这是我想从第二堂课中调用的方法:


public partial class Form1 : Form
{
    {...}
    public void WriteLine(string message)
        {
            this.richTextBox1.AppendText(Environment.NewLine + ">" + message);
        }
}

我的第二堂课:


public class Port_Com
{
    private static void Main()
    {
    Form1 form = new Form1();
    form.WriteLine("test");
    }
}

基本上我想在富文本框中显示一个日志。

【问题讨论】:

  • 不,你不能从没有实例的静态类调用非静态方法
  • 我的印象是您需要新建 Form1 以在某个阶段显示它,然后您将拥有一个实例,而无需对其进行静态调用。
  • @sujithkarivelil 在我的情况下设置实例如何工作?
  • @CRice 我这样做了:public class Port_Com { private static void Main() { Form1 form = new Form1(); form.WriteLine("test"); } }

标签: c# winforms oop


【解决方案1】:

您应该找到 Form1 实例或创建它,然后才调用方法:

 using System.Linq;
 ... 
 //TODO: Main is a specific name (entry point of the exe), I suggest renaming it
 private static void Main() {
    // Do we have opened Form1? 
    Form1 form = Application
      .OpenForms        // from all opened forms
      .OfType<Form1>()  // we want just Form1 instances
      .LastOrDefault(); // If we have several, let's take the last one

    // Comment out this fragment if you don't want to create it
    if (null == form) { 
      // No open Form1 forms found
      form = new Form1(); // Let's create Form1 instance manually
      form.Show();        // And Show it
    }
    else {
      // form has been found; but you may want

      // Resore it if it's minimized 
      if (form.WindowState == FormWindowState.Minimized)
        form.WindowState = FormWindowState.Normal;
      // Bring it to front
      form.BringToFront();
      // Set keyboard focus on it 
      if (form.CanFocus)
        form.Focus(); 
    }

    // We have a form to work with, we are ready to call the method
    if (null != form)
      form.WriteLine("Hello World!");  
    else { // No Form1 intance has been found; we can't call WriteLine
      //TODO: put relevant code here
    }             
 }

【讨论】:

    【解决方案2】:

    Main 入口点静态方法通常会创建一个主窗体,如:

    Application.Run(new Form1());
    

    您需要将Form1 对象保存在某处,然后您可以调用它的方法:

    var mainForm = new Form1();
    Application.Run(mainForm );
    ...
    mainForm.WriteLine("Hello!");
    

    此外,最好重构日志方法以允许从另一个线程调用它,如here 所述,因为窗口控件必须仅在 UI 线程中更新。由于这是关于COM 端口通信,它很可能也会从后台线程调用。喜欢:

    public void WriteLine(string message)
    {
        if (this.richTextBox1.InvokeRequired)
        {
            var d = new SafeCallDelegate(WriteLine);
            Invoke(d, new object[] { message });
        }
        else
        {
            this.richTextBox1.AppendText(message);
        }
    }
    

    【讨论】:

    • 是的,这基本上就是我所需要的。抱歉这个愚蠢的问题,我是 C# 和 OOP 的新手,但应用程序现在看起来不错 :) 感谢大家的帮助!
    【解决方案3】:

    没有实例就不能调用非静态函数。当一个函数是非静态的时,你需要一个类的实例。 要调用您的表单类,您需要这样做:

    From1 frm = new Form1();
    frm.WriteLine("text");
    

    【讨论】:

      【解决方案4】:

      这取决于您的应用程序处于什么状态... 我假设您有一个正在运行的 WinForms 应用程序,其中至少有一个打开的表单。 然后您可以使用Application.OpenForms 搜索您的表单并调用方法 例如

      Form1 instance = Application.OpenForms.OfType<Form1>().Single();
      instance.WriteLine(...);
      

      【讨论】:

        【解决方案5】:

        我认为您应该在 Port_Com 类中定义一个静态事件。准备好表格后,注册活动。如果 Port_Com 有东西要告诉表单显示,则触发事件。

        public partial class Form1 : Form
        {
            void Form_Load()
            {
                Port_Com.NewMessage += msg=> 
                {
                    // call WriteLine on UI thread
                    this.BeginInvoke(new Action(()=>{
                        this.WriteLine(msg);
                    }));
                };
            }
            {...}
            public void WriteLine(string message)
                {
                    this.richTextBox1.AppendText(Environment.NewLine + ">" + message);
                }
        }
        
        public class Port_Com
        {
            public static event Action<string> NewMessage;
            private static void Main()
            {
                //I want to call the method from here
                NewMessage?.Invoke("Message to Show");
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-01-12
          • 1970-01-01
          • 2020-07-29
          • 2018-04-18
          • 2010-10-10
          • 1970-01-01
          相关资源
          最近更新 更多