Append text to a RichTextBox from another class in VB.NET - vb.net

I have a Form (ClientGUI) that has a RichTextBox. What I want to do is to append text to this RichTextBox from a Sub located in another class (MyQuickFixApp). I know that the Sub works, because the debugger go through, but it doesn't append the text to my RichTextBox.
How do I do that ?
Thanks for you help !
ClientGUI.vb :
Imports QuickFix
Imports QuickFix.Transport
Imports QuickFix.Fields
Public Class ClientGUI
Dim initiator As SocketInitiator
Public Sub ClientGUI_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim filename As String = "Resources/initiator.cfg"
Dim settings As New SessionSettings(filename)
Dim myApp As New MyQuickFixApp()
Dim storeFactory As New FileStoreFactory(settings)
Dim logFactory As New FileLogFactory(settings)
initiator = New SocketInitiator(myApp, storeFactory, settings, logFactory)
End Sub
Public Sub ConnectToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ConnectToolStripMenuItem.Click
ToolStripDropDownButton1.Text = "Establishing connection..."
ToolStripDropDownButton1.Image = My.Resources.Connecting
initiator.Start()
End Sub
Public Sub DisconnectToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles DisconnectToolStripMenuItem.Click
ToolStripDropDownButton1.Text = "Disconnecting..."
ToolStripDropDownButton1.Image = My.Resources.Disconnecting
initiator.Stop()
End Sub
End Class
MyQuickFixApp.vb :
Imports QuickFix
Imports QuickFix.Transport
Imports QuickFix.Fields
Public Class MyQuickFixApp
Inherits MessageCracker : Implements IApplication
Dim _session As Session = Nothing
Public Sub FromAdmin(message As Message, sessionID As SessionID) Implements IApplication.FromAdmin
ClientGUI.RichTextBox1.AppendText("")
ClientGUI.RichTextBox1.AppendText("IN (ADMIN): " + message.ToString())
Try
Crack(message, sessionID)
Catch ex As Exception
ClientGUI.RichTextBox1.AppendText("")
ClientGUI.RichTextBox1.AppendText("==Cracker exception==")
ClientGUI.RichTextBox1.AppendText(ex.ToString())
ClientGUI.RichTextBox1.AppendText(ex.StackTrace)
End Try
End Sub
Public Sub FromApp(message As Message, sessionID As SessionID) Implements IApplication.FromApp
ClientGUI.RichTextBox1.AppendText("")
ClientGUI.RichTextBox1.AppendText("IN (APP): " + message.ToString())
Try
Crack(message, sessionID)
Catch ex As Exception
ClientGUI.RichTextBox1.AppendText("")
ClientGUI.RichTextBox1.AppendText("==Cracker exception==")
ClientGUI.RichTextBox1.AppendText(ex.ToString())
ClientGUI.RichTextBox1.AppendText(ex.StackTrace)
End Try
End Sub
Public Sub ToApp(message As Message, sessionId As SessionID) Implements IApplication.ToApp
Try
Dim possDupFlag As Boolean = False
If (message.Header.IsSetField(Tags.PossDupFlag)) Then
possDupFlag = Converters.BoolConverter.Convert(message.Header.GetField(Tags.PossDupFlag))
End If
If (possDupFlag) Then
Throw New DoNotSend()
End If
Catch ex As FieldNotFoundException
ClientGUI.RichTextBox1.AppendText("OUT (APP): " + message.ToString())
End Try
End Sub
Public Sub OnCreate(sessionID As SessionID) Implements IApplication.OnCreate
'_session = Session.LookupSession(sessionID)
ClientGUI.RichTextBox1.AppendText("Session created - " + sessionID.ToString())
End Sub
Public Sub OnLogon(sessionID As SessionID) Implements IApplication.OnLogon
ClientGUI.RichTextBox1.AppendText("Logon - " + sessionID.ToString())
ClientGUI.ToolStripDropDownButton1.Text = "Connected"
ClientGUI.ToolStripDropDownButton1.Image = My.Resources.Connected
'MsgBox("onlogon")
End Sub
Public Sub OnLogout(sessionID As SessionID) Implements IApplication.OnLogout
ClientGUI.RichTextBox1.AppendText("Logout - " + sessionID.ToString())
ClientGUI.ToolStripDropDownButton1.Text = "Disconnected"
ClientGUI.ToolStripDropDownButton1.Image = My.Resources.Disconnected
End Sub
Public Sub ToAdmin(message As Message, sessionID As SessionID) Implements IApplication.ToAdmin
ClientGUI.RichTextBox1.AppendText("OUT (ADMIN): " + message.ToString())
End Sub
Public Sub OnMessage(message As FIX42.Heartbeat, sessionID As SessionID)
ClientGUI.RichTextBox1.AppendText("HEARTBEAT")
End Sub
End Class

I guess that the code in MyQuickFixApp class access to the default instance of your ClientGUI, not the instance which is actually running, each time you write ClientGUI.(...).
See this thread Why is there a default instance of every form in VB.Net but not in C#? for more information about default instance, which is something you should avoid to use.
So you could add a parameter in the MyQuickFixApp class constructor :
Public Class MyQuickFixApp
Inherits MessageCracker : Implements IApplication
Dim _clientGUI As ClientGUI = Nothing
Public Sub New(cltGui As ClientGUI)
_clientGUI = cltGui
End sub
(...)
End class
Then, replace in the MyQuickFixApp class all the ClientGUI.(...), with _clientGUI.(...) to be sure to access to the correct instance.
And finally, initialize your MyQuickFixApp class in ClientGUI like this:
Dim myApp As New MyQuickFixApp(me)
Note that this code, you can only access to the method of the class in the Form_Load event. This variable should be declared in the class and initialized in the form_load if you want to access it later from the ClientGUI form.
Public Class ClientGUI
Dim initiator As SocketInitiator
Dim myApp As MyQuickFixApp()
Public Sub ClientGUI_Load(sender As Object, e As EventArgs) Handles MyBase.Load
(...)
myApp =New MyQuickFixApp(Me)
(...)
End Sub
(...)
End Class

In Form
private void button3_Click(object sender, EventArgs e)
{
TestClass tc = new TestClass();
tc.addComment(richTextBox1);
}
In Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
public class TestClass
{
public void addComment(RichTextBox rt)
{
rt.Text = rt.Text + Environment.NewLine + "My Dynamic Text";
}
}
you can do it same in VB.net also

Related

VB.net OOP How to call method in namespace from FrmMain

I am trying to make a VB.net WinForm-application that connects to a database.
I have a class with the specs to make a database-connection (Intersystems Cache). The database isn't important, the principile does.
How do I call the methods in this class form the FrmMain?
I can't get my head around it.
Thanks
Imports Test.NSConnection.Connection
Public Class FrmMain
Private Sub FrmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'how do I call the DoOpenConnectionCache?
End Sub
End Class
and:
Imports InterSystems.Data.CacheClient
Imports InterSystems.Data.CacheTypes
Imports System
Imports System.Data
Namespace NSConnection
Public Class Connection
Private _cacheString As String
Public Property cacheString() As String
Get
Return _cacheString
End Get
Set(ByVal value As String)
_cacheString = value
End Set
End Property
Private _cnCache As CacheADOConnection
Public Property cnCache() As CacheADOConnection
Get
Return _cnCache
End Get
Set(ByVal value As CacheADOConnection)
_cnCache = value
End Set
End Property
Private Sub SetConnectionString()
Dim _cacheString As String = "Server = localhost; Port = ****; Namespace = ****; User ID= **** ; Password= ****;"
Dim _cnCache = New CacheConnection(_cacheString)
End Sub
Public Sub DoOpenConnectionCache()
Try
If _cnCache.State = ConnectionState.Closed Then
_cnCache.Open()
End If
Catch ex As Exception
MessageBox.Show("Error" & vbCrLf & ex.Message)
End Try
End Sub
Public Sub DoCloseConnectionCache()
Try
If _cnCache.State = ConnectionState.Open Then
_cnCache.Close()
End If
Catch ex As Exception
MessageBox.Show("Error" & vbCrLf & ex.Message)
End Try
End Sub
End Class
End Namespace
If you want to create an object of type Connection, then you can do it like this:
Dim Connection1 As Connection = New Connection()
and call its method DoOpenConnectionCache

Converting a class with a property of T to and from json

I have a class (MyMessage) which have a property called "Settings" of Type T.
I need to convert MyMessage to json, send it via TCP and when I recieve it, I need to test what class Type T is and then convert the recieved json to the MyMessage Of T class.
This is my code so far - function SendMessage and MessageRecieved is not working ... and I need your help :)...
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim t As New MyMessage(Of MyMessageSettingsText)
t.Settings.Text = "Yes"
Call SendMessage(t)
Dim n As New MyMessage(Of MyMessageSettingsNumber)
n.Settings.Number = 1
Call SendMessage(n)
End Sub
Private Sub SendMessage(msg As MyMessage)
Dim json As String = Newtonsoft.Json.JsonConvert.SerializeObject(msg)
' Do send using tcp etc
End Sub
Private Sub MessageRecieved(msgJson As String) ' A json string recived from a tcp server
Dim msg As MyMessage = DirectCast(Newtonsoft.Json.JsonConvert.DeserializeObject(Of MyMessage)(msgJson), MyMessage)
If TypeOf (msg.Settings) Is MyMessageSettingsText Then
Dim t As MyMessage(Of MyMessageSettingsText) = CType(msg, MyMessage(Of MyMessageSettingsText))
' do something with t
End If
End Sub
End Class
Public MustInherit Class MyMessageSettingsBase
End Class
Public Class MyMessageSettingsText
Inherits MyMessageSettingsBase
Public Property Text As String
End Class
Public Class MyMessageSettingsNumber
Inherits MyMessageSettingsBase
Public Property Number As Integer
End Class
Public Class MyMessage(Of T As {New})
Public Property Name As String
Public Property Settings As New T
End Class

SerialPort.DataReceived event not firing

I've defined a SerialPort object as the following:
Public WithEvents SerialComm As New System.IO.Ports.SerialPort
SerialComm is setup and opened in the object constructor and closed when the object is disposed. My handler signature is as follows:
Private Sub OnComm(sender as Object, e as SerialDataReceivedEventArgs) Handles SerialComm.DataReceived
I'm trying to get a DataReceived event to fire from HyperTerminal. After sending some data, I can set a breakpoint and check the value of SerialComm.BytesToRead and see that it has updated to the proper number of bytes.
I have confirmed that the SerialPort is open and is receiving data, but I can't get the event to fire.
I've also tried manually wiring up the event (after removing the WithEvents definition) using AddHandler, but I was still unable to get the event to trigger.
What am I missing?
Update:
This is the class that I'm having trouble with:
Imports System.IO.Ports
Public Class CopyCat
Implements IDisposable
Private RxString As String
Private LastReceiveTime As DateTime
Public WithEvents SerialComm As New SerialPort
Public Property Timeout As TimeSpan
Public Sub New(commPort As String, timeout As TimeSpan)
Me.Timeout = timeout
Enable(commPort)
End Sub
Public Sub New(commPort As String)
Me.New(commPort, TimeSpan.FromMilliseconds(1000))
End Sub
Public Sub Enable()
CommUtilities.SetupComm(SerialComm, commPort, 115200, 8, Parity.Odd, StopBits.One, Handshake.None, System.Text.Encoding.Default)
End Sub
Public Sub Disable()
SerialComm.Close()
End Sub
Private Sub OnComm(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialComm.DataReceived
If(DateTime.Now - LastReceivedTime > Timeout) Then RxString = ""
Do While(SerialComm.BytesToRead > 0)
Dim readChar As String
Dim termChar As Char = Chr(RxString.ToByteList().XorAll())
readChar = SerialComm.ReadChar
RxString &= readChar
if (readChar = termChar) Then
SerialComm.Write((From item In GetResponse(RxString).Build()
Select item.Data).ToRawString)
RxString = ""
End If
Loop
End Sub
Public Function GetResponse(commandString As String) As MessageResponse
Dim response As MessageResponse = MessageResponse.GetMessageResponseFromByteList(commandString.ToByteList())
if (response.GetType = GetType(GetStatusResponse)) Then
response.DataBytes(8).Data = Math.Floor(Rnd() * 255)
response.DataBytes(9).Data = Math.Floor(Rnd() * 255)
End If
Return response
End Function
Private disposedValue as Boolean
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
SerialComm.Dispose()
End If
End If
Me.disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
End Class

Use VB.NET to get a filtered list Wordpress posts?

This is the code I have so far, but I can not understand why I am getting this error (Error 400).
I think that the problem is in the formatting of the argument filter. Anyone have any suggestions?
Imports CookComputing.XmlRpc
Public Class Form2
<XmlRpcUrl("http://example.wordpress.org/xmlrpc.php")> _
Public Interface IWP
Inherits IXmlRpcProxy
<XmlRpcMethod("wp.getPosts")> _
Function getPosts(ByVal args() As String) As Post()
End Interface
Public Structure Post
Public post_id As String
Public post_title As String
Public post_type As String
'...
End Structure
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim proxy As IWP = XmlRpcProxyGen.Create(Of IWP)()
Dim args() As String = {"blog_id", "user", "password", "post_type='page'"}
Dim posts() As Post
Try
posts = proxy.getPosts(args)
For Each post In posts
ListBox1.Items.Add(post.post_title)
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class

Asynchronous socket library not updating form

I am attempted to write a small asynchronous socket library that I can use to create a client/server application. I can get all of the code to run fine if I leave it in the form, however if I try to move it out into its own class, I cannot figure out how to update the form with connection status, things like that. Below is code, shortened a bit just to make this easier to read and type.
Form Code:
Class Form1
Dim Network as NetworkModule
Public Sub Button1_Click(Sender, e) Handles Button1.Click
Network = New NetworkModule("127.0.0.1", 1234)
End Sub
End Class 'Form1
NetworkModule class:
Class NetworkModule
Private mSocket as Socket
Public Sub New(IP as string, Port as Integer)
Dim remoteEP as New IPEndpoint(IP.Parse(IP), Port)
mSocket = New Socket(internetwork, stream, tcp)
mSocket.BeginConnect(remoteEP, New AsyncCallback(AddressOf onConnect), mSocket)
Notify("Connection to " & remoteEP.ToString) 'This one works
End Sub 'New
Private Sub onConnect(ar as IAsyncResult)
mSocket = CType(ar.AsyncState, Socket)
mSocket.EndConnect(ar)
Notify("Connected") 'This one never shows
End Sub 'onConnect
Private Delegate Sub _Notify(Msg as String)
Private Sub Notify(Msg as String)
If Form1.txtLog.InvokeRequired Then
Form1.txtLog.Invoke(New _Notify(AddressOf Notify), Msg)
Exit Sub
End if
Form1.txtLog.Text &= Msg & vbcrlf
End Sub 'Notify
End Class 'NetworkModule
There is actually more to that class, but I never get anything after the first message goes out. I'm not sure where to go from here. I've tried lots of different methods that I've found on the google searches, some from here, some not. Anybody have any ideas?
Here's how I would rewrite it:
Class Form1
Private Network as NetworkModule
Public NotifyDelegate As NetworkModule.NotifyDelegate
Public Sub New()
NotifyDelegate = New NetworkModule.NotifyDelegate(AddressOf Notify)
End Sub
Public Sub Button1_Click(Sender, e) Handles Button1.Click
Network = New NetworkModule("127.0.0.1", 1234, Me)
End Sub
Public Sub Notify(Msg As String)
txtLog.Text &= Msg & vbCrLf
End Sub
End Class 'Form1
NetworkModule Class (partial):
Class NetworkModule
Public Delegate Sub NotifyDelegate(Msg as String)
Private Sub Notify(Msg as String)
If m_Form.InvokeRequired Then
m_Form.Invoke(Form1.NotifyDelegate, Msg)
Else
m_Form.Notify(Msg)
End If
End Sub 'Notify
Private mSocket as Socket
Private m_Form As Form1
Public Sub New(IP as string, Port as Integer, oForm As Form1)
m_Form = oForm
Dim remoteEP as New IPEndpoint(IP.Parse(IP), Port)
mSocket = New Socket(internetwork, stream, tcp)
mSocket.BeginConnect(remoteEP, New AsyncCallback(AddressOf onConnect), mSocket)
Notify("Connection to " & remoteEP.ToString) 'This one works
End Sub 'New
Update with Interface approach
A better mechanism than passing the form itself is to implement an interface. To do this, first create the interface definition (note that the delegate has moved to the Interface for convenience):
Public Interface INotify
Sub Notify(Msg As String)
Delegate Sub NotifyDelegate(Msg As String)
End Interface
Then Implement the interface in the Form. Note that the form now determines whether or not Invoke is required. This allows the INotify interface to be used in non-UI scenarios, such as logging to disk or the event log.
Public Class Form1
Implements INotify
Public Sub Notify(Msg As String)
txtLog.Text &= Msg & vbCrLf
End Sub
Private Sub INotify_Notify(Msg As String) Implements INotify.Notify
If Me.InvokeRequired Then
Me.Invoke(New INotify.NotifyDelegate(AddressOf Notify), Msg)
Else
Me.Notify(Msg)
End If
End Sub 'Notify
Private Network As NetworkModule
Public Sub Button1_Click(Sender, e) Handles Button1.Click
Network = New NetworkModule("127.0.0.1", 1234, Me)
End Sub
End Class 'Form1
Finally, store a reference to the INotify interface instead of the Form in NetworkModule (note the NetworkModule no longer needs to know or care that an Invoke may be required):
Public Class NetworkModule
Public Delegate Sub NotifyDelegate(Msg As String)
Private m_Notifier As INotify
Private Sub Notify(Msg As String)
m_Notifier.Notify(Msg)
End Sub 'Notify
Public Sub New(IP As String, Port As Integer, oNotifier As INotify)
m_Notifier = oNotifier
' The addition code here
End Sub 'New
End Class