How to open dynamic WebBrowser link address in new window form? - vb.net

I have found the error at href so please help me
Private Sub WebBrowser1_NewWindow(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles WebBrowser1.NewWindow
Dim thiselement As HtmlElement = WebBrowser1.Document.ActiveElement
Dim targeturl As String = thiselement.GetAttribute("href")
e.Cancel = True
Dim window As New Form1
window.Show()
window.WebBrowser1.Navigate(targeturl)
End Sub
at "href" i have found error like Object reference not set to an instant of object.
my code is in vb.net 2010.

WebBrowser1.Document.ActiveElement is returning Nothing because there is no active element. Therefore when you attempt to use targeturl, you get this error: Object reference not set to an instant of object

Handle the Navigating event. Example:
webBrowser1.Navigating += Function(source, args)
Dim uriClicked = args.Uri
' Create your new form or do whatever you want to do here
End Function

Related

How to Convert string to Generic Of T?

How I call generic Of T sub choose form string?
How to better way code like this?
Sub ShowAddfrm(Of T As {Form, New})()
dim frm as new T 'New Form
frm.Show()
End Sub
Private Sub btnAddProblemfrm_Click(sender As Object, e As EventArgs)
Dim keys As String = CType(sender, Button).Name.Replace("btnAdd", "")
If keys = "frmShowProblem" Then
ShowAddfrm(Of frmShowProblem)()
End If
If keys = "frmUser" Then
ShowAddfrm(Of frmUser)()
End If
End Sub
Try this overloaded method, allowing both a Form reference and string parameter.
You can pass the default instance of a Form, naming it directly:
ShowAddfrm(Form2)
or the Form's name:
ShowAddfrm("Form2")
or using a Control's Tag property (or any other source) in an event handler:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ShowAddfrm(DirectCast(sender, Control).Tag.ToString())
End Sub
There's a difference:
if you use pass the instance of a Form, only that instance will be created. Meaning, if you use a Button to show the Form and you press the Button multiple times, no new instances will be created. If you close the Form, then a new instance will be shown.
If you use the string version, each time you call this method, a new instance of the Form will be shown, so you can have multiple Forms on screen.
The string version uses Activator.CreateInstance to generate a new instance of a Form using it's name.
Sub ShowAddfrm(Of T As {Form, New})(ByVal form As T)
form.Show()
End Sub
Sub ShowAddfrm(formName As String)
Dim appNameSpace = Assembly.GetExecutingAssembly().GetName().Name
Dim form = CType(Activator.CreateInstance(Type.GetType($"{appNameSpace}.{formName}")), Form)
ShowAddfrm(form)
End Sub

Get Source Code from Webview (VB for Metro)

I'm Making a Windows Phone's app that I can, From a webview called "DebWeb", get the ClassRoom of a specific class. The DebWeb load the site where is all the classRooms, but I want to make that my App search just my class.
Before I made an app with almost the same objetive (search the Name of a App from the Source Code), but it was made from VB for PC, now I'm working on VB for Metro (or for App Store) and I can't use the same code.
For example, On VB for PC I can use:
Dim EHTML = DebWeb.Document.All.Item(1)
Dim sourceString As String = EHTML.InnerHtml
'Use Regex Match to search from SourceString"
But on VB for Metro it's shows me the " 'Document' is not a member of 'Windows.UI.XAML.Controls.WebView' " error, so I can't get the Source Code from the page and I can't look for the ClassRoom.
I Looked on the MSDN page about Webview but the most close thing that I can do is to get the "DocumentTittle", but not the content.
This is my code, everything "works" except the "Source" variable:
Dim Source = DebWeb.[Control] 'Here is where I need the Control to get the SourceCode
Dim m As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(Source.ToString, _
"DERECHO CONSTITUCIONAL", _
System.Text.RegularExpressions.RegexOptions.IgnoreCase)
Edited with my Entire code:
Private Sub MainPage_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
Dim URL As String = "http://goo.gl/uqohKw"
Me.DebWeb.Navigate(New Uri(URL))
End Sub
Private Sub DebWeb_LoadCompleted(ByVal sender As Object, ByVal e As WebViewNavigationCompletedEventArgs)
LListo.Text = "Listo!"
Dim html As String = DebWeb.InvokeScriptAsync("eval", New String() {"document.documentElement.outerHTML;"}).ToString
Dim Source = html
Dim m As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(Source.ToString, _
"LECTURA CRÍTICA", _
System.Text.RegularExpressions.RegexOptions.IgnoreCase)
If (m.Success) Then
Dim key As String = m.Groups(1).Value
End If
End Sub
Something like this?
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
Try
Dim html As String = Await myWebView.InvokeScriptAsync("eval", New String() {"document.documentElement.outerHTML;"})
Catch ex As Exception
End Try
End Sub
More Info here

How to get values from a dialog form in VB.NET?

I have a "frmOptions" form with a textbox named "txtMyTextValue" and a button named "btnSave" to save and close the form when it's clicked,
then, I'm showing this dialog form "frmOptions" when a button "btnOptions" is clicked on the main form "frmMain", like this
Private Sub btnOptions_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOptions.Click
ShowOptionsForm()
End Sub
Private Sub ShowOptionsForm()
Dim options = New frmOptions
options.ShowDialog()
End Sub
How can I get in the main form "frmMain" the value inserted in the textbox "txtMyTextValue" when the "btnSave" is clicked?
You want to capture the information from the dialog only if the result is OK (user presses Save instead of Cancel or closes the dialog some other way), so do this:
Private Sub ShowOptionsForm()
Dim options = New frmOptions
' Did the user click Save?
If options.ShowDialog() = Windows.Forms.DialogResult.OK Then
' Yes, so grab the values you want from the dialog here
Dim textBoxValue As String = options.txtMyTextValue.Text
End If
End Sub
Now inside of your dialog form, you need to set the result Windows.Forms.DialogResult.OK when the user clicks the button that corresponds to the OK action of the dialog form, like this:
Public Class frmOptions
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
' Set the result to pass back to the form that called this dialog
Me.DialogResult = Windows.Forms.DialogResult.OK
End Sub
End Class
The simplest method is to add a public property to the frmOptions form that returns an internal string declared at the global level of the frmOptions
Dim strValue As String
Public Property MyStringValue() As String
Get
Return strValue
End Get
End Property
Then, when your user clicks the OK button to confirm its choices you copy the value of the textbox to the internal variable
Private Sub cmdOK_Click(sender As Object, e As System.EventArgs) Handles cmdOK.Click
strValue = txtMyTextValue.Text
End Sub
Finally in the frmMain you use code like this to retrieve the inserted value
Private Sub ShowOptionsForm()
Using options = New frmOptions()
if DialogResult.OK = options.ShowDialog() Then
Dim value = options.MyStringValue
End If
End Using
End Sub
I prefer to avoid direct access to the internal controls of the frmOptions, a property offer a indirection that could be used to better validate the inputs given by your user.
You can use Events to take care of this. With this approach the Settings Form does not have to be Modal and the user can click the Save Button at any time.
In frmOptions:
'You can expand the signature to take more than just a single String.
Friend Event SavedOptions(ByVal strData As String)
Private Sub btnSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSave.Click
RaiseEvent SavedOptions(txtMyTextValue.Text)
End Sub
In frmMain:
Private Sub ShowOptionsForm()
Dim options = New frmOptions
AddHandler options.SavedOptions, AddressOf OnOptionsSave
options.ShowDialog()
End Sub
Private Sub OnOptionsSave(ByVal strData As String)
'Or whatever you want to do on frmMain with Options Data.
MsgBox(strData)
End Sub
You can access the value from the frmOptions instance. However, this breaks the law of demeter.
You should expose the value with a property within your class.
Public Class frmOptions
Public ReadOnly Property MyTextValue As String
Get
Return Me.txtMyTextValue.Text
End Get
End Property
End Class
Then you can access the value:
Private Sub ShowOptionsForm()
Dim options = New frmOptions
Dim frmOptionTextValue As String
Dim frmOptionsDiagResult As DialogResult
frmOptionsDiagResult = options.ShowDialog()
If frmOptionsDiagResult = Windows.Forms.DialogResult.OK Then
frmOptionTextValue = options.MyTextValue
Else
'...
End If
End Sub
Finally, if you are using a Dialog then make sure to set the Dialog Result for the button.

VB.NET WebBrowser Control Programmatically Filling Form After Changing User-Agent (Object reference not set to an instance of an object.)

I'm working on a project where I have a WebBrowser control which needs to have a custom user-agent set, then go to Google and fill out the search box, click the search button, then click a link from the search results. Unfortunately I can't use HTTPWebRequest, it has to be done with the WebBrowser control.
Before I added the code to change the user-agent, everything worked fine. Here's the code that I have:
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("urlmon.dll", CharSet:=CharSet.Ansi)> _
Private Shared Function UrlMkSetSessionOption(dwOption As Integer, pBuffer As String, dwBufferLength As Integer, dwReserved As Integer) As Integer
End Function
Const URLMON_OPTION_USERAGENT As Integer = &H10000001
Public Sub ChangeUserAgent(Agent As String)
UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, Agent, Agent.Length, 0)
End Sub
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
ChangeUserAgent("Fake User-Agent")
wb.Navigate("http://www.google.com", "_self", Nothing, "User-Agent: Fake User-Agent")
End Sub
Private Sub wb_DocumentCompleted(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs) Handles wb.DocumentCompleted
Dim Source As String = wb.Document.Body.OuterHtml
Dim Uri As String = wb.Document.Url.AbsoluteUri
If Uri = "http://www.google.com/" Then
wb.Document.GetElementById("lst-ib").SetAttribute("value", "browser info")
wb.Document.All("btnK").InvokeMember("click")
End If
If Uri.Contains("http://www.google.com/search?") Then
Dim TheDocument = wb.Document.All
For Each curElement As HtmlElement In TheDocument
Dim ctrlIdentity = curElement.GetAttribute("innerText").ToString
If ctrlIdentity = "BROWSER-INFO" Then
curElement.InvokeMember("click")
End If
Next
End If
End Sub
End Class
The problem lies in the following code:
wb.Document.GetElementById("lst-ib").SetAttribute("value", "browser info")
wb.Document.All("btnK").InvokeMember("click")
I thought the problem might be that the page not being fully loaded (frame issue) but I put the offending code in a timer to test, and got the same error. Any help would be much appreciated.
Do you realize .All("btnK") returns a collection? So, you are doing .InvokeMember("click") on a Collection :). You cannot do that, you can only do .InvokeMember("click") on an element for obvious reasons!
Try this:
wb.Document.All("btnK").Item(0).InvokeMember("click")
The .Item(0) returns the first element in the collection returned by .All("btnK"), and since there will only probably be one item returned, since there is only one on the page, you want to do the InvokeMember on the first item, being .Item(0).
May I ask what it is you are developing?
Since you're a new user, please up-vote and/or accept if this answered your question.

Calling external user control by its name

I have one panel (Panel1), two combo boxes (ComboBox1, ComboBox2) and one button (Button1) all in same form (Form1).
When the button is clicked:
Private Sub Button1_Click(sender As Object, e As EventArgs)
Dim a as String = ComboBox1.SelectedValue() & Combobox2.SelectedValue()
AddUserControl(a)
End Sub
value of a is the name of an external user control for instance p1k1.
Can I add an external user control named p1k1 to Panel1 in Form1 using following method?
Private Sub AddUserControl(ByVal a As String)
Panel1.Controls.Add(a)
End Sub
What should I do to make this work?
Usually I would use:
Panel1.Controls.Add(new p1k1)
You'll need to use reflection to do this. Something like this:
Private Sub AddUserControl(ByVal a As String)
Dim controlType As Type = Type.GetType(a)
If controlType Is Nothing Then
Throw New ArgumentException(String.Format("""{0}"" is not a valid type. Type names are case sensitive.", a))
ElseIf Not controlType.IsSubclassOf(GetType(Control)) Then
Throw New ArgumentException(String.Format("""{0}"" does not inherit from Control. Only Controls can be added to the control collection.", a))
End If
Dim newControl As Control = Activator.CreateInstance(controlType)
If newControl Is Nothing Then
Throw New ArgumentException(String.Format("Unspecified error when creating control of type ""{0}"".", a))
End If
Panel1.Controls.Add(newControl)
End Sub
i found my answer finally...
Private Sub AddUserControl(ByVal a As String)
Dim nmspace As String = "mynamespace"
Dim t As Type = Assembly.GetExecutingAssembly().GetType(nmspace & "." & a)
Dim o As Control = Activator.CreateInstance(t)
Panel1.Controls.Add(o)
End Sub