使用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”!!!
现在这真的很奇怪,因为它根本不重要,因为在关闭对话框之前不会处理这一行。 我希望有人理解我的意思。
有人可以了解这里可能发生的事情吗?
答案 0 :(得分:3)
是的,如果将RightToLeft
属性设置为控件构造函数以外的任何位置,则会出现意外行为(用VB.NET的说法,那就是{{1}方法)。
实际上,构造函数是您应该设置表单或控件对象的所有属性的地方。如果你来自VB 6,那么在New
事件处理程序中执行此操作似乎是合乎逻辑的,但这不是惯用的.NET,并且正如您所发现的那样,在初始化某些事件时可能会导致问题属性。
技术原因是某些属性(如Load
)实际上只能在本机窗口上设置(这就是.NET世界中使用的RightToLeft
对象在后面实现的方式。场景)在创建时。当您尝试更改属性时,框架代码实际上必须销毁然后使用新属性值重新创建本机窗口。
将代码更改为:
Form
说到非惯用的.NET代码:
方法应该按照惯例进行Pascal。这意味着您的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
方法应命名为setFormRTL
。
设置对象属性的辅助函数对我来说似乎不对。如果有的话,这只是糟糕的OO设计。如果希望此方法可用于所有SetFormRtl
个对象,则派生自定义表单类并添加此方法(甚至在构造函数中执行所需的初始化)。无论哪种方式,您从此自定义表单对象派生的所有表单都将继承该功能。例如:
Form
答案 1 :(得分:1)
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.Hide()
Dim f As New Form2
modControls.setFormRTL(f)
f.ShowDialog()
MessageBox.Show("After dialog closed.")
modControls.setFormRTL(Me)
End Sub
End Class
并删除表单2的代码表单加载事件