65.9K
CodeProject 正在变化。 阅读更多。
Home

显示和处理窗体

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.26/5 (22投票s)

2005年2月15日

4分钟阅读

viewsIcon

160522

无论您是开发新手,还是来自 Visual Basic、C++、Java 或 Delphi,在 WinForms 中管理窗体最初可能会感到困惑。本文旨在面向 WinForms 编程的初学者,演示如何在 WinForms 应用程序中轻松管理和使用窗体。

引言

无论您是开发新手,还是来自 Visual Basic、C++、Java 或 Delphi,在 WinForms 中管理窗体最初可能会感到困惑。本文旨在面向 WinForms 的新手,演示如何在 WinForms 应用程序中轻松管理和使用窗体。

非模态

非模态窗体是指在打开时允许将焦点切换到其他窗口的窗体。这使得用户可以同时处理多个窗体。

模式

打开非模态窗体的基本模式如下:

C#

private void button1_Click(object sender, System.EventArgs e) {
    Form2 xForm = new Form2();
    xForm.Show();
}

Visual Basic

Private Sub Button1_Click(ByVal sender As System.Object, _
                    ByVal e As System.EventArgs) Handles Button1.Click
    Dim xForm As Form2
    xForm = New Form2
    xForm.Show()
End Sub

Show 方法将在窗体显示后返回,接下来的代码执行取决于用户在“新建”窗体或用户可能选择的任何其他已打开窗体上的操作。

释放

当非模态窗体关闭时,WinForms 会自动调用 Dispose。可以通过在 Dispose 方法(C#)中设置断点,然后关闭窗体来观察这一点。因此,无需从创建此窗体的代码中调用 Dispose

模态

模态窗体或对话框式窗体可以阻止用户将焦点移出该窗体。用户必须打开另一个窗体或关闭当前窗体。在该模态窗体之前打开的窗体无法被用户访问。

模式

C#

private void button2_Click(object sender, System.EventArgs e) {
    using (Form2 xForm = new Form2()) {
    xForm.ShowDialog(this);
    }
}

Visual Basic

Private Sub Button2_Click(ByVal sender As System.Object, _
           ByVal e As System.EventArgs) Handles Button2.Click
    Dim xForm As Form2
    xForm = New Form2
    Try
       xForm.ShowDialog(Me)
       Finally
       xForm.Dispose()
    End Try
End Sub

ShowDialog 方法的功能与 Show 方法不同。ShowDialog 会阻塞执行,直到窗体关闭为止。因此,Dispose 可以紧跟在 ShowDialog 调用之后,因为它将在窗体关闭后才会调用。如果 Dispose 调用紧跟在 Show 方法之后,窗体将仅仅闪烁一下屏幕,因为它会在显示后立即被释放。

释放

当用户关闭模态窗体时,WinForms 不会自动调用 Dispose 方法。因此,需要显式调用 Dispose。在 Visual Basic 中,通过直接调用 Dispose 方法完成;而在 C# 中,则使用 using 语句。

返回结果

ShowDialog 方法与 Show 方法的不同之处还在于它提供返回值。返回值可用于确定用户关闭窗体的方式。为此,事件代码可以设置返回值,或者更简单地使用按钮的 DialogResult 属性。

要实际查看这一点,请在模态窗体上放置两个按钮。然后将其中一个按钮的 DialogResult 属性设置为 OK,另一个设置为 Cancel。这将导致按钮关闭窗体,并将指定的返回值作为 ShowDialog 的返回值返回。

然后可以像这样修改模式:

C#

private void button2_Click(object sender, System.EventArgs e) {
    using (Form2 xForm = new Form2()) {
        if (xForm.ShowDialog(this) == DialogResult.OK) {
            // Take some action
        }
    }
}

Visual Basic

Private Sub Button2_Click(ByVal sender As System.Object, _
           ByVal e As System.EventArgs) Handles Button2.Click
    Dim xForm As Form2
    xForm = New Form2
    Try
        If xForm.ShowDialog(Me) = DialogResult.OK Then
            ' Take some action
        End If
    Finally
        xForm.Dispose()
    End Try
End Sub

传递数据

可以通过创建公共方法、成员或属性并在显示窗体之前访问它们来轻松地将数据传递到窗体。

例如,假设以下内容声明在第二个窗体中:

C#

public void SetValue(string aValue) {
    button1.Text = aValue;
    // Do some other things
}

Visual Basic

Public Sub SetValue(ByVal aValue As String)
button1.Text = aValue
' Do something else
End Sub

然后可以从调用代码中调用此方法:

C#

private void button1_Click(object sender, System.EventArgs e) {
     Form2 xForm = new Form2();
     xForm.SetValue("Test");
     xForm.Show();
}

Visual Basic

Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click
    Dim xForm As Form2
    xForm = New Form2
    xForm.SetValue("Test")
    xForm.Show()
End Sub

此示例使用 Show 方法,但也可与 ShowDialog 结合使用。

同样的方法也可用于从模态窗体中检索数据,通过在 ShowDialog 返回后、但在 Dispose 被调用之前调用方法,或访问成员或属性。事实上,这就是 WinForms 不会自动释放模态窗体的原因。

示例如下:

C#

private void button2_Click(object sender, System.EventArgs e) {
    using (Form2 xForm = new Form2()) {
        if (xForm.ShowDialog(this) == DialogResult.OK) {
            _Value = xForm.GetValue();
        }
    }
}

Visual Basic

Private Sub Button2_Click(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles Button2.Click
    Dim xForm As Form2
    xForm = New Form2
    Try
        If xForm.ShowDialog(Me) = DialogResult.OK Then
            _Value = xForm.GetValue()
        End If
    Finally
        xForm.Dispose()
    End Try
End Sub

其中 GetValue 是您自己定义的函数。

静态显示

如果一个窗体总是以显示并且需要某些参数,那么可以将该过程封装到窗体类的 static 方法中。假设之前的 SetValue 示例是必需的,并且甚至需要返回结果,那么可以像这样将其添加到 Form2 类中:

C#

public static string Display(string aValue) {
    using (Form2 xForm = new Form2()) {
        xForm.SetValue("Test");
        if (xForm.ShowDialog() == DialogResult.OK) {
            return GetValue();
        } 
        else {
            return "";
        }
    }
}

Visual Basic

Public Shared Function Display(ByVal aValue As String) As String
Dim xForm As Form2
xForm = New Form2
    Try
        xForm.SetValue(aValue)
        If xForm.ShowDialog() = xForm.DialogResult.OK Then
        Return GetValue()
        Else
        Return ""
        End If
    Finally
        xForm.Dispose()
    End Try
End Function

SetValue 方法也应该声明为 private 而不是 public,以防止其被外部使用。

要显示窗体,调用代码如下所示:

C#

private void button1_Click(object sender, System.EventArgs e) {
    _Value = Form2.Display("Test");
}

Visual Basic

Private Sub Button1_Click(ByVal sender As System.Object, _
          ByVal e As System.EventArgs) Handles Button1.Click
    _Value = Form2.Display("Test")
End Sub

当然,这也可以在不返回结果的情况下完成,只需将方法类型更改为 void (C#) 或 Sub (Visual Basic)。在此示例中,我将其更改为使用 Show,仅作为一种变体。

C#

public static void Display(string aValue) {
    Form2 xForm = new Form2();
    xForm.SetValue("Test");
    xForm.Show();
}

Visual Basic

Public Shared Sub Display(ByVal aValue As String) As String
    Dim xForm As Form2
    xForm = New Form2
    xForm.SetValue(aValue)
    xForm.Show()
End Sub

保留引用

通常,将窗体的引用存储起来供以后使用会很有用。您的应用程序可能需要在其他事件中更新窗体、重新显示窗体、隐藏窗体等。.NET 不支持全局变量,这是我们许多人以前用于此目的的方式。但是,static 窗体成员可用于此目的。

Form2 中,只需声明以下成员:

C#

public static Form2 Form2Ref;

Visual Basic

Public Shared Form2Ref As Form2

然后可以使用此变量来存储窗体实例的引用。稍后再次引用它,例如重新显示窗体或将其聚焦,可以使用以下代码:

C#

Form2.Form2Ref.Show();

Visual Basic

Form2.Form2Ref.Show()
© . All rights reserved.