首页 > 解决方案 > FlowLayoutPanel 清除后不显示多个控件

问题描述

我的程序使用 selenium、HTTP 请求和称为 HtmlAgilityPack 的 HTML 解析器自动执行网站上的流程。

此过程的某些部分需要用户输入,而硬编码值无法自动填写这些输入。允许用户控制网站来填写这些输入是错误的。很难知道他们何时完成输入,并且他们可能会触摸他们不应该触摸的东西,这会在网站控制权交还给程序时导致错误。

相反,我使用 selenium 下载网站的页面源代码,并使用 HtmlAgilityPack 从 HTML 中解析输入。然后动态生成匹配这些输入的控件并将其添加到 FlowLayoutPanel。FlowLayoutPanel 第一次正常工作。它显示所有添加的控件。当用户完成后,他们点击一个按钮并继续该过程。

有时该过程会遇到错误,导致它循环回到用户需要再次输入输入的位置。之前工作的确切代码然后再次在同一个子例程中运行。这一切都按预期运行,没有错误。我在运行时手动检查了控件是否已添加到 FlowLayoutPanel,它们的大小是否大于 0、0,并且它们是可见颜色。然而,无论有多少应该可见,FlowLayoutPanel 中都只会显示一个控件。

FlowLayoutPanel 的AutoScroll属性设置为true,并且有足够的空间来添加更多控件。正如我所说,这第一次很好用,但第二次就不行了。我已经坚持了一段时间,希望能得到一些帮助。代码将在下面发布,供您查看。

我要发布的代码有几个 FlowLayoutPanel。一个是在设计器中创建的永久在窗体上,另一个是动态生成的以对控件进行分组。

问题在于永久性问题。正如我所说,它显示了一个控件。该控件是第一个动态生成的流布局面板及其所有子项。它不显示添加到其中的任何其他 FlowLayoutPanel 控件。只是先添加哪个。

对于那些想知道FLPOutOfStock.ImprovedClear()下面代码中的行的人,.Improved clear 是我编写的扩展方法。使用普通方法清除 FlowLayoutPanel 时.Clear(),控件会被删除,但不会被丢弃。我的方法处理面板中的所有控件,然后调用Clear()面板上的方法。

我意识到这种Clear()方法在他们被处理后就没有必要了,它只是一个备份,因为似乎没有任何效果。我想确保面板已完全重置。

这是代码:

Private Sub UIOutOfStockState_Load()
    Try
        cmdOutOfStockDeleteAll.Enabled = False
        cmdOutOfStockContinue.Enabled = False
        FLPOutOfStock.ImprovedClear() 'The flowlayoutpanel that does not display all controls
        With New WebDriverWait(ChromeDriver, TimeSpan.FromSeconds(20)).Until(Function(driver) CBool((CType(driver, IJavaScriptExecutor)).ExecuteScript("return jQuery.active == 0")))
        End With
        LBLOutOfStockErrors.Text = "Notice. The following items are out of stock. Please see below for product-specific availability dates. If you have any questions, please contact Customer Service at (800) 843-2020. All direct to patient orders will ship complete. The entire order will ship when out-of-stock product becomes available."
        Dim OutOfStockDoc As New HtmlAgilityPack.HtmlDocument
        OutOfStockDoc.LoadHtml(ChromeDriver.PageSource)
        Dim OutOfStockProductNodes As HtmlAgilityPack.HtmlNodeCollection = OutOfStockDoc.DocumentNode.SelectNodes("//div[contains(@id,'id_detail_item_')]")
        FLPOutOfStock.SuspendLayout()
        If OutOfStockProductNodes IsNot Nothing Then
            For Each OutOfStockProductNode As HtmlAgilityPack.HtmlNode In OutOfStockProductNodes
                Dim FLPOutOfStockProduct As New FlowLayoutPanel
                FLPOutOfStockProduct.SuspendLayout()
                FLPOutOfStockProduct.FlowDirection = FlowDirection.LeftToRight
                FLPOutOfStockProduct.AutoSize = False
                FLPOutOfStockProduct.Size = New Size(420, 160)
                FLPOutOfStock.Controls.Add(FLPOutOfStockProduct)
                Dim WBProductText As New WebBrowser
                WBProductText.Size = New Size(400, 120)
                WBProductText.AllowNavigation = False
                WBProductText.AllowWebBrowserDrop = False
                WBProductText.IsWebBrowserContextMenuEnabled = False
                WBProductText.ScriptErrorsSuppressed = True
                WBProductText.ScrollBarsEnabled = True
                WBProductText.Margin = New Padding(0, 0, 0, 0)
                WBProductText.Padding = New Padding(0, 0, 0, 0)
                WBProductText.Navigate("about:blank")
                Dim ProductTextHtmlDoc As New HtmlAgilityPack.HtmlDocument
                ProductTextHtmlDoc.LoadHtml(OutOfStockProductNode.OuterHtml)
                ProductTextHtmlDoc.DocumentNode.SelectSingleNode("/descendant::a[@id='patient-outOfStock-delete-item']").Remove()
                WBProductText.DocumentText = ProductTextHtmlDoc.DocumentNode.OuterHtml
                FLPOutOfStockProduct.Controls.Add(WBProductText)
                FLPOutOfStockProduct.SetFlowBreak(WBProductText, True)
                Dim SpaceReducer0 As New Panel
                SpaceReducer0.Size = New Size(0, 0)
                FLPOutOfStockProduct.Controls.Add(SpaceReducer0)
                Dim cmdProductDeleteButton As New Button
                cmdProductDeleteButton.Text = "Delete"
                cmdProductDeleteButton.BackColor = Color.White
                cmdProductDeleteButton.ForeColor = Color.Black
                cmdProductDeleteButton.Margin = New Padding(0, 0, 0, 0)
                cmdProductDeleteButton.Padding = New Padding(0, 0, 0, 0)
                cmdProductDeleteButton.Size = New Size(400, 20)
                Dim OnClickAttributeValueWithQuoteEscaping As String = OutOfStockProductNode.SelectSingleNode("/descendant::a[@id='patient-outOfStock-delete-item']").GetAttributeValue("onclick", "")
                cmdProductDeleteButton.Tag = "//a[@id='patient-outOfStock-delete-item' and (@onclick=""" & OnClickAttributeValueWithQuoteEscaping & """)]"
                AddHandler cmdProductDeleteButton.Click, AddressOf cmdProductDeleteButton_Click
                FLPOutOfStockProduct.Controls.Add(cmdProductDeleteButton)
                FLPOutOfStockProduct.SetFlowBreak(cmdProductDeleteButton, True)
                Dim SpaceReducer1 As New Panel
                SpaceReducer1.Size = New Size(0, 0)
                FLPOutOfStockProduct.Controls.Add(SpaceReducer1)
                FLPOutOfStockProduct.ResumeLayout()
            Next
            FLPOutOfStock.ResumeLayout()
            FLPOutOfStock.Refresh()
        End If
        cmdOutOfStockDeleteAll.Enabled = True
        cmdOutOfStockContinue.Enabled = True
    Catch Ex As Exception
        cmdOutOfStockDeleteAll.Enabled = True
        cmdOutOfStockContinue.Enabled = True
    End Try
End Sub

所以我被要求展示改进后的清除方法中的内容。这里是:

<Extension()>
Public Function ImprovedClear(ByRef Control as Control)
    For Each controlchild as control in control.controls
        Control.Dispose()
    Next
    Control.Controls.Clear()
    Return Nothing
End Function

标签: vb.netwinformscontrolsflowlayoutpanel

解决方案


推荐阅读