我的 winforms 应用程序需要与硬件设备交互。显示是一种工作流程......在步骤 1 .. 完成后.. 转到步骤 2 .. 等等。显示是动态的,控件在运行时可见并且活动正在启动(这些用户控件中的每一个都使用计时器/ BGWorker 内)。
我从 timer/BGWorker_Completed 引发自定义事件。这将有助于进行下一步并更新 UI。我在做正确的事吗?
我是winforms的新手,我只是无法弄清楚显示失败的原因。
我没有发现任何异常......但是在特定步骤之后我看不到控件!我不知道在哪里以及如何调试这种情况。如果我单独执行主窗体..我也可以看到显示。但是,如果我从登录页面导航/更改主表单中的选项卡并返回..我看不到显示。
在调用 UI 上的更新之前,我尝试按以下相同顺序进行检查。Thread.Current.IsBackground 返回 false,control.IsHandleCreated 返回 true,否则我使用 dim x=Control.handle()) 创建它 Me.InvokeRequired/ Control.invokeRequired 返回 false(我想要的方式)。但是我没有看到 userControl 正在显示...可见性/颜色/正在设置所有内容(在程序中)..并且我能够看到硬件交互!!!.. 但是没有显示:-((第 4 步及以后)
我在登录页面……或 tabChanged 事件中没有做任何花哨的事情。(在选项卡更改事件上......我只清理打开的连接/关闭 bg 工作人员(如果有的话)......将在需要时重新连接)
请让我知道我是否需要做任何事情......以及如何解决这个问题。我还在初始化每个用户控件/主窗体的组件后不久调用 EnsureHandleIsCreated(control) 子例程。
'Code in Login Form
Dim myForm as new MainForm()
myForm.ShowDialog(Me) ' here i also tried with show/showDialog.. with/without ownerForm
Me.Hide() ' Hide login page
'Code for checking if handle is created or not
Public Sub CheckForInvalidThread()
frmMain.CheckForIllegalCrossThreadCalls() = True
If Thread.CurrentThread.IsBackground Or Not Thread.CurrentThread.Name Is THREAD_MAIN_NAME Then
Throw New InvalidOperationException(THREAD_IS_INVALID)
End If
If Not Me.IsHandleCreated Then
Dim x = Me.Handle()
Thread.Sleep(20)
End If
End Sub
Public Sub EnsureHandleIsCreated(ByRef c As Control)
Try
If Not c.IsHandleCreated Then
Dim h As System.IntPtr = c.Handle()
End If
If c.HasChildren Then
For Each child As Control In c.Controls
Try
EnsureHandleIsCreated(child)
Catch ex As Exception
DAL.LogException(ex.Message, ex.StackTrace, "EnsureHandleIsCreated: " & c.Name, 0)
End Try
Next
End If
Catch ex As Exception
DAL.LogException(ex.Message, ex.StackTrace, "EnsureHandleIsCreated: " & c.Name, 0)
End Try
End Sub
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lbRole.Text = RoleName
lbName.Text = UserName
Try
Me.Activate()
If Thread.CurrentThread.IsBackground Then
Throw New ApplicationException(THREAD_IS_INVALID)
End If
Thread.CurrentThread.Name = THREAD_MAIN_NAME
CheckForInvalidThread()
clGlobals.frmMain = Me
If RoleName Is Nothing Or String.IsNullOrEmpty(RoleName) Or RoleName.Equals("OPERATOR", StringComparison.InvariantCultureIgnoreCase) Then
tcEtch.TabPages("tbMaintenance").Hide()
tcEtch.TabPages("tbAdmin").Hide()
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
Finally
End Try
Initiate()
End Sub
Public Sub GoToNextStep() Handles Me.GoToNextStepEvent
Try
CheckForInvalidThread()
CurrentStep = CurrentStep + 1
Select Case CurrentStep
Case 0 To 2
If Me.InvokeRequired Then
_delegateDisplayInitiate = AddressOf DisplayStep2
Me.Invoke(_delegateDisplayInitiate)
Else
DisplayStep2()
End If
Case 3
If ucCycleStart.InvokeRequired Then
_delegateDisplayInitiate = AddressOf DisplayStep3
ucCycleStart.Invoke(_delegateDisplayInitiate)
Else
DisplayStep3()
End If
Case 4
If Me.InvokeRequired Or ucPartCountVerification.InvokeRequired Or Thread.CurrentThread.IsBackground Then
Throw New Exception("Check out")
End If
EnsureHandleIsCreated(ucPartCountVerification)
If ucPartCountVerification.InvokeRequired Then
_delegateDisplayInitiate = AddressOf DisplayStep4
ucPartCountVerification.Invoke(_delegateDisplayInitiate)
Else
DisplayStep4()
End If
End Select
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Sub DisplayStep4() Handles Me.DisplayStep4Event
ucPartCountVerification.Visible = True
ucPartCountVerification.Show()
ucPartCountVerification.Initiate()
End Sub
Public Sub Initiate()
frmMain.CheckForInvalidThread()
'Just to verify if things are fine.. i put in this check below
If Me.InvokeRequired Or pnStep4.InvokeRequired Or Not (Me.IsHandleCreated And pnStep4.IsHandleCreated ) Then
MessageBox.Show("cHECK OUT")
Else
Me.Visible = True
pnStep4.Visible = True
Me.BackColor = Color.Red
pnStep4.BackColor = Color.Gray
Dim height = Me.Size.Height
Dim width = Me.Size.Width
MessageBox.Show(height.ToString() + Me.InvokeRequired.ToString())
End If
end Sub