none
如何从另一个类将消息返回到 MDI Parent 的状态条 RRS feed

  • 问题

  • 各位好!
    本人有一个WinForm程序,启动界面是 MDI 窗口。单击菜单访问另一个Winform类(假设为A),类 A 和 MDI 不在同一个项目,放在另一个项目,类 A 有个统计项目个数的方法,可根据输入的不同条件统计。我想把统计结果显示在 MDI 的状态条,请问该如何实现?

    如果只是单次调用,则很简单,只要:
    dim a as A = new A
    mdi.statusBar.text = a.GetProject()
    问题是调用 A 后,A 会显示 Winform 界面,根据条件运行 GetProject,这时候 A 并没有退出。而项目引用设置是 MDI 引用 A,A 不能直接引用 MDI。

    其实问题应该是 MDI (调用类)如何在 A (被调用类)运行时访问 A (被调用类)。

    Ay
    2009年8月25日 2:27

答案

  • 你需要在一个窗体中定义事件,同时提供一个自定义的事件参数(继承于EventArgs的类),你要传递的数据就包含在这个事件参数中(定义成类的属性)
    然后在另一个窗体中订阅事件,并提供处理程序,通过事件参数就可以获取这个传递的参数了(e.XXXX),这样一个窗体中的数据就在另外的窗体中获取到了!

    希望这个解释对你有帮助!
    周雪峰
    • 已标记为答案 Ay Xu 2009年8月25日 7:33
    2009年8月25日 4:23
    版主

全部回复

  • 你好!
         可以通过一个自定义的事件来实现,通过事件的参数来传递你想传递的数据!
    周雪峰
    2009年8月25日 2:32
    版主
  • 感谢回复!对于事件我不熟悉,能否再解释一下。按照你的提示,我的理解:
    假设 A 有属性 ProjectCount as integer.
    添加自定义事件 ProjectCountChange. 也就是在项目统计个数变化时触发. 那么处理该事件的代码应该是放在 MDI 中,不然还是无法访问状态条。
    那么在 MDI 中该如何写呢?

    Public Class MDI ...
    dim a1 as A
    private sub menuProjectCount(..) handles menu.click
      a1 = new A
      a1.show()
    end sub

    private sub showProjectCountinStatusBar (e as eventArgs) handles a1.ProjectCountChange
      me.statusBar.text = e.ProjectCount
    end sub

    end Class

    上面的思路有问题吗?感觉 a1.ProjectCountChange 好像不会触发。

    Ay
    2009年8月25日 2:54
  • 你需要在一个窗体中定义事件,同时提供一个自定义的事件参数(继承于EventArgs的类),你要传递的数据就包含在这个事件参数中(定义成类的属性)
    然后在另一个窗体中订阅事件,并提供处理程序,通过事件参数就可以获取这个传递的参数了(e.XXXX),这样一个窗体中的数据就在另外的窗体中获取到了!

    希望这个解释对你有帮助!
    周雪峰
    • 已标记为答案 Ay Xu 2009年8月25日 7:33
    2009年8月25日 4:23
    版主
  • 你好,你可以在MDI窗体定义一个委托 比如 delegate void ShowProjectCount(string count);

    然后在MDI中添加一个方法 public  void ShowAProjectCount(string count)
    {
    this.statusBar.text=count;
    }

    然后为A实例化的时候将委托作为参数传递给窗体A的构造函数,或者在A中增加个属性
    比如
    public ShowProjrectCount ShowMyProjectCount{get;set;}
    设置窗体A的这个属性

    FormAInstance.ShowMyProjectCount=ShowAProjectCount;


    然后在A中通过ShowMyProjectCount("这里是count的值");
    Wenn ich dich hab’,gibt es nichts, was unerträglich ist.坚持不懈!http://hi.baidu.com/1987raymond
    2009年8月25日 5:44
    版主
  • 感谢两位的回复! Raymond,我看来 delegate 的资料,如果在同一个项目实现 delegate 好像挺简单的。但要在两个项目之间实现,不知道该如何操作。按照你的说明,结合 MSDN,我在 MDI 里添加: 
    Public Delegate Sub subDelegate(ByVal str As String) 

    Public Sub ShowMessageInStatusBar(ByVal message As String) 
        Me.slMessage.Text = message 
    End Sub 

    Sub DelegateShowMessageInStatusBar(ByVal msg As String, ByVal op As subDelegate) 
        op.Invoke(msg) ' Call the method. 
    End Sub 
    如在 MDI 中调用委托函数,只要调用:Me.DelegateShowMsgToStatusBar("some messages.", AddressOf ShowMessageInStatusBar)。如何才能在 A 中执行委托函数呢?你说的“然后为A实例化的时候将委托作为参数传递给窗体A的构造函数”,不明白如何传递?
    Ay
    • 已编辑 Ay Xu 2009年8月25日 7:26
    2009年8月25日 7:23
  • 问题已解决,按照 周老师 的方法,并参照网上的代码,实现起来不复杂。
    VB主窗口
    Private Sub ShowForm2()
    Dim f2 As New Form2
    f2.Show()
    AddHandler f2.SendMessage, AddressOf ShowMessage
    End Sub
    Private Sub ShowMessage(ByVal str As String)
    MsgBox(str)
    End Sub
    VB从窗口
    Public Delegate Sub DelegateOfSendMessage(ByVal str As String)
    Public Event SendMessage As DelegateOfSendMessage
    Private Sub Send()
    RaiseEvent SendMessage("A Message From Form2")
    End Sub

    Ay
    2009年8月25日 7:35
  • 恭喜啊!问题得到解决了!
    因为看你的回复,感觉你已经是成手了,所以我没有提供代码,因为我相信你看思路自己就能实现了!
    周雪峰
    2009年8月25日 11:12
    版主