I'm having some issues with WinForms ComboBox class. What I am trying to achieve is programmatically setting SelectedValue from the ComboBox.TextChanged handler once a match is found. This works fine on Windows 7, but in Windows XP SelectedValue will get set and SelectedValueChanged will be raised, but then once it reaches Validating SelectedValue returns Nothing. It seems the only way to change SelectedValue in XP is via selecting something from the dropdown.
Here's a toy Form with just a ComboBox and a multi-line TextBox.
XP: Typed into the ComboBox is 1Y, then tab is pressed. Output:
SelectedValueChanged: SelectedValue: 1X
Validating: SelectedValue: Nothing
Value is:
Validated: SelectedValue: Nothing
Win7: Typed into the ComboBox is 1Y, then tab is pressed. Output:
SelectedValueChanged: SelectedValue: 1X
Validating: SelectedValue: 1X
Value is: 1X
Validated: SelectedValue: 1X
Code:
Public Class ComboBoxXPForm
Private WithEvents mData As New DataHolder
Private mBindingSrc As BindingSource
Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
mBindingSrc = New BindingSource() With {.DataSource = mData}
Dim dt As New DataTable()
dt.Columns.Add("value", GetType(String))
dt.Columns.Add("displayValue", GetType(String))
dt.Rows.Add("", "")
For i = 1 To 10
dt.Rows.Add(i & "X", i & "Y")
Next
cboBox.DataSource = dt
cboBox.ValueMember = "value"
cboBox.DisplayMember = "displayValue"
cboBox.DataBindings.Add("SelectedValue", mBindingSrc, "StrVal", True)
End Sub
Private Sub cboBox_SelectedValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboBox.SelectedValueChanged
txtDebug.Text &= vbNewLine & "SelectedValueChanged: SelectedValue: " & _
If(cboBox.SelectedValue Is Nothing, _
"Nothing", cboBox.SelectedValue.ToString())
End Sub
Private Sub DataHolder_DebugInfo(ByVal sender As Object, ByVal e As DebugEventArgs) Handles mData.DebugInfo
txtDebug.Text &= vbNewLine & e.DebugInfo
End Sub
Private Sub cboBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboBox.TextChanged
'For Each row In cboBox.Items
' If cboBox.Text = row("displayValue") AndAlso row("value") <> cboBox.SelectedValue Then
' 'cboBox.SelectedValue = row("value")
' cboBox.SelectedItem = row
' End If
'Next
For i = 0 To cboBox.Items.Count - 1
Dim item = cboBox.Items(i)
If cboBox.Text = item("displayValue") Then
cboBox.SelectedIndex = i
End If
Next
End Sub
Private Sub cboBox_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboBox.Validated
txtDebug.Text &= vbNewLine & "Validated: SelectedValue: " & _
If(cboBox.SelectedValue Is Nothing, _
"Nothing", cboBox.SelectedValue.ToString())
End Sub
Private Sub cboBox_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles cboBox.Validating
txtDebug.Text &= vbNewLine & "Validating: SelectedValue: " & _
If(cboBox.SelectedValue Is Nothing, _
"Nothing", cboBox.SelectedValue.ToString())
End Sub
End Class
Public Class DebugEventArgs
Inherits EventArgs
Private mDebugInfo As String
Public Sub New(ByVal DebugString As String)
MyBase.New()
DebugInfo = DebugString
End Sub
Public Property DebugInfo() As String
Get
Return mDebugInfo
End Get
Set(ByVal value As String)
mDebugInfo = value
End Set
End Property
End Class
Public Class DataHolder
Public Event DebugInfo(ByVal sender As Object, ByVal e As DebugEventArgs)
Private mStrVal As String
Public Property StrVal() As String
Get
Return mStrVal
End Get
Set(ByVal value As String)
mStrVal = value
RaiseEvent DebugInfo(Me, New DebugEventArgs("Value is: " & value))
End Set
End Property
End Class
Try turning AutoCompleteMode to become SuggestAppend, and AutoCompleteSource to become ListItems. Then you can remove the entire TextChanged code block and it should also work properly on XP.
Related
I have a sub that brings a second form with a treeview on it that is populated from an array. I want to click on an item on the array and pass the key and text back to the sub and close the second form.
I feel like this should be easy but I cannot figure this out. The array is passed to the treeview as follows.
For j = 0 To NoFlowsheets - 1
Form2.TreeView1.Nodes.Add("Flowsheet" & CStr(j), ColumnNames(j, 0))
For k = 0 To j_max - 1
If ColumnNames(j, k) <> "NAME_EMPTY DO_NOT_USE_THIS_NAME" Then
Form2.TreeView1.Nodes(j).Nodes.Add("Flowsheet" & CStr(j), ColumnNames(j, k))
End If
Next k
Next j
Form2.ShowDialog()
after this a form pops up with the treeview. I want the user to click on one of the items in the tree view and pass it back to the sub
This is a very basic example, but it shows how you can pass something into a form, and how to get back what the user selected/entered. You can easily modify this to pass in your array, and pass back the selected value(s).
On the first form (where you open the child form), you add code like this:
Public Class frmStart
Private Sub btnAskUser_Click(sender As Object, e As EventArgs) Handles btnAskUser.Click
Dim frmAskUserAboutThemselves As New frmQuestion(19, "John Doe")
frmAskUserAboutThemselves.ShowDialog(Me)
If frmAskUserAboutThemselves.WasRecordSaved = True Then
lblStatus.Text = "Name: " & frmAskUserAboutThemselves.ValueThatUserSelectedOnTheFormName & vbCrLf & "Age: " & frmAskUserAboutThemselves.ValueThatUserSelectedOnTheFormAge
Else
lblStatus.Text = "The user did not enter/select any values."
End If
frmAskUserAboutThemselves.Dispose()
Beep()
End Sub
End Class
On the child form (where you ask the user to select something), you add code like this:
Public Class frmQuestion
#Region " Override Windows Form Designer Generated Code "
Public Sub New(Optional ByVal iAge As Integer = 0, Optional ByVal sName As String = "")
MyBase.New()
m_iPassedInPersonAge = iAge
m_sPassedInPersonName = sName
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
#End Region
#Region " Form Level Variables "
Private m_iPassedInPersonAge As Integer = 0
Private m_sPassedInPersonName As String = ""
Private m_bWasRecordSaved As Boolean = False
#End Region
#Region " Form Level Functions "
Public ReadOnly Property WasRecordSaved() As Boolean
Get
Return m_bWasRecordSaved
End Get
End Property
Public ReadOnly Property ValueThatUserSelectedOnTheFormName() As String
Get
Return m_sPassedInPersonName
End Get
End Property
Public ReadOnly Property ValueThatUserSelectedOnTheFormAge() As Integer
Get
Return m_iPassedInPersonAge
End Get
End Property
#End Region
#Region " Normal Page Code "
Private Sub frmQuestion_Load(sender As Object, e As EventArgs) Handles MyBase.Load
txtName.Text = m_sPassedInPersonName
NumericUpDownAge.Value = m_iPassedInPersonAge
End Sub
Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click
m_bWasRecordSaved = False
Me.Close()
End Sub
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
m_iPassedInPersonAge = NumericUpDownAge.Value
m_sPassedInPersonName = txtName.Text.Trim
m_bWasRecordSaved = True
Me.Close()
End Sub
#End Region
End Class
If you are unsure what controls i placed on each form, just ask, but it should be pretty easy to figure that out.
I am new to visual basic so hopefully this is a simple question. I have a menu with buttons to call different forms. The forms are designed and have labels and text fields and buttons and so on. From the main menu I have tried calling the forms two different ways. One way the forms open and look correct and function. The other way the form opens as a small blank square with no fields. Ultimately I want to create a set of List objects when the main menu opens and pass them back and forth to the other forms for input and processing. I'm using parallel Lists as a temporary database for a simple school lab. I just don't see what is wrong with the way I am calling the form. I haven't even bothered worrying about passing the List objects properly yet.
Public Class frmMain
Dim arrGames As New List(Of String)
Dim arrDates As New List(Of String)
Dim arrPrices As New List(Of Decimal)
Dim arrSeats As New List(Of Integer)
Private Sub btnEnterGames_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEnterGames.Click
'NewEnter.Visible = True
Dim frmEnter As New NewEnter(arrGames, arrDates, arrPrices, arrSeats)
frmEnter.ShowDialog()
End Sub
Private Sub btnReports_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReports.Click
'Reports.Visible = True
Dim frmReports As New Reports(arrGames, arrDates, arrPrices, arrSeats)
frmReports.Visible = True
End Sub
Private Sub btnSellTickets_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSellTickets.Click
'SellTickets.Visible = True
Dim frmSell As New SellTickets(arrGames, arrDates, arrPrices, arrSeats)
frmSell.Visible = True
End Sub
Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click
Close()
End Sub
End Class
This is the code for the form NewEnter. I have the New routine which accepts the 4 Lists and basically does nothing else. Doing the "'NewEnter.Visible = True" in the main menu will load the form correctly but I have to comment out the New sub routine in the forms or there is an error.
Public Class NewEnter
Private _arrGames As List(Of String)
Private _arrDates As List(Of String)
Private _arrPrices As List(Of Decimal)
Private _arrSeats As List(Of Integer)
Sub New(ByVal arrGames As List(Of String), ByVal arrDates As List(Of String), ByVal arrPrices As List(Of Decimal), ByVal arrSeats As List(Of Integer))
' TODO: Complete member initialization
' _arrGames = arrGames
' _arrDates = arrDates
' _arrPrices = arrPrices
' _arrSeats = arrSeats
End Sub
Private Sub btnSaveGame_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSaveGame.Click
Dim arrGames As New List(Of String)
Dim arrDates As New List(Of String)
Dim arrPrices As New List(Of Decimal)
Dim arrSeats As New List(Of Integer)
Dim strGame As String
Dim strPrice As String
Dim strSeats As String
Dim intSeats As Integer
Dim decPrice As Decimal
Dim bolGameErr As Boolean
Dim bolDateErr As Boolean
Dim bolPriceErr As Boolean
Dim bolSeatErr As Boolean
strGame = txtGame.Text
strPrice = txtPrice.Text
strSeats = txtSeats.Text
'~~~~~~~~~~~~verify a game is entered
If String.IsNullOrEmpty(strGame) Or String.IsNullOrWhiteSpace(strGame) Then
bolGameErr = True
Else
'~~~~~~~~~~~~verify price is numeric
If IsNumeric(strPrice) Then
decPrice = strPrice
'~~~~~~~~~~~~~~~verify seats are numeric
If IsNumeric(strSeats) Then
intSeats = Convert.ToInt32(strSeats)
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ add elements to array lists
arrGames.Add(New String(strGame))
arrDates.Add(dtpDate.Text)
arrPrices.Add(New Decimal(decPrice))
arrSeats.Add(intSeats)
lblSaveSuccessful.Visible = True
ClearInput()
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ add elements to array lists
Else
bolSeatErr = True
End If
Else
bolPriceErr = True
End If
End If
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Check flags for input errors
If bolDateErr = True Then
lblErr.Text = "Invalid date"
lblErr.Visible = True
End If
If bolGameErr = True Then
lblErr.Text = "Must enter a game name"
lblErr.Visible = True
txtGame.Focus()
End If
If bolDateErr = True And bolGameErr = True Then
lblErr.Text = "Must enter a game name and valid date"
lblErr.Visible = True
txtGame.Focus()
End If
If bolPriceErr = True Then
lblPriceErr.Visible = True
txtPrice.Text = ""
txtPrice.Focus()
End If
If bolSeatErr = True Then
lblSeatErr.Visible = True
txtSeats.Text = ""
txtSeats.Focus()
End If
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Check flags for input error
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Display output
Dim i As Integer
i = 0
lblData.Text = arrGames.Count.ToString
Do While i < arrGames.Count
lblData.Text = Convert.ToString(arrGames(i)) & " on " & Convert.ToString(arrDates(i)) & " Price: " & _
Convert.ToString(arrPrices(i)) & " Available Seats: " & Convert.ToString(arrSeats(i))
i += 1
Loop
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Display output
lblData.Visible = True
End Sub
Private Sub ClearInput()
'lblErr.Visible = False
'lblPriceErr.Visible = False
'lblSeatErr.Visible = False
txtGame.Text = ""
txtPrice.Text = ""
txtSeats.Text = ""
txtGame.Focus()
End Sub
Public Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Me.Visible = True
'Me.BackColor = Color.BurlyWood
'Me.ResumeLayout()
'Me.Activate()
'Me.Focus()
'Me.Show()
'Me.lblGameHdr.Visible = True
End Sub
Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click
Close()
End Sub
End Class
Add InitializeComponent() to your constructor class.
This is added by default to the New (constructor) function of all Visual Basic forms. It requires it to set-up the UI components on the form.
I run the site following errors occured:
System.InvalidCastException was unhandled by user code
Message="Conversion from string "kumar" to type 'Short' is not valid."
Imports System.Data.OleDb
Namespace wbdsproject
Partial Class frmprofile
Inherits System.Web.UI.Page
Dim proCon As OleDbConnection
Dim proCmd As OleDbCommand
Dim prodr As OleDbDataReader
Dim username As String
Dim userid As Int16
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load, Me.Load
'Put user code to initialize the page here
' maillink.NavigateUrl = "mailto:saranya#gmail.com"
Dim proselqry As String
username = Session("loginuser")
lblusername.Text = username
userid = Request.QueryString("userid")
'Response.Write(userid)
proCon = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\Discussion Forum\database-WBDS\SampleForum.mdb")
proCon.Open()
If Session("loginuser") = "" Then
Response.Redirect("frmlogin.aspx")
End If
proselqry = "select * from tblprofile where uid='" & userid & "'"
proCmd = New OleDbCommand(proselqry, proCon)
proCmd.ExecuteNonQuery()
prodr = proCmd.ExecuteReader
If prodr.Read Then
lbldob.Text = prodr("dob")
lblquali.Text = prodr("quali")
lblinterest.Text = prodr("interest")
lbladdress.Text = prodr("address")
maillink.Text = prodr("emailid")
maillink.NavigateUrl = "mailto:" & prodr("emailid")
lblzip.Text = prodr("zip")
lblphno.Text = prodr("phno")
End If
End Sub
Private Sub btnmodify_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnmodify.Click
Response.Redirect("frmregmodify.aspx?user=" & username & "&userid=" & userid & "&page=frmprofile")
End Sub
Private Sub LinkButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
End Sub
End Class
End Namespace
at Microsoft.VisualBasic.CompilerServices.Conversions.ToShort(String Value)
You're trying to cast a String returning function into a Int16 in this line
userid = Request.QueryString("userid")
Apparently, your return is not numeric. You can either change that from the source if you have control over it or change change the userid type to string.
I would suggest using a user defined function to test if the requesting querty string is numeric before casting to an Int16 datatype.
I was wondering if you could help me? My question is that, is there a way of changing the value in my.Settings in a form if you enter a number/decimal in a textbox and click a button and then update in the settings to be then changed in another from which is linked to my.Settings in a variable?!
Form 1:
Public Class frmConverter
Dim input As String
Dim result As Decimal
Dim EUR_Rate As Decimal = My.Settings.EUR_Rates
Dim USD_Rate As Decimal = 1.6
Dim JYP_Rate As Decimal = 179.65
Private Sub btnCalc_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalc.Click
input = txtInput.Text
Try
If ComboBox1.Text = "£" Then
Pounds()
ElseIf ComboBox1.Text = "€" Then
Euros()
ElseIf ComboBox1.Text = "$" Then
Dollars()
ElseIf ComboBox1.Text = "¥" Then
Yen()
End If
Catch es As Exception
MsgBox("Error!")
End Try
End Sub
Private Sub btnSettings_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSettings.Click
Me.Hide()
frmExchange.Show()
End Sub
Private Sub btnReset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReset.Click
txtInput.Text = ""
lblResult.Text = ""
End Sub
Function Pounds()
If ComboBox1.Text = "£" And ComboBox2.Text = "€" Then
result = (input * EUR_Rate)
lblResult.Text = FormatNumber(result, 2) & " " & ComboBox2.Text
ElseIf ComboBox1.Text = "£" And ComboBox2.Text = "$" Then
result = (input * USD_Rate)
lblResult.Text = FormatNumber(result, 2) & " " & ComboBox2.Text
ElseIf ComboBox1.Text = "£" And ComboBox2.Text = "¥" Then
result = (input * JYP_Rate)
lblResult.Text = FormatNumber(result, 2) & " " & ComboBox2.Text
End If
Return 0
End Function
Form 2:
Public Class frmExchange
Private Sub frmExchange_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
My.Settings.EUR_Rates = (txtinput.Text)
My.Settings.Save()
My.Settings.Reload()
End Sub
Public Sub SetNewRate(ByVal rate As Decimal)
txtinput.Text = rate.ToString
End Sub
Private Sub btnchange_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnchange.Click
If ComboBox1.Text = "€" Then
My.Settings.USD_Rates = (txtinput.Text)
frmConverter.SetNewRate(txtinput.Text)
End If
End Sub
End class
It sounds like you are trying to use My.Settings as some sort of set of global reference variables. Thats not what they are for, not how they work and not what they are.
First, turn on Option Strict as it looks like it may be Off. This will store the decimal value of a textbox to a Settings variable which is defined as a Decimal:
My.Settings.USD_Rates = CDec(SomeTextBox.Text)
Thats all it will do. It wont save the value and it wont pass it around or share it with other forms and variables.
My.Settings.Save 'saves current settings to disk for next time
My.Settings.Reload 'Load settings from last time
This is all covered on MSDN. There is no linkage anywhere. If you have code in another form like this:
txtRate.Text = My.Settings.USD_Rates.ToString
txtRate will not automatically update when you post a new value to Settings. There are just values not Objects (see Value Types and Reference Types). To pass the new value to another form:
' in other form:
Public Sub SetNewRate(rate As Decimal)
' use the new value:
soemTextBox.Text = rate.ToString
End Sub
in form which gets the change:
Private Sub btnchangeRate(....
' save to settings which has nothing to do with passing the data
My.Settings.USD_Rates = CDec(RateTextBox.Text)
otherForm.SetNewRate(CDec(RateTextBox.Text))
End Sub
You may run into problems if you are using the default form instance, but that is a different problem.
You botched the instructions. The 2 procedures are supposed to go in 2 different forms - one to SEND the new value, one to RECEIVE the new value. With the edit and more complete picture, there is an easier way.
Private Sub btnSettings_Click(...) Handles btnSettings.Click
' rather than EMULATE a dialog, lets DO a dialog:
'Me.Hide()
'frmExchange.Show()
Using frm As New frmExchange ' the proper way to use a form
frm.ShowDialog
' Im guessing 'result' is the xchg rate var
result = CDec(frm.txtInput.Text)
End Using ' dispose of form, release resources
End Sub
In the other form
Private Sub btnchange_Click(....)
' do the normal stuff with Settings, if needed then:
Me.Hide
End Sub
In Form1 I have a Textbox1, in this textbox I have the location of a file "C:\folder\file.iso"
In the Form2 I want to get the file size of the file in Textbox1 so I tried this
Dim fileDetail As IO.FileInfo
fileDetail = My.Computer.FileSystem.GetFileInfo(Form1.Textbox1.Text)
Label1.Text = Size: fileDetail.Length
End Sub
I dont get an error, but the size of the file isn't showed in the label.
Edit: This doesn't seem to work
Private Sub Unscramble_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If System.IO.File.Exists(Form1.TextBox2.Text) Then
Dim fi As New System.IO.FileInfo(Form1.TextBox2.Text)
Label3.Text = "Size: " & fi.Length.ToString()
End If
End Sub
It still doesn't give me the size of the file nor it gives the "Size:"
Dim fileDetail = My.Computer.FileSystem.GetFileInfo(form1.Textbox1.Text)
Label1.Text = "Size : " & fileDetail.Length
' this is the first(main) form'
Public Class Form1
Private Sub Button1_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
' create the form2 by PASSING it the file path in constructor'
Dim f2 As New Form2(TextBox1.Text)
f2.ShowDialog()
End Sub
End Class
' this is the second form'
Public Class Form2
Inherits Form
Private _filePath As String
Private Label1 As Label
Public Sub New(ByVal filePath As String)
_filePath = filePath
End Sub
' this is the _Load method of the second form'
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
MyBase.OnLoad(e)
If IO.File.Exists(_filePath) Then
Dim fi As New IO.FileInfo(_filePath)
Label1.Text = "Size :" & fi.Length.ToString()
End If
End Sub
End Class
Code works perfect but something in my project is blocking it.
Created a new project and it worked perfect.
'label3.Text is my all string with file size.
Label3.Text = "Size : " & My.Computer.FileSystem.GetFileInfo("C:\Download\my song.mp3").Length & " Bytes"
'Output: Size: 2344 Bytes
Label3.Text = "Size : " & System.Math.Round(My.Computer.FileSystem.GetFileInfo("C:\Download\my song.mp3").Length / 1024) & " KB"
'Output: Size: 2 KB
There is two choice, Which you want