2015-10-20 3 views
0

Я пытаюсь написать функцию в приложении 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 и как это сделать?

ответ

1

В соответствии с MSDN IsLoaded является свойством элемента структуры, который указывает, был ли загружен элемент управления для представления, не, загружена ли веб-страница элемента управления WebBrowser.

Пока я вопрос, почему вы бы создать экземпляр браузера и он перейти на страницу в методе, называемом «GetHeight» ... то, что я думаю, что вы хотите сделать здесь подписаться на событие LoadCompleted: https://msdn.microsoft.com/en-us/library/system.windows.controls.webbrowser.loadcompleted(v=vs.110).aspx

Возможно, вы можете создать свой веб-браузер и провести его по другому методу и подписаться на событие LoadCompleted с помощью метода GetHeight?

Редактировать Я забыл упомянуть, что, поскольку вы объявили свой контроль браузера за пределами XAML, управление никогда не будет загружен (и, таким образом, navgiation не будет работать), потому что это не в визуальном дереве приложения WPF. Вам придется либо использовать WebBrowser уже объявленной в 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> 

класса MainWindow

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.stackoverflow.com") 

    AddHandler wb.LoadCompleted, Sub(s, ee) DoSomething() 
End Sub 

Private Sub DoSomething() 
    MessageBox.Show("blah") 
End Sub 

End Класс

+0

Спасибо за ваш ответ. Это действительно помогло. Действительно, я должен добавить WebBrowser в Visual Tree; иначе он не будет перемещаться. Кстати, я решил другую проблему, вставив FormsApplication.DoEvents() внутри цикла и смог вернуть целочисленное значение из функции. Ответ на ваш вопрос «почему мне нужно создать WebBrowser и вернуть его высоту из функции»: Мне нужно было настроить высоту iframe с заданной шириной таким образом, чтобы iframe соответствовал его контенту. – Zagavarr

+0

@ Zagavarr, 'DoEvents' - это плохая бандад для этого. Этот ответ - лучший маршрут. – OneFineDay

+1

@Rowbear, метод 'DoSomething' должен быть' Sub', так как он не должен или ничего не должен возвращать. – OneFineDay