How to call a WCF service in my client application form - vb.net

I am new to VB.NET and am completely lost on a project. I currently have a service that contains many methods such as GetCustomersAll, GetCustomersByPhone, etc. I am now trying to consume the service with my Windows Form Application. Currently I have a service reference set up but I am just lost when it comes to programming the button in my form. I would like the button to call on the GetCustomersAll method from my service but every time I fix one error another one presents itself. So far this is the code I have:
Private Sub btnAllCustomers_Click(sender As Object, e As EventArgs) Handles btnAllCustomers.Click
Dim MyService As Demo2ServiceReference.Service1Client = New Demo2ServiceReference.Service1Client
Dim MyResult As Demo2ServiceReference.Customer
MyResult = MyService.GetCustomersAll()
lblAllCustomers.Text = "Customer Id: " & MyResult.CustomerId & ", Customer Name: " & MyResult.FirstName & " " & MyResult.LastName & "<br/>"
End Sub
When I run this bit of code I get an error on "MyService.GetCustomersAll()" which says "Value of type '1-dimensional array of DemoWindowsApplication.Demo2ServiceReference.Customer' cannot be converted to 'DemoWindowsApplication.Demo2ServiceReference.Customer'.
**When I change MyResult to an array (Demo2ServiceReference.Customer()) I then get errors on my returns inside my label. MyResult.CustomerId and the rest turn into errors stating "CustomerId" is not a member of "System.Array".
This is all guess work. I honestly have no idea where to start when it comes to coding this button. If anyone has some advice or suggestions it would be much appreciated. If I have left out important information needed to assist me with this please let me know.

Related

VB.Net Visual basic Adding a custom event in the Webbrowser control that calls a routine in the main application

I'm trying to create and call a custom event in the webbrowser control and everything that I've tried to do causes one error or another when the webpage executes the code. What I'm doing is adding a button on each row of a table to facilitate removing that row. However, the master list of data is in the application. When the script in the web page executes, I need to update the master list in the application. My thoughts were to call a custom event that will be fired in my application where I can do everything that I need to do. I just can't make this work. here are more details of what I have right now. Here is the html code for a given row:
Dim M As String = "</TD><TD>"
RetStr.Append("<TR ID='" & Me.Manifest & "' name='" & Me.Manifest & "'>")
RetStr.Append("<TD>").Append(CompanyID).Append(M).Append(CompanyName).Append(M)
RetStr.Append(ContactName).Append(M).Append(Address1).Append(M).Append(Address2)
RetStr.Append(M).Append(City).Append(M).Append(State).Append(M)
RetStr.Append(Zip).Append(M).Append(Phone).Append("</TD>")
RetStr.Append("<TD><button onclick='deleteRow(""" & Me.Manifest & """)'>Remove</button></TD>")
Return Replace(RetStr.ToString(), "<TD></TD>", "<TD> </TD>")
Here is the code that is in the function:
Dim HTMLOut As New List(Of String)
HTMLOut.Add("<HEAD>")
HTMLOut.Add(" <SCRIPT language=""VBScript"">")
HTMLOut.Add(" Function deleteRow(rowid)")
HTMLOut.Add(" set row = document.getElementById(rowid)")
HTMLOut.Add(" row.parentNode.removeChild(row)")
HTMLOut.Add(" dispatchEvent(Row)")
HTMLOut.Add(" End Function")
HTMLOut.Add(" </SCRIPT>")
HTMLOut.Add("</HEAD>")
HTMLOut.Add("<BODY>")
HTMLOut.Add(" <TABLE border='1' style='font-size:12;' NAME='Table' ID='TABLE'>")
Here is the code that I have in the application:
Private Sub WB_DocumentCompleted(sender As Object, e As
WebBrowserDocumentCompletedEventArgs) Handles WB.DocumentCompleted
WB.Document.AttachEventHandler("UpdateList", New EventHandler(
Function(ByVal s As Object, ByVal k As EventArgs)
MsgBox("BOO")
Return True
End Function))
End Sub
Any help in any direction, even if it means I need to change how I'm doing all of this, is very welcomed! There is more code then this, it's stripped down to what is needed to convey what I'm doing. I know I'm missing something, I just can't figure out what it is. The end goal is to update the master list in the application hosting the web browser; ideas suggestions and comments are always welcome. As a side note, I'm using the web browser control because the final part of the process is to create a file and sftp it to the vender (the application will do this), and print the report. Thanks!
I figured this out. I needed to create a class object, with the comvisible attribute set and add this to the objectForScripting property of the web browser control.
Imports System.Runtime.InteropServices
<ComVisible(True)> Public Class WBClassCode
Public Sub UpdateStuff(ByVal Data)
'My code goes here... called from the web page.
MsgBox("boo")
End Sub
End Class

spell checking richtextbox in winforms project

I have a WinForms project that contains a RichTextBox (RTB) written with VB
I have set ShortcutsEnabled = FALSE in the RTB
To use any Spell Checker I am guessing this would need to set to TRUE
That is NOT my question! I have been reading for way more hours than I care to admit
With the understanding that Spell Checking is easy if you have a ASP.Net OR WPF project
Well I don't so here are the three candidates from NuGet NONE of these candidates offer much help
WeCantSpell.Hunspell and VPKSoft.SpellCheckUtility and NetSpell
I am not asking for a recommendation
Because I can not find a tutorial and am clueless on how to implement these Add In's with code
As well as NOT knowing if they are compatible with WinForms
I even looked at this CP post
CP LINK
Just a suggestion how to use one of these Add In's OR how to add spell checking to the RTB?
To achieve spell checking, you can try Nuget Package NHunspell.
First, you need to add "NHunspell" from "NuGet" and import it. The specific operation is as follows:
Right click the Reference and select "Manage NuGet Packages...", then type "NHunspell " in the search bar and install it:
Second step, you need to create a folder to store ".aff" and ".dic" like this.
Download the "zip" containing the corresponding file, you can access this site.
Here is a demo you can refer to.
Private Sub btCheck_Click(sender As Object, e As EventArgs) Handles btCheck.Click
Dim affFile As String = AppDomain.CurrentDomain.BaseDirectory & "../../Dictionaries/en_us.aff"
Dim dicFile As String = AppDomain.CurrentDomain.BaseDirectory & "../../Dictionaries/en_us.dic"
lbSuggestion.Items.Clear()
lbmorph.Items.Clear()
lbStem.Items.Clear()
Using hunspell As New Hunspell(affFile, dicFile)
Dim correct As Boolean = hunspell.Spell(TextBox1.Text)
checklabel.Text = TextBox1.Text + " is spelled " & (If(correct, "correct", "not correct"))
Dim suggestions As List(Of String) = hunspell.Suggest(TextBox1.Text)
countlabel.Text = "There are " & suggestions.Count.ToString() & " suggestions"
For Each suggestion As String In suggestions
lbSuggestion.Items.Add("Suggestion is: " & suggestion)
Next
Dim morphs As List(Of String) = hunspell.Analyze(TextBox1.Text)
For Each morph As String In morphs
lbmorph.Items.Add("Morph is: " & morph)
Next
Dim stems As List(Of String) = hunspell.Stem(TextBox1.Text)
For Each stem As String In stems
lbStem.Items.Add("Word Stem is: " & stem)
Next
End Using
End Sub
The result,
Hope this can help you.

VB6 Error Handling in Properties -> Best practise?

im using CodeSmart 2013 to analyze my VB6 projects.
The review function says i should add error handling (or at least "on error resume next") to my class-properties.
My properties typically look like this (in 99% cases):
Public Property Let PLZ(ByVal strPlz As String)
myStrPLZ = strPlz
End Property
Public Property Get PLZ() As String
PLZ = myStrPLZ
End Property
When i automatically add error handling it would look like this:
Public Property Let PLZ(ByVal strPlz As String)
'<EhHeader>
On Error GoTo PLZ_Err
'</EhHeader>
myStrPLZ = strPlz
'<EhFooter>
Exit Property
PLZ_Err:
MsgBox Err.Description & vbCrLf & _
"in TNV.frmSucheTeilnehmer.PLZ " & _
"at line " & Erl, _
vbExclamation + vbOKOnly, "Application Error"
Resume Next
'</EhFooter>
End Property
Public Property Get PLZ() As String
'<EhHeader>
On Error GoTo PLZ_Err
'</EhHeader>
PLZ = myStrPLZ
'<EhFooter>
Exit Property
PLZ_Err:
MsgBox Err.Description & vbCrLf & _
"in TNV.frmSucheTeilnehmer.PLZ " & _
"at line " & Erl, _
vbExclamation + vbOKOnly, "Application Error"
Resume Next
'</EhFooter>
End Property
is anyone practically doing error handling in properties? is this best practise? because this would be a lot of additional code to my projects (code overview decreases imho)
Thx for help!
Greetings from germany
SLimke
You should add error handling in just the same way as you would in any method (Sub/Function).
My rule of thumb is that if the method is only a couple of lines long and doesn't do anything exotic then there is no error handling required. The same can be said of a property Get/Set
Yes adding error handling to all your property getters and setters generates a lot of code so one option could be to use centralised error handling. See this post for some discussion of this: Centralized error handling in VB6
Don't take these guidelines (especially from a program written by someone with their own opinion of what "best practice" entails). I've never used it so I can't speak (nor do I doubt) it's quality... just saying.
MarkJ is also right. If you don't need any validation on property setting then just make them public variables. If you later need to add validation, making them into private variables and having the public Property Get/Let/Set instead won't break the interface and no other code changes are needed.
As for adding error handlers in every class property get/let? Why? Personally, I assume if someone is going to use my class they will at least take a moment to make sure they know what the !##$ they are doing and how to use it. If they set a property so incorrectly that it causes a runtime (or compile-time) error then they will know right away.
If the value for setting the property is coming from the user, i.e.
MyClass.SomeProperty = Input("Enter something: ")
Then I personally think the error code should be placed there. i.e.
On Error GoTo StupidUser
MyClass.SomeProperty = Input("Enter something: ")
Exit Sub
ErrorHandler:
MsgBox "You did not supply a correct value!", vbExclamation
Otherwise, what are you going to do when you handle an error in your class? Pass it on to a centralized error handler which will just create more code to follow and end up with the same result? The user being notified/written to a log/etc.?
I (again, personally... programming isn't black & white) prefer to put error handling code in the caller routine... the procedure that's using the class, setting properties, etc.
Any sort of "code optimizer/checker" is written by a person or multiple, and even reputable ones will bring up debate among those who use it on how it should work.
TL;DR: some recommendations can be safely ignored.
Why not use public fields instead of these boilerplate properties?
Public PLZ As String
If you later need to add logic, no problem! You can convert public fields to properties without breaking clients.

VB.NET/WMI - Real-Time Windows Service Monitoring?

So there's an application at my work that installs several Windows services to a server. As a side project, I've been asked to make a simple GUI that will list these services with a "light" (a picture box with a red or green dot) next to the name of each service. The idea is that in the event these services were to stop running, the "light" would change from green to red.
I have the GUI part built, and I can query a remote server's services, then compare it to an array of the ones I'm interested and set the "light" next to each service to green/red depending on the service state. The part I'm hung up on is how to monitor these services in real time? Currently, I just have the following code in the Form_Load event:
Dim myConnectionOptions As New System.Management.ConnectionOptions
With myConnectionOptions
.Impersonation = System.Management.ImpersonationLevel.Impersonate
.Authentication = System.Management.AuthenticationLevel.Packet
End With
Try
Dim myManagementScope As System.Management.ManagementScope
myManagementScope = New System.Management.ManagementScope("\\" & SERVERNAME & "\root\cimv2", myConnectionOptions)
myManagementScope.Connect()
Dim query As New Management.ObjectQuery("SELECT * FROM Win32_Service")
Dim searcher As New Management.ManagementObjectSearcher(myManagementScope, query)
Dim i As Integer = 0
For Each queryObj As Management.ManagementObject In searcher.Get()
For Each service As String In arrServices
If queryObj("DisplayName").Equals(service) Then
If queryObj("State").Equals("Stopped") Then
arrLights(i).Image = My.Resources.redlight
End If
i += 1
End If
Next
Next
Catch err As Management.ManagementException
MessageBox.Show("WMI query failed with the following error: " & err.Message)
Catch unauthorizedErr As System.UnauthorizedAccessException
MessageBox.Show("Authentication error: " & unauthorizedErr.Message)
End Try
Would a simple timer that executes this code repeatedly be the best approach, or is there a more elegant solution? I have a little experience in VB.NET and WMI, but none in any type of real-time monitoring activity like this.
First of all i would put it into a thread, that way even if your connection times out you dont freeze your UI, then i would use a custom wait timer not the built in one as cross threading can be a pain.
wait timer:
Public Sub Wait(ByVal wait_time As Integer)
Dim time As Date
time = Now.AddMilliseconds(wait_time)
Do While time > Now
Application.DoEvents()
Loop
End Sub
example of threading:
Private services_check As Thread
private sub form1_load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
services_check = new thread(AddressOf 'Current code in a public sub')
services_cheack.IsBackground = True
Services_check.start()
It may not be the most elegant solution but its how i would do it, as for your current code im sorry i dont know enough about remote connections to help you.

Accessing Form1 Properties From Thread

I have an exceptionhandler function that basically just writes a line to a textbox on Form1. This works fine when being run normally but the second I use a thread to start a process it cannot access the property. No exception is thrown but no text is written to the textbox:
Public Sub ExceptionHandler(ByVal Description As String, Optional ByVal Message As String = Nothing)
' Add Error To Textbox
If Message = Nothing Then
Form1.txtErrLog.Text += Description & vbCrLf
Log_Error(Description)
Else
Form1.txtErrLog.Text += Description & " - " & Message & vbCrLf
Log_Error(Description, Message)
End If
MessageBox.Show("caught")
End Sub
Is it possible to access a form's properties from a thread this way or would it be easier to write to a text file or similar and refresh the textbox properties every 10 seconds or so (Don't see this as a good option but if it's the only way it will have to do!).
Also, still new to VB so if I have done anything that isn't good practice please let me know!
No, you shouldn't access any GUI component properties from the "wrong" thread (i.e. any thread other than the one running that component's event pump). You can use Control.Invoke/BeginInvoke to execute a delegate on the right thread though.
There are lots of tutorials around this on the web - many will be written with examples in C#, but the underlying information is language-agnostic. See Joe Albahari's threading tutorial for example.
You have to use delegates. Search for delegates in VB.
Here a peace of code that does the job.
Delegate Sub SetTextCallback(ByVal text As String)
Public Sub display_message(ByVal tx As String)
'prüfen ob invoke nötig ist
If Me.RichTextBox1.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf display_message)
Me.Invoke(d, tx)
Else
tx.Trim()
Me.RichTextBox1.Text = tx
End If
End Sub