【问题标题】:Static or Class Method in Delphi PrismDelphi Prism中的静态或类方法
【发布时间】:2011-08-19 18:28:21
【问题描述】:

我正在使用 Delphi Prism for .NET。我需要从另一个 winform 方法调用我的 mainform 类中的公共方法。所以,最近了解了静态,我在我的程序中使用了它。静态或类 winform 效果很好,但将方法设为静态或类似乎不一样。

我的主窗体类中有一个名为 updateButtons 的方法。它根据用户的操作更新主窗体上的所有按钮和控件。此方法需要从另一个 winform 方法调用。因此,我将 UpdateButtons 方法设为静态或类。虽然现在我看到了要调用的方法,但编译器不喜欢。它不断引发以下错误,“无法在没有实例引用的情况下调用实例成员(任何控件)。”

如何将方法设为类或静态,并且仍然可以从 winform 访问控件?

具有静态或类方法的主类:

  MainForm = partial class(System.Windows.Forms.Form)
  private
  protected
    method Dispose(disposing: Boolean); override;
  public
    class method updateButtons;
  end;

更新按钮的定义:

class method MainForm.updateButtons;
begin    
        if SecurityEnabled then
                LoginBtn.Enabled := true       //All the lines where I call Buttons raise the error exception that I mentioned above.
        else
        begin
                UnitBtn.Enabled := true;
                SignalBtn.Enabled := true;
                AlarmBtn.Enabled := true;
                MakerBtn.Enabled := true;
                TrendBtn.Enabled := true;
                DxCommBtn.Enabled := (Scanning = false);
                TxBtn.Enabled := true;
                ControlBtn.Enabled := true;
                PIDBtn.Enabled := true;
                SystemBtn.Enabled := true;
                WinListBox.Enabled := true;
                WinBtn.Enabled := true;
                ShutdownBtn.Enabled := true;
                OptionBtn.Enabled := true;
                LoginBtn.Enabled:=false;
        end;
  end;

【问题讨论】:

    标签: singleton static-methods delphi-prism class-method


    【解决方案1】:

    这无法按照您希望的方式工作。

    类(或静态)方法在类上静态调用,而不是在特定对象实例上调用。

    您可以多次实例化同一个表单类。然后你就有了表单的几个对象实例,它们可以同时打开或隐藏。

    现在,当您调用静态方法时,应该更新这几种形式中的哪一种?编译器无法判断,也不允许访问属于对象实例的字段或属性。

    为此,您必须使该方法成为对象的普通方法(非类或静态),并且您需要检索具体表单对象实例的引用并在那里调用它。

    【讨论】:

    • @Sebastian,你是对的。由于它是一个方法并且变成类使其成为静态,它本身需要被实例化。事实上,它甚至无法识别来自 MainForm 的任何控件。您的解决方案看起来很简单,但需要做一些事情。
    • @Sebastian 您的解释确实澄清了我的误解并帮助我找到了解决方案,即使我不接受您的回答。所以,我对你的回答投了票。谢谢。
    【解决方案2】:

    由于我要执行的方法来自 MainForm Window Form 并从按钮事件中触发,因此我决定从 MainForm 而不是其他 winform 的 Button Click 事件中调用该方法。这具有相同的最终结果。另外,它更简单。

    //This is just a sample code
    MainForm = class(system.windows.forms.form)
    private
        method ScanBtn_Click(sender: System.Object; e: System.EventArgs);
    protected
    public
        Method UpdateButtons;
    end;
    
    Method Mainform.UpdateButtons;
    begin
       Button1.enabled:=true;
       Button1.text:='Start Scanning';
    end;
    
    method MainForm.ScanBtn_Click(sender: System.Object; e: System.EventArgs);
    begin
        if not Scanning then
            stopthread:=true;
    
        dxCommWin.Scan(not Scanning);
        UnitWin.UpdateMenu;  
        UpdateButtons; <-------I call it here instead of from dxCommWin.Scan Method.
    end;
    

    【讨论】:

    • 实际上,在这种情况下,如果您想从 dxCommWin.Scan 调用它,您可以简单地将 MainForm (self) 的引用作为第二个参数传递给该方法:dxCommWin.Scan(not Scanning, self); 在此如果方法的签名看起来像 method dxCommWin.Scan(scanning: boolean; form: MainForm); 并且您可以从方法中访问表单。这就是我所说的“检索对表单的引用”的意思。
    • 是的。我正计划实现类似的代码,但我想到了我的解决方案,它似乎更合适,因为这就是我想做的全部 - 在调用 dxCommWin.Scan 后立即执行该方法。谢谢,塞巴斯蒂安。
    猜你喜欢
    • 1970-01-01
    • 2013-05-18
    • 2011-01-17
    • 2011-07-11
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多