我正在尝试一个消息框,当显示时,主应用程序正在使用视觉样式(但为此我不会浪费时间重新发明轮子)。随着它的发展,这已经变成了一个非常有趣的小练习,在此过程中我学到了很多东西。
首先,我在VB中这样做,所以我将所有代码放在它自己的dll中,然后又放在一个Module中,以便在最终项目中引用这个dll的最终用户(在这种情况下我) )可以调用MyDll.MessageBox.show()。
我第一次称之为一切都完全符合预期,第二次奇怪的事情开始发生。经过多次实验后,我只能得出结论,在我的消息框第一次关闭后,它才被正确处理掉。
现在我无法在包含创建消息框的代码的模块上实现IDisposable,因为VB不允许它。我试图明确处理对象,因为它关闭,但显然不起作用。我错过了一些东西,但说实话,我对这个问题有点不了解。
我在这里阅读了各种帖子(尽管几乎所有帖子都与c#以及你可以积极实施IDisposable的领域有关),所以我仍然不是更聪明的。
我是否开始关注正确的区域(IDisposable),在这种情况下,我应该如何继续进行,因为这是从一个模块发出的,或者我在完全错误的区域中查找?
由于
代码:
这是show方法:
Public Function Show(ByVal text As String) As DialogResult
If String.IsNullOrEmpty(text) Then
Throw New ArgumentNullException("text", "You need to supply text for the message itself.")
Else
MessageText = text
End If
MessageCaption = String.Empty
SetMessageButtons(VtlMessageBoxButtons.OK)
IconSelected = False
Return CreateVtlMessageBox()
End Function
这导致了CreateVtlMessageBox
Private Function CreateVtlMessageBox() As DialogResult
'check to see that we have a theme to use
If String.IsNullOrEmpty(CurrentC1ThemeInUse) Then
Throw New ArgumentException("No theme has been set for the message box to use. Please ensure that you have set a value for the property 'CurrentC1ThemeInUse'.")
Exit Function
End If
'we have a theme so we'll continue
_maximumWidth = CType((SystemInformation.WorkingArea.Width * 0.6), Integer)
_maximumHeight = CType((SystemInformation.WorkingArea.Height * 0.9), Integer)
frm = New Form With {.Text = MessageCaption,
.MaximizeBox = False,
.MinimizeBox = False,
.ShowIcon = False,
.ShowInTaskbar = False,
.FormBorderStyle = FormBorderStyle.FixedDialog,
.StartPosition = FormStartPosition.CenterParent}
AddHandler frm.Load, AddressOf FormLoad
AddHandler frm.FormClosing, AddressOf FormClosing
AddHandler frm.FormClosed, AddressOf FormClosed
Dim result As DialogResult
Using frm
result = frm.ShowDialog
End Using
Return result
End Function
我通过实验添加了formClosing和Closed方法,我认为它们是多余的,我将删除它们。
Private Sub FormClosing(sender As Object, e As FormClosingEventArgs)
If sl isNot nothing Then
sl.Dispose
End If
End Sub
Private Sub FormClosed(sender As Object,e As FormClosedEventArgs)
frm.Dispose
End Sub
为了澄清,sl是我最初认为是问题的标签控件。 另一方面,FormLoad可以完成驴工作,我认为问题的根源可能就在那里以及它所依赖的方法。
Private Sub FormLoad(sender As Object, e As EventArgs)
frm.Size = New Size(_maximumWidth, _maximumHeight)
_maximumLayoutWidth = frm.ClientSize.Width - LeftPadding - RightPadding
_maximumLayoutHeight = frm.ClientSize.Height - TopPadding - BottomPadding
If IconSelected Then
CreateAndPositionIconOnForm()
End If
SetTheText()
PositionAndSizeTheSuperLabel()
SetTheOptimumSizeForTheForm()
LayoutTheForm()
If frm Is Nothing Then
Return
Else
If IconSelected Then
frm.Controls.Add(IconPanel)
End If
frm.Controls.Add(sl)
End If
Dim lThemeName As String = CurrentC1ThemeInUse
If Not String.IsNullOrEmpty(lThemeName) Then
Dim lThemeLocator As New C1ThemeLocator(locationType:=C1ThemeLocator.LocationType.ThemesFolder, themeName:=lThemeName)
Dim lTheme As C1Theme = New C1ThemeLocator(lThemeLocator).GetTheme()
C1ThemeController.ApplyThemeToControlTree(frm, lTheme)
End If
If NoCancelButton Then
'disable the close Button
Disable(frm)
End If
End Sub
当我第二次调用消息框时,添加下面的SetTheTex方法通过显式处理它解决了sl的问题。
Private Sub SetTheText
If sl Is Nothing Then
sl = New C1SuperLabel With {.Text = MessageText}
Else
sl.Dispose
sl = New C1SuperLabel With {.Text = MessageText}
End If
End Sub
现在第二次调用消息框时,它不会抛出一个未处理的异常,因为它在我处理sl之前就会发生,但它确实复制了所有的buutons,并且每次调用它时都会继续添加它们试。
与此相关的两位代码如下所示。
Private Sub SetTheOptimumSizeForTheForm()
Dim ncWidth As Integer = frm.Width - frm.ClientSize.Width
Dim ncHeight As Integer = frm.Height - frm.ClientSize.Height
Dim messageRowWidth As Integer
If IconSelected Then
messageRowWidth = sl.Width + IconToMessagePadding + IconPanel.Width
Else
messageRowWidth = sl.Width + RightPadding
End If
_buttonsRowWidth = GetWidthOfAllAvailableButtons()
Dim captionWidth As Integer = GetCaptionSize().Width + CloseButtonWidth
Dim maxItemWidth As Integer = Math.Max(messageRowWidth, _buttonsRowWidth)
Dim requiredWidth As Integer = LeftPadding + maxItemWidth + RightPadding + ncWidth
'Since Caption width is not client width, we do the check here
If requiredWidth < captionWidth Then
requiredWidth = captionWidth
End If
Dim requiredHeight As Integer
If IconSelected Then
requiredHeight = TopPadding + Math.Max(sl.Height, IconPanel.Height) + ItemPadding + ItemPadding + GetButtonSize().Height + BottomPadding + ncHeight
Else
requiredHeight = TopPadding + sl.Height + ItemPadding + ItemPadding + GetButtonSize().Height + BottomPadding + ncHeight
End If
If requiredHeight > _maximumHeight Then
sl.Height -= requiredHeight - _maximumHeight
End If
Dim height As Integer = Math.Min(requiredHeight, _maximumHeight)
Dim width As Integer = Math.Min(requiredWidth, _maximumWidth)
frm.Size = New Size(width, height)
End Sub
Private Sub LayoutTheForm()
If IconSelected Then
IconPanel.Location = New Point(LeftPadding, TopPadding)
sl.Location = New Point(LeftPadding + IconPanel.Width + IconToMessagePadding * (If(IconPanel.Width = 0, 0, 1)), TopPadding)
Else
sl.Location = New Point(LeftPadding + IconToMessagePadding, TopPadding)
End If
Dim buttonSize As Size = GetButtonSize()
'buttons need to be positioned from the right of the message box
Dim allButtonsWidth As Integer = _buttonsRowWidth + ButtonPadding
Dim firstButtonX As Integer = CType(frm.ClientSize.Width - allButtonsWidth, Integer)
Dim firstButtonY As Integer = frm.ClientSize.Height - BottomPadding - buttonSize.Height
Dim nextButtonLocation As Point = New Point(firstButtonX, firstButtonY)
Dim foundDefaultButton As Boolean = False
Dim i As Integer
For Each button As String In MessageButtons
Dim buttonCtrl As C1Button = AddMessageBoxButton(button, buttonSize, nextButtonLocation)
nextButtonLocation.X += buttonSize.Width + ButtonPadding
i = buttonCtrl.Location.Y
buttonCtrl.Anchor = AnchorStyles.Bottom And AnchorStyles.Right
frm.Controls.Add(buttonCtrl)
Next
End Sub
我希望这有助于遵循我的逻辑或缺乏逻辑!
答案 0 :(得分:1)
我强烈建议你从模块中删除所有这些代码。这并非真正使用模块。相反,创建一个表单的子类。
Class MyMessageBox
Inherits Form
Public Sub New(ByVal messageCaption As String)
'we have a theme so we'll continue
_maximumWidth = CType((SystemInformation.WorkingArea.Width * 0.6), Integer)
_maximumHeight = CType((SystemInformation.WorkingArea.Height * 0.9), Integer)
Text = messageCaption,
MaximizeBox = False,
MinimizeBox = False,
ShowIcon = False,
ShowInTaskbar = False,
FormBorderStyle = FormBorderStyle.FixedDialog,
StartPosition = FormStartPosition.CenterParent}
End Sub
Public Shared Function Show(ByVal text As String) As DialogResult
If String.IsNullOrEmpty(text) Then
Throw New ArgumentNullException("text", "You need to supply text for the message itself.")
Else
MessageText = text
End If
MessageCaption = String.Empty
SetMessageButtons(VtlMessageBoxButtons.OK)
IconSelected = False
'check to see that we have a theme to use
If String.IsNullOrEmpty(CurrentC1ThemeInUse) Then
Throw New ArgumentException("No theme has been set for the message box to use. Please ensure that you have set a value for the property 'CurrentC1ThemeInUse'.")
Exit Function
End If
Dim frm = New MyMessageBox(MessageCaption)
Dim result As DialogResult
Using frm
result = frm.ShowDialog
End Using
Return result
End Function
Private Sub FormLoad(sender As Object, e As EventArgs) Handles Me.Load
End Sub
End Class
这个想法是共享函数创建一个继承表单的实例,其中包含要添加到其中的所有特殊功能。这样,该表单可以处理IDispose。您的所有活动也将成为该表单的一部分,而不是在模块中。每个表单还将拥有自己的变量实例,这将减少冲突。