|
-
Aug 25th, 2010, 03:40 PM
#1
Thread Starter
Addicted Member
[RESOLVED] UserControl Question
Hi all
Description of problem: I have a simple form with a usercontrol on it. There is a drop down box with a list of departments in it and a button, this is all in the usercontrol. I pick a department then press the button to view the employees in a listview for the department picked. All worked fine until I moved the code for drop down and button into the usercontrol from the form.
The data is taken from oracle database express 10G edition and I am using a cursor package (CP) and I pass parameters from the code to the oracle procedure within the CP. One of these parameters is the selected department from the drop down list (which I have picked) and my code does not seem to be picking up this parameter, it keps saying that the bold bit of code below is nothing:
Code:
myCmd.Parameters.Add(New OracleParameter("n_dept", OracleDbType.Varchar2)).Value = usr1.cmbDepartments.SelectedItem
Everything else seems to be fine. Because it is not picking up the selected item then the dr.read (no data by the looks of it) is false and it just falls out without populating any employees for that dept in the listview.
Does anyone care to take a stab at suggesting what might be wrong? Why won't it pick up the selected item in the user control I have just picked it in?
Thanks
G
Last edited by Grifter; Aug 25th, 2010 at 03:46 PM.
-
Aug 25th, 2010, 04:34 PM
#2
Re: UserControl Question
Because an item isn't selected? That's the only reason SelectedItem would ever be Nothing (unless, of course, you've added Nothing values to your ComboBox). Maybe check SelectedIndex, too.
-
Aug 25th, 2010, 04:59 PM
#3
Re: UserControl Question
If you moved this code into the usercontrol then surely you dont need to say usr1.cmbDepartments but just cmbDepartments ? Do you have a public instances called usr1 that is not the one in question?
-
Aug 25th, 2010, 05:00 PM
#4
Re: UserControl Question
I think he's referencing the ComboBox from the form, not the UserControl. By default, the scope for added controls is Friend in VB.NET, Private in C#.
-
Aug 25th, 2010, 05:01 PM
#5
Re: UserControl Question
 Originally Posted by Grifter
I pick a department then press the button to view the employees in a listview for the department picked.
You sure? the button is on the usercontrol.
-
Aug 25th, 2010, 05:15 PM
#6
Re: UserControl Question
That would make the code impossible to build, though - UserControls don't have default instances.
-
Aug 25th, 2010, 05:16 PM
#7
Re: UserControl Question
Thats why I went for the public instance being declared but not being used in this case hence the nothing
-
Aug 25th, 2010, 05:31 PM
#8
Re: UserControl Question
so is the query within the usercontrol or in the parent form?
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
-
Aug 26th, 2010, 12:48 AM
#9
Thread Starter
Addicted Member
Re: UserControl Question
Finding it hard deciding who too respoond to first. What I will do is post the code from the different classes etc and see if anyone can see the issue:
User control class:
Code:
Public Class UserControl1
Dim emp As New employees
Private Sub btn1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btn1.Click
With cmbDepartments
If .SelectedItem Is Nothing Then
MessageBox.Show("Please Pick a Department Before Continuing.", "Pick Department")
.Focus()
Else
Form1.ListView1.Items.Clear()
Form1.SetListViewColumns()
emp.getEmployeeDetails() ' Changed 19/05/2010
End If
End With
End Sub
Private Sub UserControl1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
Dim queryStr1 As String = "Select department_name from departments"
'Dim queryStr2 As String = "Select department_id from departments"
Me.connectToOra(queryStr1)
End Sub
' Pass cmbbox, sql query string, table column, and connection string to db, for this function
' Use function to dimension array
' to dimension count for array
' to dimension connection as new oracle connection
' Associate parameter function connstr string value with oracle connection object
' Fire 'try' statement to firstly connect to DB with error handling
' Finish 'try' then dimension a new oracle command object
' Associate sql string (sqlstr) to command text
' Associate command type text as command type
' Associate oracle connection with commmand type connection
' Dimension oracle data reader
' Start 'try' to read data into array
' Use variable table column to read each value in the passed table column to the array
' Add count 1 to each value put in the array
' once array is populated use combobox parameter to additems to the combo box
' Return the array
' Close the connection
' Dispose of the connection object
Public Function populateComboDepts(ByVal cmbBox As ComboBox, _
ByVal sqlStr As String, _
ByVal tableCol As String, _
ByVal connStr As String) As String()
Dim array(0) As String
Dim cnt As Integer = 0
Dim conn As New OracleConnection
conn.ConnectionString = connStr
Try
conn.Open()
Catch ex As Exception
MessageBox.Show("Error: " & ex.Message)
MsgBox("Failed connection to Oracle" & ex.Message)
'Return array
End Try
Dim cmd As New OracleCommand
With cmd
.CommandText = sqlStr
.CommandType = CommandType.Text
.Connection = conn
End With
Dim dr As OracleDataReader
dr = cmd.ExecuteReader
Try
While dr.Read
ReDim Preserve array(cnt)
array(cnt) = dr.Item(tableCol)
cnt = cnt + 1
End While
'cmbBox.Items.Clear()
cmbBox.Items.AddRange(array)
'Return array
Catch ex As Exception
MessageBox.Show(ex.Message, "Error")
'Dim a(0) As String
'a(0) = 0
'Return a
Finally
conn.Close()
conn.Dispose()
End Try
Return array
End Function
Public Sub connectToOra(ByVal queryStr1 As String)
Try
Dim xe As String = "Data Source=XE;User Id=hr;Password=hr;"
Dim conn As New OracleConnection(xe) ' Associate connection string with connection object
conn.Open()
Dim sql1 As String = queryStr1
'Dim sql2 As String = queryStr2
Dim cmd As New OracleCommand(sql1, conn)
cmd.CommandType = CommandType.Text
Dim dr As OracleDataReader = cmd.ExecuteReader
dr.Read()
populateComboDepts(Me.cmbDepartments, sql1, "department_name", xe)
'populateComboDeptID(cmbDeptID, sql2, "department_id", xe)
conn.Dispose()
Catch ex As Exception
MessageBox.Show("Error: " & ex.Message)
Finally
End Try
End Sub
End Class
Employees Class:
Code:
Public Class employees
Private mEmployees As New Collection
Public Function count() As Long
count = mEmployees.Count
End Function
Public Sub remove(ByVal index As VariantType)
mEmployees.Remove(index)
End Sub
Public Function item(ByVal index As VariantType) As employee
item = mEmployees.Item(index)
End Function
Public Function newenum()
newenum = mEmployees.GetEnumerator
End Function
Public Sub getEmployeeDetails()
Dim usr1 As UserControl1
usr1 = New UserControl1
Dim ds As New DataSet
Dim xe As String = "Data Source = XE; User id=hr;Password=hr;"
Dim conn As New OracleConnection(xe)
conn.Open()
Dim myCmd As New OracleCommand
myCmd.Connection = conn
myCmd.CommandText = "curspkg_emp.emp_details_cursor1"
myCmd.CommandType = CommandType.StoredProcedure
myCmd.Parameters.Add(New OracleParameter("n_dept", OracleDbType.Varchar2)).Value = usr1.cmbDepartments.SelectedItem
<< Here's where it is not picking up the selected item
myCmd.Parameters.Add(New OracleParameter("io_cursor", OracleDbType.RefCursor)).Direction = ParameterDirection.Output
Dim dr As OracleDataReader = myCmd.ExecuteReader
Dim emp As employee
emp = New employee
While dr.Read
With emp
.EmployeeID = dr.Item("Employee_ID")
.FirstName = dr.Item("First_Name")
.LastName = dr.Item("Last_Name")
.Email = dr.Item("Email")
.PhoneNumber = dr.Item("Phone_Number")
.HireDate = dr.Item("Hire_Date")
.JobID = dr.Item("Job_ID")
.Salary = dr.Item("Salary").ToString
If IsDBNull(dr.Item("Commission_PCT")) Then
.CommissionPCT = 0
Else
.CommissionPCT = dr.Item("Commission_PCT")
End If
If IsDBNull(dr.Item("Manager_ID")) Then
.ManagerID = 0
Else
.ManagerID = dr.Item("Manager_ID")
End If
.DepartmentID = dr.Item("Department_ID")
End With
Dim lst As New ListViewItem
Form1.ListView1.Items.Add(lst)
lst.Text = dr.Item("Employee_ID")
With lst.SubItems
.Add(dr.Item("First_Name"))
.Add(dr.Item("Last_Name"))
.Add(dr.Item("Email"))
.Add(dr.Item("Phone_Number"))
.Add(dr.Item("Hire_Date"))
.Add(dr.Item("Job_ID"))
.Add(dr.Item("Salary").ToString)
If IsDBNull(dr.Item("Commission_PCT")) Then
.Add(0)
Else
.Add(dr.Item("Commission_PCT"))
End If
If IsDBNull(dr.Item("Manager_ID")) Then
.Add(0)
Else
.Add(dr.Item("Manager_ID"))
End If
.Add(dr.Item("Department_ID"))
mEmployees.Add(emp)
End With
'Print("Hello")
lst = Nothing
End While
End Sub
End Class
There is a form1 class but so little in it that's it's pointless posting. Now I think someone mentioned that if the selected item is nothing then it means it is not selected but when I had all the controls on the form it worked fine, all I have done is move the code to a user control.
I think it's something to do with an incorrect instance setting or something but not exactly sure. I also notice that if I press F8 and go right through the code it loops through this bit twice In user control and tries to pick up a collection in employees class which isn't yet available. Is that right that it tries to pick up a collection, even when not there?:
Code:
Dim emp As New employees
I still get a bit mixed up with these instances, does new mean a clean instance with no data or a newly created instance of an existing object or both, that is what gets me sometimes. Sometimes an instance is not declared as new, sometimes it is.
Any ideas?
G
-
Aug 26th, 2010, 03:48 AM
#10
Re: UserControl Question
Dim usr1 As UserControl1 'You have declared a variable that will hold a reference to an object, currently it does not point to anything
usr1 = New UserControl1 'You have created a brand new usercontrol, assuming you have one on your form, this is then a second copy
As you declared this inside a method you will loose reference to it when the method is complete.
So when you call usr1.xxxx you are using the New copy which you can not see as you have never shown it to the user, and as such will have no values selected.
The way to get around this (the quickest way anyway) is to pass the usercontrol that calls this method as a paramter so:
Code:
emp.getEmployeeDetails(Me)
....
Public Sub getEmployeeDetails(usr1 As UserControl1)
'remove local declaration
Dim ds As New DataSet
....
-
Aug 26th, 2010, 03:57 AM
#11
Re: UserControl Question
I think you are being confused by this:
Form1.ListView1.Items.Clear()
For some reason MS decided to bring back in default instance names for forms, to help those VB6 users who are converting up. When you call Form1.xxx if Form1 has never been created ie Dim Form1 As New Form1, then it will do it for you. You can access it from anywhere and things look much simpler to code, however you have just shot yourself in the foot in the design sense. You call Form1. while inside your UserControl1, which means that your usercontrol can not be placed on any form, only ever the default instance of Form1. The idea of a usercontrol is that you can re-use it, put it on Form2 put it on a different copy of Form1. Controls have the ability to raise events to tell their parents that an action is required.
In your case you could do this
Code:
'At top of usercontrol
Public Event SetupSelection()
'Inside your sub instead of
'Form1.ListView1.Items.Clear()
'Form1.SetListViewColumns()
RaiseEvent SetupSelection
'Inside your form you can handle the UserControl1_SetupSelection event and add
ListView1.Items.Clear()
SetListViewColumns()
This way the form and usercontrol do not interact with their local objects via anything other than their public interface. If the Form1 changes the ListView1 to a new name or you swap to a swanky new SuperListView1 then the usercontrol does not break.
-
Aug 26th, 2010, 01:11 PM
#12
Thread Starter
Addicted Member
Re: UserControl Question
Hi
I now have it working ok after doing what you said. This helps me understand the use of instances and user controls as well, which I am still trying to learn.
Thanks for all the replies
G
 Originally Posted by Grimfort
Dim usr1 As UserControl1 'You have declared a variable that will hold a reference to an object, currently it does not point to anything
usr1 = New UserControl1 'You have created a brand new usercontrol, assuming you have one on your form, this is then a second copy
As you declared this inside a method you will loose reference to it when the method is complete.
So when you call usr1.xxxx you are using the New copy which you can not see as you have never shown it to the user, and as such will have no values selected.
The way to get around this (the quickest way anyway) is to pass the usercontrol that calls this method as a paramter so:
Code:
emp.getEmployeeDetails(Me)
....
Public Sub getEmployeeDetails(usr1 As UserControl1)
'remove local declaration
Dim ds As New DataSet
....
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|