【问题标题】:Form doesn't show controls on load event表单不显示加载事件的控件
【发布时间】:2020-08-27 00:54:56
【问题描述】:

我有一个表单可以检查文件夹中是否有一些更改。我使用 FileSystemWatcher 执行此操作。 当通知更改时,必须加载另一个表单。第二个窗体已加载,但控件不可见。当我通过单击按钮加载第二个表单时,控件是可见的。我认为这是因为 If 语句,但我不确定。有人可以帮我解决这个问题吗?

Imports System.IO
'Imports System.Diagnostics

Public Class Settings
  Public watchfolder As FileSystemWatcher
  Private Sub Settings_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    txt_watchpath.Text = "D:\temp"
    If txt_watchpath.Text = "" Then
        btn_startwatch.Enabled = False
    End If
  End Sub

  Private Sub txt_watchpath_TextChanged(sender As Object, e As EventArgs) Handles txt_watchpath.TextChanged
    If Me.Text <> "" Then
        btn_startwatch.Enabled = True
    End If
  End Sub

  Private Sub btn_startwatch_Click(sender As Object, e As EventArgs) Handles btn_startwatch.Click
    watchfolder = New System.IO.FileSystemWatcher()

    'this is the path we want to monitor
    watchfolder.Path = txt_watchpath.Text

    'Add a list of Filter we want to specify
    'make sure you use OR for each Filter as we need to
    'all of those 

    watchfolder.NotifyFilter = IO.NotifyFilters.DirectoryName
    watchfolder.NotifyFilter = watchfolder.NotifyFilter Or
    IO.NotifyFilters.LastWrite
    watchfolder.NotifyFilter = watchfolder.NotifyFilter Or
    IO.NotifyFilters.Attributes

    ' add the handler to each event
    AddHandler watchfolder.Changed, AddressOf logchange
    AddHandler watchfolder.Created, AddressOf logchange
    'AddHandler watchfolder.Deleted, AddressOf logchange

    ' add the rename handler as the signature is different
    AddHandler watchfolder.Renamed, AddressOf logrename

    'Set this property to true to start watching
    watchfolder.EnableRaisingEvents = True
    watchfolder.IncludeSubdirectories = False

    btn_startwatch.Enabled = False
    btn_stop.Enabled = True
    Me.Hide()

    'End of code for btn_start_click
  End Sub

  Private Sub logchange(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)

    If e.ChangeType = IO.WatcherChangeTypes.Changed Then
        FrmPopup.Fullpath = e.FullPath
        FrmPopup.Activity = e.Name & " is changed"
        FrmPopup.Show()
    End If

    If e.ChangeType = IO.WatcherChangeTypes.Created Then
        FrmPopup.Fullpath = e.FullPath
        FrmPopup.Activity = e.Name & " is made"
        test.Show()
    End If
   
  End Sub

  Private Sub logrename(ByVal source As Object, ByVal e As System.IO.RenamedEventArgs)

    FrmPopup.Fullpath = e.FullPath
    FrmPopup.Activity = e.OldName & " is changed to " & e.Name
    FrmPopup.Show()

  End Sub

  Private Sub btn_stop_Click(sender As Object, e As EventArgs) Handles btn_stop.Click
    FrmPopup.Show()
  End Sub
End Class

【问题讨论】:

  • 向我们展示您用于通过单击加载表单的代码与此代码。我在发布的代码中没有看到 `=New FrmPopup()`。
  • @LarsTech,我将完整的代码放入问题中。在`Private Sub btn_stop_Click(sender As Object, e As EventArgs) Handles btn_stop.Click`中是按钮点击语句来显示弹出表单。弹出表单只是一个带有两个标签和一个按钮的表单。当我点击按钮时。控件在弹出表单中可见。
  • test.Show() 在做什么?
  • 同FrmPopup.Show()。它是另一种带有按钮的表单。只是看看 FrmPopup 是否有问题。

标签: vb.net winforms


【解决方案1】:

FileSystemWatcher 事件不是由 UI 线程生成的。 要进入你的 UI 线程,你需要使用这样的东西:

Private Sub logchange(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)

    If InvokeRequired Then
        Me.Invoke(New MethodInvoker(Sub()

                                        If e.ChangeType = IO.WatcherChangeTypes.Changed Then
                                            FrmPopup.Fullpath = e.FullPath
                                            FrmPopup.Activity = e.Name & " is changed"
                                            FrmPopup.Show()
                                        End If

                                        If e.ChangeType = IO.WatcherChangeTypes.Created Then
                                            FrmPopup.Fullpath = e.FullPath
                                            FrmPopup.Activity = e.Name & " is made"
                                            test.Show()
                                        End If

                                    End Sub))
    End If

End Sub

Private Sub logrename(ByVal source As Object, ByVal e As System.IO.RenamedEventArgs)

    If InvokeRequired Then
        Me.Invoke(New MethodInvoker(Sub()

                                        FrmPopup.Fullpath = e.FullPath
                                        FrmPopup.Activity = e.OldName & " is changed to " & e.Name
                                        FrmPopup.Show()

                                    End Sub))
    End If

End Sub

【讨论】:

  • 避免这种情况,因为 FileSystemWatcher 用于检查不在 UI 线程内的文件。否则没有意义。
  • Re 避免这种情况 - 可能需要告诉微软,'cos it's what they do..
  • SynchronizingObject(我们所说的)的默认值为NULL。这是一个参数,是可选的,并且 FileSystemWatcher 生成的事件是由系统而不是您的应用程序生成的,这是有充分理由的。 FileSystemWatcher 的使用场景不会在 FileSystemWatcher 正在侦听时请求 Form/Control/UI 处于活动状态。所以我重复一遍。避免使用 SynchronizingObject。微软有很多方法可以避免,或者说只在特定情况下使用。
猜你喜欢
  • 2015-08-31
  • 1970-01-01
  • 1970-01-01
  • 2019-10-21
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多