gpt4 book ai didi

VB.NET 绝对奇怪的表单加载行为

转载 作者:行者123 更新时间:2023-12-01 12:42:10 25 4
gpt4 key购买 nike

我在使用 RightToLayout 布局时遇到了一个奇怪的行为:我的表单会自动关闭。

我创建了一个简单的项目来重现该问题:

在VS2012中新建一个VB.NET工程,添加窗体“Form1”和“Form2”。将“Form1”设置为起始表单。

然后在“Form1”中添加如下代码:

Public Class Form1

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

Me.Hide()

Dim f As New Form2
f.ShowDialog()

MessageBox.Show("After dialog closed.")

modControls.setFormRTL(Me) 'This line causes the Form2 to automatically close. Why??? This line should only be processed AFTER the dialog has been shown and closed

End Sub
End Class

将以下代码添加到“Form2”:

Public Class Form2

Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load

modControls.setFormRTL(Me)

End Sub
End Class

将名为“modControls”的模块添加到项目中。向其中添加以下代码:

Module modControls

Public Sub setFormRTL(ByVal uForm As Form)

uForm.RightToLeft = RightToLeft.Yes

End Sub

End Module

没有 setFormRTL,我的项目工作得很好,但有了它,“Form2”会自动关闭。您可以看到这一点,因为显示了消息框。

当我删除行时

        modControls.setFormRTL(Me)

从 Form1 加载,它再次正常工作。是的,我的意思是来自“Form1”,而不是来自“Form2”!!!

现在这真的很奇怪,因为它根本不重要,因为在关闭对话框之前没有处理这一行。我希望有人明白我的意思。

任何人都可以阐明这里可能发生的事情吗?

最佳答案

是的,如果您在控件的构造函数以外的任何位置设置 RightToLeft 属性(用 VB.NET 的说法,即 New 方法),您将获得意想不到的行为。

事实上,构造函数是您应该设置窗体或控件对象的所有 属性的地方。如果您来自 VB 6,在 Load 事件处理程序中执行此操作似乎合乎逻辑,但这不是惯用的 .NET,并且正如您所发现的那样,在初始化某些属性时可能会导致问题。

这样做的技术原因是某些属性(如 RightToLeft)实际上只能在 native 窗口上设置(这就是 Form 对象在 . NET 世界在创建时在幕后实现)。当您尝试更改属性时,框架代码实际上必须销毁然后使用新的属性值重新创建 native 窗口。

将代码改为如下所示:

Public Class Form1

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

modControls.SetFormRtl(Me)
End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.Hide()

Dim f As New Form2
f.ShowDialog()

MessageBox.Show("After dialog closed.")
End Sub
End Class

Public Class Form2

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

modControls.SetFormRtl(Me)
End Sub

Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load

End Sub
End Class

说到非惯用的 .NET 代码:

  1. 按照惯例,所有方法都应采用 Pascal 大小写。这意味着您的 setFormRTL 方法应命名为 SetFormRtl

  2. 设置对象属性的辅助函数对我来说似乎是错误的。如果有的话,那就是糟糕的 OO 设计。如果您希望此方法可用于所有 Form 对象,请派生一个自定义表单类并添加此方法(或者甚至在构造函数中执行所需的初始化)。无论哪种方式,您从这个自定义表单对象派生的所有表单都将继承该功能。示例:

    Public Class MyCustomForm : Inherits System.Windows.Forms.Form

    Public Sub New()
    MyBase.New()

    Me.SetRtl()
    End Sub

    Public Sub SetRtl()
    Me.RightToLeft = RightToLeft.Yes
    End Sub

    End Class

    Public Class Form1 : Inherits MyCustomForm

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    Me.Hide()

    Dim f As New Form2
    f.ShowDialog()

    MessageBox.Show("After dialog closed.")
    End Sub

    End Class

    Public Class Form2 : Inherits MyCustomForm

    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load

    End Sub

    End Class

关于VB.NET 绝对奇怪的表单加载行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23356312/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com