如何在函数内等待事件?
How to wait for the event inside a function?
我正在尝试在 VB.Net WPF 应用程序中编写一个函数,用于在 MS WebBrowser 控件中检索文档的高度。只有在页面呈现后一段时间后,我才能获得此值。所以,我尝试了:
Private Function GetHeight(ByVal htmlstring As String) As Integer
Dim wb As New WebBrowser 'Declare WebBrowser
wb.Width = 940 'set Width
wb.NavigateToString(htmlstring) 'Navigate to content
Do Until wb.IsLoaded 'Wait until page is rendered
Loop
'Get DOM Document
Dim doc As mshtml.HTMLDocument = wb.Document
'Get sought value
Dim RetVal As Integer = CInt(doc.body.getAttribute("scrollHeight").ToString)
doc = Nothing : wb.Dispose() : wb = Nothing 'Free variables
Return RetVal 'Return value
End Function
但是调用这样的函数会导致应用程序冻结。我应该怎么办?我是否需要实现 Async 和 Await 关键字以及 Threading.Tasks 以及如何实现?
根据 MSDN,IsLoaded 是一个框架元素 属性,它指示控件是否已加载用于显示,不是WebBrowser 控件的网页是否已加载已加载。
虽然我质疑您为什么要实例化一个浏览器并让它在一个名为 "GetHeight" 的方法中导航到一个页面...我认为您想在这里做的是订阅 LoadCompleted 事件:https://msdn.microsoft.com/en-us/library/system.windows.controls.webbrowser.loadcompleted(v=vs.110).aspx
也许您可以构建您的网络浏览器并让它以不同的方法导航,然后使用您的 GetHeight 方法订阅 LoadCompleted 事件?
编辑 我忽略了因为你在 xaml 之外声明了你的浏览器控件,控件将永远不会被加载(因此,导航将不起作用) 因为它不在 WPF 应用程序的可视化树中。您必须使用已经在 xaml 中声明的网络浏览器(我会推荐),或者使用如下内容以编程方式添加它:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel x:Name="MainPanel">
<Button Click="Button_Click"> Clicky</Button>
</StackPanel>
Class 主窗口
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
Dim wb As New WebBrowser 'Declare WebBrowser
wb.Width = 940 'set Width
Me.MainPanel.Children.Add(wb)
wb.NavigateToString("www.whosebug.com")
AddHandler wb.LoadCompleted, Sub(s, ee) DoSomething()
End Sub
Private Sub DoSomething()
MessageBox.Show("blah")
End Sub
结束Class
我正在尝试在 VB.Net WPF 应用程序中编写一个函数,用于在 MS WebBrowser 控件中检索文档的高度。只有在页面呈现后一段时间后,我才能获得此值。所以,我尝试了:
Private Function GetHeight(ByVal htmlstring As String) As Integer
Dim wb As New WebBrowser 'Declare WebBrowser
wb.Width = 940 'set Width
wb.NavigateToString(htmlstring) 'Navigate to content
Do Until wb.IsLoaded 'Wait until page is rendered
Loop
'Get DOM Document
Dim doc As mshtml.HTMLDocument = wb.Document
'Get sought value
Dim RetVal As Integer = CInt(doc.body.getAttribute("scrollHeight").ToString)
doc = Nothing : wb.Dispose() : wb = Nothing 'Free variables
Return RetVal 'Return value
End Function
但是调用这样的函数会导致应用程序冻结。我应该怎么办?我是否需要实现 Async 和 Await 关键字以及 Threading.Tasks 以及如何实现?
根据 MSDN,IsLoaded 是一个框架元素 属性,它指示控件是否已加载用于显示,不是WebBrowser 控件的网页是否已加载已加载。
虽然我质疑您为什么要实例化一个浏览器并让它在一个名为 "GetHeight" 的方法中导航到一个页面...我认为您想在这里做的是订阅 LoadCompleted 事件:https://msdn.microsoft.com/en-us/library/system.windows.controls.webbrowser.loadcompleted(v=vs.110).aspx
也许您可以构建您的网络浏览器并让它以不同的方法导航,然后使用您的 GetHeight 方法订阅 LoadCompleted 事件?
编辑 我忽略了因为你在 xaml 之外声明了你的浏览器控件,控件将永远不会被加载(因此,导航将不起作用) 因为它不在 WPF 应用程序的可视化树中。您必须使用已经在 xaml 中声明的网络浏览器(我会推荐),或者使用如下内容以编程方式添加它:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel x:Name="MainPanel">
<Button Click="Button_Click"> Clicky</Button>
</StackPanel>
Class 主窗口
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
Dim wb As New WebBrowser 'Declare WebBrowser
wb.Width = 940 'set Width
Me.MainPanel.Children.Add(wb)
wb.NavigateToString("www.whosebug.com")
AddHandler wb.LoadCompleted, Sub(s, ee) DoSomething()
End Sub
Private Sub DoSomething()
MessageBox.Show("blah")
End Sub
结束Class