Difficulty retrieving text in TextBox upon selecting an ID in ComboBox - sql-server

Upon selecting a Question ID in the combo box the relating question should then appear in the text box. I am unsure how to get this to work though. I receive an error "Value of type......cannot be converted to string" on retrieveQuestion(). Any help is appreciated, thankyou.
Private Sub cmbQuestion_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbQuestion.SelectedIndexChanged
txtExistingQuestion.Text = retrieveQuestion() 'Add question, relevant to Question ID, to text box, DO I NEED .ToString?????????????????
loaded = True
End Sub
Public Function retrieveQuestion() As List(Of Question) 'Retrieves selected question into text box
Dim typeList As New List(Of Question)
Dim Str As String = "SELECT Question_ID, Question_Text FROM Question WHERE Question_ID =" & cmbQuestion.SelectedValue
Try
Using conn As New SqlClient.SqlConnection(DBConnection)
conn.Open()
Using cmdQuery As New SqlClient.SqlCommand(Str, conn)
Using drResult As SqlClient.SqlDataReader = cmdQuery.ExecuteReader()
While drResult.Read
typeList.Add(New Question(drResult("Question_ID"), drResult("Question_Text")))
End While
End Using 'Automatically closes connection
End Using
End Using
Catch ex As Exception
MsgBox("Question List Exception: " & ex.Message & vbNewLine & Str)
End Try
Return typeList
End Function
Public Class Question 'defining one club within class
Public Sub New(ByVal questionID As Integer, ByVal questionText As String)
mQuestionID = questionID 'm is for member of the class
mQuestionText = questionText
End Sub
Private mQuestionID As String = ""
Private mQuestionText As String = ""
Public Property QuestionID() As String
Get
Return mQuestionID
End Get
Set(ByVal value As String)
mQuestionID = value
End Set
End Property
Public Property QuestionText() As String
Get
Return mQuestionText
End Get
Set(ByVal value As String)
mQuestionText = value
End Set
End Property
End Class

Your issue is this line:
mQuestionID = questionID
In your class you have defined this:
Private mQuestionID As String = ""
But in your constructor, you are saying that questionID should be an Integer, like this:
Public Sub New(ByVal questionID As Integer, ByVal questionText As String)
You need to change your backing variable in your class (mQuestionID) to be an Integer, like this:
Private mQuestionID As Integer
This will also necessitate a change to the property syntax for QuestionID, like this:
Public Property QuestionID() As Integer
Get
Return mQuestionID
End Get
Set(ByVal value As Integer)
mQuestionID = value
End Set
End Property

Your error is originated by the return value of retrieveQuestion declared as a List(Of Question) but then you try to set the text property of a TextBox (and there is no way to convert automatically a List(Of Question) to a string)
So you could write something like this to extract the text of the first question in the list
Dim qList = retrieveQuestion()
if qList.Count > 0 then
txtExistingQuestion.Text = qList(0).QuestionText
loaded = True
End If
Of course, if your query returns zero or just one question, then there is no need to return a List(Of Question) and you can change the retrieveQuestion method to return just a Question or Nothing
Public Function retrieveQuestion() As Question
Dim questionResult As Question = Nothing
......
Using drResult As SqlClient.SqlDataReader = cmdQuery.ExecuteReader()
if drResult.Read() then
questionResult = New Question(drResult("Question_ID"), _
drResult("Question_Text")))
End if
End Using
....
return questionResult
End Function
Dim question = retrieveQuestion()
if question IsNot Nothing then
txtExistingQuestion.Text = question.QuestionText
loaded = True
End If
However, all the comments about string and integer conversion happening automatically on your code are really an alarm bell. You should strive to avoid this kind of conversion because they render your code weak and prone to misterious errors. Switch to Option Strinct On on your project properties and prepare yourself to a lot of conversion fixing.

Related

How to create a new instance of a class when converting to it as a type vb.net

I have a Serializable class called SettingsForProgram this class contains a list of string called ServerList
I am using this class to save settings for myprogram (username , password , colors , etc..) but when i try to save a list the same way then add -or get- items from it i get object reference not set to instance of object so how can i create a new instance of the class when converting it
To understand what i mean here are some codes :
The class :
<Serializable()>
Public Class SettingsForProgram
Private Namev As String = ""
Private pwv As String = ""
Public LocationsList As New List(Of String)
Private Savev As New Boolean()
Public Property LoginName As String
Get
Return Namev
End Get
Set(value As String)
Namev = value
End Set
End Property
Public Property LoginPassword As String
Get
Return pwv
End Get
Set(value As String)
pwv = value
End Set
End Property
Public Property SaveLogin As Boolean
Get
Return Savev
End Get
Set(value As Boolean)
Savev = value
End Set
End Property
Public Sub New()
LocationsList = New List(Of String)
End Sub
End Class
To load settings:(where i want to initialize the new instance of the class)
public MySettings as new SettingsForProgram
Public Sub LoadSettings()
Dim formatter As New BinaryFormatter()
Dim data As Byte() = File.ReadAllBytes(savepath)
Dim ms As New MemoryStream(data)
MySettings = CType(formatter.Deserialize(ms), SettingsForProgram)
End Sub
To save settings :
Public Sub SaveSettings()
Dim bf As New BinaryFormatter()
Dim ms As New MemoryStream()
If MySettings.LoginName = Nothing Then
MySettings.LoginName = "name"
ElseIf MySettings.LoginPassword = Nothing Then
MySettings.LoginPassword = "password"
End If
bf.Serialize(ms, MySettings)
Dim mySaveState As Byte() = ms.ToArray()
File.WriteAllBytes(savepath, mySaveState)
End Sub
I made a quick test like this
button 1 : save
MySettings.LocationsList.AddRange({"test1", "test2", "test3"}) <<<< where i get the error
SaveSettings()
button 2 : load
LoadSettings()
MsgBox(MySettings.LocationsList(1))
thanks to #Steve i now know the problem
, the solution is to do like i did with name and password saving ,
just added this to the save Settings
If MySettings.LocationsList Is Nothing Then
MySettings.LocationsList = New List(Of String)
MySettings.LocationsList.Add("Location 1")
End If
and every thing worked
final code
Public Sub SaveSettings()
Dim bf As New BinaryFormatter()
Dim ms As New MemoryStream()
If MySettings.LoginName = Nothing Then
MySettings.LoginName = "name"
ElseIf MySettings.LoginPassword = Nothing Then
MySettings.LoginPassword = "password"
End If
If MySettings.LocationsList Is Nothing Then
MySettings.LocationsList = New List(Of String)
MySettings.LocationsList.Add("Location 1")
End If
bf.Serialize(ms, MySettings)
Dim mySaveState As Byte() = ms.ToArray()
File.WriteAllBytes(savepath, mySaveState)
End Sub

Find value in the List(Of T)

I'm new to List(Of T). Please help me.
I load my List value when system running. How to search for data that have in the List?
1. My List class
Public Class Directory
Public strdirname As String
Public strdircategory As String
Public strdirlevel As String
Public Sub New(ByVal m_dirname As String, ByVal m_dirlevel As String, ByVal m_dircat As String)
Try
strdirname = m_dirname
strdirlevel = m_dirlevel
strdircategory = m_dircat
Catch ex As Exception
MessageBox.Show("Error new instance.Ex-" & ex.Message)
End Try
End Sub
Public Property ShopName() As String
Get
Return strdirname
End Get
Set(ByVal value As String)
strdirname = value
End Set
End Property
Public Property ShopLevel() As String
Get
Return strdirlevel
End Get
Set(ByVal value As String)
strdirlevel = value
End Set
End Property
Public Property ShopCategory() As String
Get
Return strdircategory
End Get
Set(ByVal value As String)
strdircategory = value
End Set
End Property
End Class
2. My new instance for List
MyDir = New List(Of Directory)
In my search page, I want to find lets say a category eg: food & beverages. How to find all the data from the list where the strdircategory = "Food & Beverages"? Some page need to get by Level, Name also.
If I wanna search from the list, should I new the List again? Please advise.
Edited:
Dim filterSpecific As List(Of Directory) = MyDir.FindAll(Function(p As Directory) p.strdircategory = txtkey.Text)
To find an element in your List(Of T), use the Find method (for a single element):
List(Of T).Find Method
Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire List.
or FindAll (for all elements):
List(Of T).FindAll Method
Retrieves all the elements that match the conditions defined by the specified predicate.
So, in your case, just use
Dim result = yourlist.FindAll(Function(d) d.strdircategory = "Food & Beverages")
You could also use the Where extension method (which returns a lazy query instead of a new List(Of T)).

How to retrieve column items from listview in code

I am new to wpf and am going for an MCTS exam. I have searched for 2 days now on how to retrieve row column items in code. I have been able to insert data into the listview by creating a structure and adding row items via code.
Public Structure SimpleData
Public Property Txt1 As String
Get
Return mTxt1
End Get
Set(value As String)
mTxt1 = value
End Set
End Property
Private mTxt1 As String
Public Property Txt2 As String
Get
Return mTxt2
End Get
Set(value As String)
mTxt2 = value
End Set
End Property
Private mTxt2 As String
Public Property Txt3 As String
Get
Return mTxt3
End Get
Set(value As String)
mTxt3 = value
End Set
End Property
Private mTxt3 As String
End Structure
Public Structure MyData
Public Property Desc() As String
Get
Return m_Desc
End Get
Set(value As String)
m_Desc = Value
End Set
End Property
Private m_Desc As String
Public Property Progress() As Integer
Get
Return m_Progress
End Get
Set(value As Integer)
m_Progress = Value
End Set
End Property
Private m_Progress As Integer
Public Property ProgressText() As String
Get
Return m_ProgressText
End Get
Set(value As String)
m_ProgressText = Value
End Set
End Property
Private m_ProgressText As String
Public Property Pic() As String
Get
Return m_Pic
End Get
Set(value As String)
m_Pic = Value
End Set
End Property
Private m_Pic As String
End Structure
Private Sub Button2_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button2.Click
Dim sd As New SimpleData
sd.Txt1 = "Today is"
sd.Txt2 = "a good day"
sd.Txt3 = "O YES!"
listView1.Items.Add(sd)
End Sub
I want to be able to retrieve row(0).Item(0).ToString, which is how to retrieve it in win forms. Expecting a response. Thanks in advance
Dim constr As String = "Put your connection string here"
Dim ds As New DataSet
Dim con As New SqlClient.SqlConnection(constr)
con.Open()
Dim sqladap As New SqlClient.SqlDataAdapter("select * from tbl_Employee", con)
sqladap.Fill(ds)
For i As Integer = 0 To ds.Tables(0).Columns.Count - 1
ListView1.Columns.Add(ds.Tables(0).Columns(i).ToString())
Next
For i As Integer = 0 To ds.Tables(0).Rows.Count - 1
Dim listRow As New ListViewItem
listRow.Text = ds.Tables(0).Rows(i)(0).ToString()
For j As Integer = 1 To ds.Tables(0).Columns.Count - 1
listRow.SubItems.Add(ds.Tables(0).Rows(i)(j).ToString())
Next
ListView1.Items.Add(listRow)
Next
Read data from Listview :
Dim name, room, subject, date, period As String
If listviewName.SelectedItems.Count > 0 then
For i As Integer = 0 To listviewName.SelectedItems.Count - 1
'*********** transfer selected data on declare String variable ************'
name= listviewName.SelectedItems(i).SubItems(0).Text
room = listviewName.SelectedItems(i).SubItems(1).Text
subject = listviewName.SelectedItems(i).SubItems(2).Text
date= listviewName.SelectedItems(i).SubItems(3).Text
period= listviewName.SelectedItems(i).SubItems(4).Text
'*********** delete **************'
cmd1.Connection = MYSQLCON
MYSQLCON.Open()
cmd1.CommandText = "DELETE FROM tablename WHERE columnname = '" & name & "'"
reader = cmd1.ExecuteReader
MYSQLCON.Close()
Next
End If
I have found the answer by casting the listview item to the created structure SimpleData then looping through it
Dim getitems = CType(listView1.SelectedItem, SimpleData)
For Each mem In getitems.Txt1
MsgBox(mem.ToString)
Next

VB.NET DataGridView "An item with the same key has already been added." while using a unique index

VB.NET 2010, .NET 4
Hello,
I've looked around and can't seem to find a solution to my problem. I have an EventLog object which inherits DataGridView and has a public variable EventList which is a List(Of EventLogItem). EventLogItem has seven properties which describe the event, including Index which is set to EventList.Count each time an entry is added (so, it should be unique). Everything has worked just fine until I tried to add an entry from a serial port DataReceived event handler upon which I receive the following exception:
An error occurred creating the form. See Exception.InnerException for details. The error is: An item with the same key has already been added.
Clicking 'View Details' and expanding the InnerException yields no more information. Here is some relevant code:
The EventLog class with its EventList:
Public Class EventLog
Inherits DataGridView
Public EventList As New List(Of EventLogItem)
..Column creation code, etc..
End Class
The EventLogItem class:
Public Class EventLogItem
Public Property Index As Integer
Public Property Timestamp As String
Public Property User As String = String.Empty
Public Property [Step] As String = String.Empty
Public Property Type As Types
Public Property Message As String
Public Property TypeIcon As Image
Public Enum Types
SeriousError = -2
NormalError = -1
Warning = 0
NormalEvent = 1
ImportantEvent = 2
ManualEntry = 3
End Enum
Private Sub New()
Me.Timestamp = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss.f")
Me.Type = Types.NormalEvent
SetTypeIcon()
End Sub
Public Sub New(ByVal Message As String)
Me.New()
Me.Message = Message
End Sub
Public Sub New(ByVal Message As String, ByVal User As String)
Me.New()
Me.Message = Message
Me.User = User
End Sub
Public Sub New(ByVal Message As String, ByVal User As String, ByVal Type As Types)
Me.New(Message, User)
Me.Type = Type
SetTypeIcon()
End Sub
Public Sub New(ByVal Message As String, ByVal User As String, ByVal Type As Types, ByVal [Step] As Integer)
Me.New(Message, User, Type)
Me.Step = ([Step] + 1).ToString
End Sub
Private Sub SetTypeIcon()
Select Case Me.Type
Case Types.NormalError
Me.TypeIcon = My.Resources.ErrorIcon
Case Types.SeriousError
Me.TypeIcon = My.Resources.ErrorIcon
Case Types.Warning
Me.TypeIcon = My.Resources.WarningIcon
Case Types.ManualEntry
Me.TypeIcon = My.Resources.ManualIcon
Case Else
Me.TypeIcon = My.Resources.OkayIcon
End Select
End Sub
End Class
Code for inserting an item into the event log:
Inside my main-form class:
Public Sub NewEventLogEntry(ByVal Message As String, ByVal ex As Exception, ByVal Type As EventLogItem.Types, ByVal IncludeProcessStepNumber As Boolean)
If IncludeProcessStepNumber Then
SafeInvokeControl(EventLog, Sub(x)
Dim FirstRow As Integer = x.FirstDisplayedScrollingRowIndex
Dim [Event] As New EventLogItem(Message, My.Settings.SelectedUser, Type, Device.CurrentProcessStep)
[Event].Index = x.RowCount + 1
x.EventList.Insert(0, [Event])
x.DataSource = GetType(List(Of EventLogItem))
x.DataSource = x.EventList
x.SetRowStyles()
If FirstRow >= 0 And FirstRow < x.RowCount Then x.FirstDisplayedScrollingRowIndex = FirstRow
End Sub)
Else
SafeInvokeControl(EventLog, Sub(x)
Dim FirstRow As Integer = x.FirstDisplayedScrollingRowIndex
Dim [Event] As New EventLogItem(Message, My.Settings.SelectedUser, Type)
[Event].Index = x.RowCount + 1
x.EventList.Insert(0, [Event])
x.DataSource = GetType(List(Of EventLogItem))
x.DataSource = x.EventList
x.SetRowStyles()
If FirstRow >= 0 And FirstRow < x.RowCount Then x.FirstDisplayedScrollingRowIndex = FirstRow
End Sub)
End If
If Type < EventLogItem.Types.Warning Then
Dim ErrorBox As New ErrorBox
Dim ErrorBoxThread As New Threading.Thread(AddressOf ErrorBox.ShowDialog)
ErrorBoxThread.IsBackground = True
ErrorBox.Exception = ex
If Type = EventLogItem.Types.NormalError Then
ErrorBox.Type = ErrorBox.Types.Error
ErrorBox.Message = Message
ElseIf Type = EventLogItem.Types.SeriousError Then
ErrorBox.Type = ErrorBox.Types.SeriousError
ErrorBox.Message = Message & vbNewLine & vbNewLine & "This is a serious error and indicates that the program is " & _
"unstable. The source of this error should be corrected before this program is used for anything important."
End If
StopMasterTimer()
ErrorBoxThread.Start()
End If
End Sub
end main-form class snippet
The code that's causing the problem (ch4cp is my namespace. this code resides in a class other than my main-form class):
Inside a serial port device class:
<Runtime.CompilerServices.MethodImplAttribute(Runtime.CompilerServices.MethodImplOptions.Synchronized)> _
Private Shared Sub Port_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles Port.DataReceived
..some code..
ch4cp.NewEventLogEntry("testing")
..some more code..
End Sub
End serial port device class snippet
Any ideas?
Thanks a lot in advance.
It sounds like you are getting a thread exception error in your code somewhere. The threading problem will cause other issues and not appear until you step through the code and look at each line being executed.
Try the following at the beginning of your code block to try to identify the problem.
Control.CheckForIllegalCrossThreadCalls = false

VB.NET using LINQ to transpose an ObservableCollection

I have a custom item class (basically two string values with associated properties), as below:
Public Class itmDataDetails
Private _strDataName As String
Private _strDataValue As String
Public Property strDataName() As String
Get
Return _strDataName
End Get
Set(ByVal value As String)
_strDataName = value
End Set
End Property
Public Property strDataValue() As String
Get
Return _strDataValue
End Get
Set(ByVal value As String)
_strDataValue = value
End Set
End Property
Public Sub New(Optional ByVal strDataNameIn As String = "", Optional ByVal strDataValueIn As String = "")
strDataName = strDataNameIn
strDataValue = strDataValueIn
End Sub
and an ObservableCollection wrapper class around this. I'd like to transpose this ObservableCollection (that is, make the data names into the columns and their associated values into the rows) for display in a WPF ListView.
Here's what I have so far:
Private Sub Transpose()
Dim colGroupedValues = From x In MyBase.Items Group x By Key = x.strDataName Into Group Select strName = Key, colValues = Group
MyBase.Clear()
For Each x In colGroupedValues
MyBase.Add(x)
Next
End Sub
Naturally, this doesn't work as x cannot be added to the ObservableCollection(Of itmDataDetails). Any suggestions on how to accomplish this? I don't know LINQ that well, so I wouldn't be surprised to discover I'm doing it wrong.
Thanks in advance, everyone.
So I think I was asking the wrong question here. What I really wanted was to have each column in a GridView be set to the DataName part of itmDataDetails and its corresponding records be set to the DataValue.
To do this, I followed the helpful guide at: http://weblogs.asp.net/psheriff/archive/2010/03/08/using-a-wpf-listview-as-a-datagrid.aspx
So the whole thing is replaced by:
Private Sub FillDataList()
Dim strConnectionString As String = "INSERT CONNECTION INFO HERE"
Dim strCommandString As String = "INSERT QUERY HERE"
Dim objCommand As New OleDb.OleDbCommand(strCommandString)
Dim objConnection As New OleDb.OleDbConnection(strConnectionString)
Dim objAdapter As New OleDb.OleDbDataAdapter
Dim ds As New DataSet
objConnection.Open()
objAdapter.SelectCommand = objCommand
objCommand.Connection = objConnection
objAdapter.Fill(ds)
lsvData.View = BuildDataView(ds)
lsvData.DataContext = ds.Tables(0)
lsvData.SetBinding(ListView.ItemsSourceProperty, New Binding)
objConnection.Close()
End Sub
Public Function BuildDataView(ByVal ds As DataSet) As GridView
Dim gv As New GridView
For Each item As DataColumn In ds.Tables(0).Columns
Dim gvc As New GridViewColumn
gvc.DisplayMemberBinding = New Binding(item.ColumnName)
gvc.Header = item.ColumnName
gvc.Width = [Double].NaN
gv.Columns.Add(gvc)
Next
Return gv
End Function
This gives me what I wanted. Sorry for the misunderstanding, if there was any. I'll still accept an answer that does this task better than my solution (to be charitable, etc.)
I also suspect that the database engine doesn't matter here, so you could probably do something similar for Oracle databases, etc.

Categories

Resources