ParentForm 的 属性 变化检测问题

Issue with ParentForm's property changing detection

我正在定制 TitleBar (UserControl)。我想要做的是 检测 ParentFormText 属性 被开发人员在 设计时间 然后更新TitleBarText属性.

在我开始在网上寻找这个之前,我已经在我的 UserControl 中添加了一个 Timer 来完成这个 "work"。像这样的东西......

Private Sub Timer_Tick(sender As Object, e As EventArgs) Handles Timer.Tick
    FormTitle_Label.Text = Me.ParentForm.Text
End Sub

然后我意识到这不是最合适的方法。所以我发现了这样的东西......

Protected Overrides Sub OnCreateControl()
    MyBase.OnCreateControl()
    AddHandler Me.FindForm.TextChanged, AddressOf ParentForm_TextChanged 
    FormTitle_Label.Text = Me.FindForm.Text
End Sub

Private Sub ParentForm_TextChanged(sender As Object, e As EventArgs)
    FormTitle_Label.Text = Me.FindForm.Text
End Sub

部分有效,但每次我重建删除重新添加我的UserControl 变成 Form,当我尝试更改 ParentFormText 属性 时,出现错误 Property value is not valid. Details: Object reference not set to an instance of an object.。如果我 closereopen 我的项目然后它再次工作,但直到我 rebuild 它或 删除重新添加我的UserControl。知道为什么会这样吗?

在访问 属性 之前,您必须测试 Me.FindForm 的值为 Nothing。创建控件并不能保证它已经存在于表单中。

尝试使用 OnBindingContextChanged OnParentChanged 来跟踪 adding/removing 您对父容器的控制。 但我不确定它是否也适用于设计时。

编辑 添加了完全控制代码

Public Class SimonetosTitleBar
    Inherits Control

    Private fText As String = "Default title"
    Private WithEvents fOwnerForm As Form

    Protected Overrides Sub OnParentChanged(e As EventArgs)
        MyBase.OnParentChanged(e)
        fOwnerForm = FindForm()
        fOwnerForm_TextChanged()
    End Sub

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)
        e.Graphics.DrawString(fText, Font, SystemBrushes.ControlText, Point.Empty)
    End Sub

    Private Sub fOwnerForm_TextChanged() Handles fOwnerForm.TextChanged
        If fOwnerForm Is Nothing Then
            fText = "Default title"
        Else
            fText = fOwnerForm.Text
        End If
        Invalidate()
    End Sub

End Class