I am doing a database validation on the TextBox validating event. I am also using the e.Cancel = True if the data is invalid. The problem is that the validating event is triggered twice ultimately causing the SQL also to run twice, and I don't want that to happen (coz sometime the query is resource intensive).
Steps:
Drag & drop a RadTextBox & a RadLabel to the Form.
For the RadTextBox validating event use the below code.
Run the application, focus the RadTextBox & then click on the label. Then if you check the output window of visual studio you will notice that the console has logged that the validating event was actually triggered twice. (The event runs twice only when I try to click a RadButton or a RadLabel)
I noticed this bug when I was checking my queries in SQL Server Profiler & the query gets executed twice, which is unnecessary. I also checked with actual wincontrols & this issue doesn't exist in them.
How do I fix this issue ?
Here a sample code to replicate the behavior
Private Sub RadTextBox1_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles RadTextBox1.Validating
Console.WriteLine("VALIDATING EVENT TRIGGERED")
e.Cancel = True
End Sub
It seems as a known issue with RadTextBox: issue link
Perhaps you can try RadTextBoxControl for your needs?
Related
ok so ive got an updating program via clickonce, I want it to notify the user there is an update but don't actually update the program until an admin logs on and requests the update to go ahead.
I'm checking for updates like this via code
If My.Application.IsNetworkDeployed() Then
If My.Application.Deployment.CheckForUpdate() Then
MsgBox("Updates are available", vbInformation, "Updates available")
Note I haven't called the
My.Application.Deployment.Update()
to actually update.
When my application checks for updates it displays ok, but when no one does anything else when it is shut down again and then started up - it seems to revert back to automatically downloading the update on program startup. I have update automatically turned off in the project properties
I tried not checking for updates and the program starts and doesn't update so I'm thinking that just the act of checking and finding an update automatically sets the program to download it next time its started. which id rather it didn't
has anyone come across this issue before?
thanks
Modify this code. It is with an "updating" action but you'll be able to change this
Imports System.Deployment.Application
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
Dim updateCheck = ApplicationDeployment.CurrentDeployment
Dim info = updateCheck.CheckForDetailedUpdate()
If (info.UpdateAvailable) Then
MsgBox("Update wird geladen.")
updateCheck.Update()
MessageBox.Show("The application has been upgraded, and will now restart.")
Application.Restart()
End If
Catch : End Try
Form1.Show()
Me.Close()
End Sub
Do you by any chance have these options selected??
If you're handling the updates programmatically, you need to untick the "The application should check for updates" box.
Doing this will grey-out the "After" and "Before" radio buttons below it.
I am trying to read/use the output from a python program in my vb.net project so far I'm not getting any results. What I'd like to see is the python program run (just by itself first) and all of the output get redirected into a textbox.
I've looked at some other posts about this, but I'm either missing something or not understanding something, as all I'm getting is blank output.
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim PythonPath = "C:\Python27\"
Dim strPath As String = Application.StartupPath
MessageBox.Show(PythonPath & "python.exe """ & strPath & "\Resources\import_logs.py"" ")
Dim start_info As New ProcessStartInfo(TextBox1.Text)
' Make the process and set its start information.
Dim process As New Process()
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
process.StartInfo.FileName = PythonPath & "\python.exe"
process.StartInfo.Arguments = """" & strPath & "\resources\import_logs.py"""""
process.StartInfo.UseShellExecute = False
process.StartInfo.CreateNoWindow = True
process.StartInfo.RedirectStandardOutput = True
'process.StartInfo.RedirectStandardError = True
AddHandler process.OutputDataReceived, AddressOf proccess_OutputDataReceived
process.Start()
process.BeginOutputReadLine()
End Sub
Public Sub proccess_OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
On Error Resume Next
' output will be in string e.Data
' modify TextBox.Text here
'Server_Logs.Text = e.Data ` Does not display anything in textbox
MsgBox(e.Data) 'It works but I want output in text box field
End Sub
End Class
Eventually I'm going to pass arguments to the python script and I'd like to get feedback that I can then use (insert error into a database, email when it's done, etc), so I'd like it to capture the process while running and not just a data dump at the end.
Any help would be much appreciated.
First things first—it's no wonder you aren't sure what's wrong with your code, you're silencing all errors that could possibly help you to diagnose it. That's the only purpose of On Error Resume Next in VB.NET. That unstructured error handling was included only for backwards compatibility with the pre-.NET versions of VB and it's time to forget that it ever existed. You certainly don't want to use it in code. (I would say "in code that you're debugging", but all code is a potential candidate for debugging and ignoring errors is just dumb.)
Anyway, on to the specific problem. We know that the call to MsgBox works, but it doesn't work right when you start interacting with controls on your form. So something is falling apart there.
It turns out that the OutputDataReceived event is raised on an entirely different thread, a different one than was used to create the process and a different one than is running your application's UI. It actually just retrieves a thread from the system thread pool.
And that's where the problem lies: you cannot manipulate UI objects on a thread other than the one that created those objects (at least not without jumping through some hoops), which is precisely what your code tries to do here. In fact, you're probably swallowing an exception that would have rather obtusely informed you of this situation.
The simple fix is to set the SynchronizingObject property of the Process class to one of your UI components (like the form, or the specific control you want to output to). This forces all event handlers to execute on the same thread that created that component. At that point, your code should work fine, because you're not trying to do any cross-thread UI access. (Message boxes are not vulnerable to this because any thread can display a message box. You're not trying to access an existing UI object that is bound to another thread.)
Alternatively, you could handle the marshalling yourself in the event handler method through the use of delegates and the BeginInvoke method, but this seems like unnecessary work to me.
Team,
I have build a VB.Net windows application which does uploads data into database and basically updates two controls:
1. A textbox which is constantly updated with one line per database record upload.
2. A label which keeps track of the count of database record uploaded.
I have used BackgroundWorker thread concept, where the thread's bgwWorker_DoWork() method contains the business logic for upload and bgwWorker_ProgressChanged() updates the 2 UI controls based on uploads.
But the issue I am facing is that I do not get complete updates on both the UI controls. Sometimes the thread bypasses update of textbox and sometimes of label. I could resolve this issue by adding System.Threading.Thread.Sleep(25) before each UI control update code. Is this correct way of solving the issue? OR is there something I am missing?
Kindly suggest.
Below is the code in both these methods:
Private Sub bgwWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwWorker.DoWork
.................
.................
'Updates database record related update in textbox
System.Threading.Thread.Sleep(25)
updater.eventName = "UpdateStatusBox"
updater.errorMessageToLog = String.Empty
updater.errorMessageToLog += GetErrorMessage(dataTable(rowNumber)("Name").ToString(), ExceptionData)
bgwWorker.ReportProgress(1, updater)
.................
.................
'Updates Status Count in LABEL
System.Threading.Thread.Sleep(25)
updater.eventName = "UpdateStatusBar"
updater.successCount = successCount.ToString()
updater.failureCount = failureCount.ToString()
bgwWorker.ReportProgress(2, updater)
End Sub
Private Sub bgwWorker_ProgressChanged(ByVal sender As System.Object, ByVal e As ProgressChangedEventArgs) Handles bgwWorker.ProgressChanged
Dim updater As UIUpdater = TryCast(e.UserState, UIUpdater)
..........................................
If updater.eventName = "UpdateStatusBar" Then
UpdateStatusBar(updater.successCount, updater.failureCount)
ElseIf updater.eventName = "UpdateStatusBox" Then
txtUpdates.Text = txtUpdates.Text & updater.errorMessageToLog
End If
.....................................
End Sub
I'm almost positive that your problem is your instance of the UIUpdater object called updater. This object appears to be declared globally and is thus shared between calls.
Omitting a little bit of code this is what you have:
updater.eventName = "UpdateStatusBox"
bgwWorker.ReportProgress(1, updater)
updater.eventName = "UpdateStatusBar"
bgwWorker.ReportProgress(2, updater)
Although you call ReportProgress() linearly, it doesn't fire your ProgressChanged event immediately nor does it block until that method completed. To do so would defeat the purpose of threading if you think about it.
To put it another way, you have a global object that you are setting a property on. You then say "when someone gets a chance, do something with this". You then change a property on that global object and sometimes this happens before "someone has done something" happens.
The solution is either to create two global variables, one for each possible event or to just create an instance variable when needed. I'm not sure that its thread safe to use a global variable the way you are so I would recommend just creating an instance variable. In fact, the state object you pass to ReportProgress could just be a string.
I would NOT use a sleep in your DoWork event.
Have you tried refreshing the control after you update it? Each control has a Refresh method which forces a redraw. This may result in flickering though.
Another option is to include the information needed for both controls (textbox and label) in a single call to ReportProgress rather than trying to make two calls.
I use the LostFocus Event in vb.net to check the validity of a field for the name.
After this field a have another one which is the for the password validity, and i'm handilg the same event in order to check the password.
My problem comes when i run the (name) lost focus, runs the code inside the sub and after that automatically goes to the password_lostfocus which brings me alot of troubles.
That happens even i use the error provider which works fine and bring to me the error with the red flashing.After that i put the command (name_textbox.focus), which logically has to bring the control in the name_textbox.. But NO.. the control goes to the Password_textbox sub automatically.
Please see my sub
Private Sub UsernameTextBox_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles UsernameTextBox.LostFocus
Select Case DB_Access.IfExistUser(UsernameTextBox.Text, sender, e)
Case True
PasswordTextBox.Focus()
Case False
ErrorProvider1.SetError(UsernameTextBox, "Ο χρήστης ΔΕΝ υπάρχει παρακαλώ καλέστε τον Administrator")
Beep()
UsernameTextBox.Text = ""
UsernameTextBox.Focus()
End Select
End Sub
Please if anyone have seen this issue and face it, assist me.
Excuse me for some Greek characters they are meaningless, they are comments
Well finally i found that.
In order to handle the Login Form as it give it from visual studio 2010 you need to do it in only one sub (Lost Focus) and that is only the password_LostFocus.
I believe the particular form is meant to be like that.
Any way i solve the issue and if anybody needs assistance on that just "asc a question"
I am trying to validate textbox values during runtime in vb.net I have following code which is validating txtno from database table tblmachines. But i have problem with chartype and stringtype. Is there any other solution to fix that problem?
Private Sub txtno_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtno.KeyPress
If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then
e.Handled = True
If (Me.txtno.Text = "") Then
Interaction.MsgBox("!!!!!!!!Machine number can not be empty. Please Correct.!!!!!!!!", &H40, "Check Machine Number")
Me.txtno.Focus()
ElseIf (Me.txtno.Text = "0") Then
Me.txtturnover.Focus()
Else
Dim table As DataTable = Me.DataSet1.Tables.Item("tblmachines")
Dim defaultView As DataView = table.DefaultView
defaultView.RowFilter = ("local_no='" & Me.txtno.Text & "'")
If ((Char.IsLetter(CharType.FromString(Me.txtno.Text)) Or (defaultView.Count = 0)) Or (StringType.StrCmp(Me.txtno.Text, "", False) = 0)) Then
Interaction.MsgBox("This machine is not on database. Please correct machine number.", &H40, "Check Machine Number")
Me.txtno.Focus()
Else
Me.txtturnover.Focus()
End If
End If
End If
I think you'd be better off using validation from the Winforms library than in the KeyPress event. KeyPress is going to cause a lot of validation scripts to be run and will bog down your app.
I think you should do the validation in the following steps
Check to ensure that there is data in the texbox
Validate that the data entered in the textbox is in the proper format. You can use regular code, or possibly a RegEx for that.
Validate that the number entered is a part of the database. I made it a habit reset the filters to a blank string before applying any new filters to the table.
The good part about using inbuilt validation is that you do not have to worry about moving focus around.
The control has a property called CausesValidation - if you set it to true (which it already is) then this control will run the validation code. If you do not want the control to run validation code, you can turn the property to False.
The validation happens as Focus shifts - so when you focus off a control, it's validation events are fired.
The events Validating and Validated are commonly used for this purpose. You can put your code validation in there instead of putting it on the KeyPress.
This is not the proper way to let the user input this specific data. You've got a list of valid entries available from your database. Put them in a ComboBox so the user doesn't have to guess and can't get it wrong.