TSFLLC
asked on
Dynamically access private variable value created and populated in windows form
I use the following code to get the values of textboxes below, but I have 6 private variables that I need to dynamically access in the same way.
I've been looking through System.Windows.Forms.* but cannot find anything that resembles how I would do it.
Please help.
I've been looking through System.Windows.Forms.* but cannot find anything that resembles how I would do it.
Please help.
Private Function GetLocalControl(ByVal ctrlName As String) As System.Windows.Forms.Control
For Each ctrl As Control In Me.Controls
If ctrl.Name = ctrlName.Trim Then
Return ctrl
End If
Next
For Each ctrl As Control In gb1.Controls
If ctrl.Name = ctrlName.Trim Then
Return ctrl
End If
Next
For Each ctrl As Control In gb3.Controls
If ctrl.Name = ctrlName.Trim Then
Return ctrl
End If
Next
Return Nothing
End Function
>>From Calling Sub
xField = CType(GetLocalControl(dvSortFields(j)("field_code_name").ToString), TextBox).Text
vals(j) = xField
>> perform find using vals
ASKER
Thanks Idle_Mind
1) The version is VB.NET 2005 Professional
2) The coding snippets are below
3) I populate the variables below. The glSortOrderFieldName1 = the sort order field name in the table. I use the glSortOrderFieldTypeX variables to define the field type of the sort fields are:
d = "Date"
t = "Text"
n = "Long"
I allow for the possibility of six sort fields. If the glSortOrderFieldTypeX = "" I exit with EndWhile
Then perform a find on the existing or new row in dvGlobalContacts.
dvGlobalContacts in form is sorted based on using the dvTableSortOrder(0)("sort_ order_fiel ds").tostr ing
dvGlobalContacts.Sort = dvTableSortOrder(0)("sort_ order_fiel ds").tostr ing
In saving a row I perform a find on the table after the dvTable is re-freshed with values of the form fields in the order of the user-defined sort order.
Below is the real problem. I don't know how to code something that would go in place of the ???? in the code snippet below:
???? CType(GetLocalControl("glS ortOrderFi eldType" & Trim(Str(j))).ToString), variable).Text
Hope all makes sense.
1) The version is VB.NET 2005 Professional
2) The coding snippets are below
3) I populate the variables below. The glSortOrderFieldName1 = the sort order field name in the table. I use the glSortOrderFieldTypeX variables to define the field type of the sort fields are:
d = "Date"
t = "Text"
n = "Long"
I allow for the possibility of six sort fields. If the glSortOrderFieldTypeX = "" I exit with EndWhile
Then perform a find on the existing or new row in dvGlobalContacts.
dvGlobalContacts in form is sorted based on using the dvTableSortOrder(0)("sort_
dvGlobalContacts.Sort = dvTableSortOrder(0)("sort_
In saving a row I perform a find on the table after the dvTable is re-freshed with values of the form fields in the order of the user-defined sort order.
Below is the real problem. I don't know how to code something that would go in place of the ???? in the code snippet below:
???? CType(GetLocalControl("glS
Hope all makes sense.
>> As form is initializing
Private dvTableSortOrder As New DataView
Private glSortOrderFieldCount As Integer = 0
Private glSortOrderFieldName1 As String = ""
Private glSortOrderFieldName2 As String = ""
Private glSortOrderFieldName3 As String = ""
Private glSortOrderFieldName4 As String = ""
Private glSortOrderFieldName5 As String = ""
Private glSortOrderFieldName6 As String = ""
Private glSortOrderFieldType1 As String = ""
Private glSortOrderFieldType2 As String = ""
Private glSortOrderFieldType3 As String = ""
Private glSortOrderFieldType4 As String = ""
Private glSortOrderFieldType5 As String = ""
Private glSortOrderFieldType6 As String = ""
>> Sub that populates the variables
Private Sub GetUserTableSortOrderValues()
Dim da As New SqlDataAdapter
Dim ds As New DataSet
Dim dt As New DataTable
da.SelectCommand = New SqlCommand
da.SelectCommand.Connection = TSFConnection
da.SelectCommand.CommandType = CommandType.StoredProcedure
da.SelectCommand.CommandText = "SPGS_SelectUserSortOrderDefaults"
da.SelectCommand.Parameters.Add(New SqlParameter("@TableName", "contact"))
da.SelectCommand.Parameters.Add(New SqlParameter("@UserID", glUserID))
da.Fill(ds, "user_account")
dt = ds.Tables(0)
dvTableSortOrder.Table = dt
If dvTableSortOrder.Count > 0 Then
glSortOrderFieldCount = dvTableSortOrder(0)("field_count").ToString
glSortOrderFieldName1 = dvTableSortOrder(0)("form_field_name1").ToString
glSortOrderFieldName2 = dvTableSortOrder(0)("form_field_name2").ToString
glSortOrderFieldName3 = dvTableSortOrder(0)("form_field_name3").ToString
glSortOrderFieldName4 = dvTableSortOrder(0)("form_field_name4").ToString
glSortOrderFieldName5 = dvTableSortOrder(0)("form_field_name5").ToString
glSortOrderFieldName6 = dvTableSortOrder(0)("form_field_name6").ToString
glSortOrderFieldType1 = dvTableSortOrder(0)("form_field_type1").ToString
glSortOrderFieldType2 = dvTableSortOrder(0)("form_field_type2").ToString
glSortOrderFieldType3 = dvTableSortOrder(0)("form_field_type3").ToString
glSortOrderFieldType4 = dvTableSortOrder(0)("form_field_type4").ToString
glSortOrderFieldType5 = dvTableSortOrder(0)("form_field_type5").ToString
glSortOrderFieldType6 = dvTableSortOrder(0)("form_field_type6").ToString
End If
End Sub
>> From my SaveRecord Sub
>> The ???? represents what I would code to be able to access the value of the glSortOrderFieldNameX variables
GetUserTableSortOrderValues() ' I refresh the user's sort order in certain cases
Dim j As Int64 = 1, vals(Convert.ToInt16(dvTableSortOrder(0)("field_count").ToString)) As Object, xField As String = "", xField2 As Long = 0, xEndWhile As Boolean = True
While xEndWhile
If ???? = "" Then
Exit While
ElseIf ???? = "d" Then ' Field Type = Date
xField = Format(CDate(CType(GetLocalControl(dvTableSortOrder(0)("form_field_name" & Trim(Str(j))).ToString), TextBox).Text), "MM/d/yyyy hh:mm:ss tt")
vals(j) = xField
ElseIf ???? = "t" Then ' Field Type = Text
xField = CType(GetLocalControl(dvTableSortOrder(0)("form_field_name" & Trim(Str(j))).ToString), TextBox).Text
vals(j) = xField
ElseIf ???? = "n" Then ' Field Type = Numeric
xField2 = CLng(CType(GetLocalControl(dvTableSortOrder(0)("form_field_name" & Trim(Str(j))).ToString), TextBox).Text)
vals(j) = xField2
End If
j = j + 1
End While
j = dvGlobalContacts.Find(vals)
If j >= 0 Then
glCurrentContactEntryRow = j
Else
glCurrentContactEntryRow = 0
End If
Let's start with a tip...
Replace your GetLocalControl() function with:
Private Function GetLocalControl(ByVal ctrlName As String) As Control
Dim matches() As Control = Me.Controls.Find(ctrlName. Trim, True)
If matches.Length > 0 Then
Return matches(0)
End If
Return Nothing
End Function
With regard to the variables...not sure I follow yet.
You have glSortOrderFieldName1 thru glSortOrderFieldName6...an d I think you want to do something like?
*** PSEUDO CODE ***
For i As Integer = 1 To 6
Select Case glSortOrderFieldName & i
Case "d"
Case "t"
Case "n"
Case ""
Exit Sub
End Select
Next
If that is the case then REFLECTION is what you're looking for. Let me know if the above is what you want and I'll post relevant code.
Replace your GetLocalControl() function with:
Private Function GetLocalControl(ByVal ctrlName As String) As Control
Dim matches() As Control = Me.Controls.Find(ctrlName.
If matches.Length > 0 Then
Return matches(0)
End If
Return Nothing
End Function
With regard to the variables...not sure I follow yet.
You have glSortOrderFieldName1 thru glSortOrderFieldName6...an
*** PSEUDO CODE ***
For i As Integer = 1 To 6
Select Case glSortOrderFieldName & i
Case "d"
Case "t"
Case "n"
Case ""
Exit Sub
End Select
Next
If that is the case then REFLECTION is what you're looking for. Let me know if the above is what you want and I'll post relevant code.
ASKER
Why are you wanting me to replace my GetLocalControl() function?? Is yours more efficient?
YES, that is exactly what I want to do. I need to loop through them dynamically and get each value!!
Please post. I'm curious to see how you're going to use reflection to do this. Thanks!
YES, that is exactly what I want to do. I need to loop through them dynamically and get each value!!
Please post. I'm curious to see how you're going to use reflection to do this. Thanks!
ASKER
As far as 'more efficient' evidently you don't have to specify separate panels in order to access the controls. It allows for accessibility to ALL controls on the form?
Correct. The Controls.Find() method (with the True parameter) will recursively search ALL containers on the form for matches. GetLocalControl() would then not have to be "fixed" if you were to add more containers or change the name of your existing ones.
There is nothing wrong with hard-coding the search as you did...just thought you would be interested to see a more generic approach. =)
I'll whip up a simplified Reflection example to demonstrate my above pseudo code...
There is nothing wrong with hard-coding the search as you did...just thought you would be interested to see a more generic approach. =)
I'll whip up a simplified Reflection example to demonstrate my above pseudo code...
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
This is too good to be true :) :) :) :)
Including the SetValue.
I know this is asking alot, but I have an open EE question that basically involves the same thing only from a class library ---> private/global variables in a different project form. Can you either post an example of the changes above or into the other EE posting where you would do the same in a form from class library (CLibrary1) to a form in a project (MyProject) where variable exists.
https://www.experts-exchange.com/questions/24512892/Class-Library-and-Project-code-to-access-form-from-class-library-where-form-exists-in-project.html
JackofPH has given a valiant effort, but I'm with 'a paper bag over my head' when it comes to Reflection and this issue and it appears that the code you've included is, with a few minor adjustments, going to resolve that problem also. I have so much on my mind right now I didn't even realize the two would involve the same ideas.
I will definitely up the ante on your 'beer fund'. You've helped me MANY times Mike.
Including the SetValue.
I know this is asking alot, but I have an open EE question that basically involves the same thing only from a class library ---> private/global variables in a different project form. Can you either post an example of the changes above or into the other EE posting where you would do the same in a form from class library (CLibrary1) to a form in a project (MyProject) where variable exists.
https://www.experts-exchange.com/questions/24512892/Class-Library-and-Project-code-to-access-form-from-class-library-where-form-exists-in-project.html
JackofPH has given a valiant effort, but I'm with 'a paper bag over my head' when it comes to Reflection and this issue and it appears that the code you've included is, with a few minor adjustments, going to resolve that problem also. I have so much on my mind right now I didn't even realize the two would involve the same ideas.
I will definitely up the ante on your 'beer fund'. You've helped me MANY times Mike.
ASKER
Very timely in answering and well designed....well documented
Glad that was what you needed. =)
I took a peek at your other question there. Based on your pseudo snippet:
Dim frm As String = "MyForm"
Dim frmID as String = "MyVariable"
Application.OpenForms(frm) .?
Jack's last link involving Activator is what you're looking for.
Now I haven't dealt with this across projects, though, so I can't give you concrete bullet proof code...but this is how you would do it within the same project:
Dim frmName As String = "Form2"
Dim assm As Assembly = Assembly.GetExecutingAssem bly
Dim frm As Form = assm.CreateInstance(assm.G etName.Nam e & "." & frmName)
If Not IsNothing(frm) Then
frm.Show()
End If
I would ~assume~ that you could do this with any assembly (you use LoadAssembly() probably?)...but here I am showing my inexperience with this topic. =)
I took a peek at your other question there. Based on your pseudo snippet:
Dim frm As String = "MyForm"
Dim frmID as String = "MyVariable"
Application.OpenForms(frm)
Jack's last link involving Activator is what you're looking for.
Now I haven't dealt with this across projects, though, so I can't give you concrete bullet proof code...but this is how you would do it within the same project:
Dim frmName As String = "Form2"
Dim assm As Assembly = Assembly.GetExecutingAssem
Dim frm As Form = assm.CreateInstance(assm.G
If Not IsNothing(frm) Then
frm.Show()
End If
I would ~assume~ that you could do this with any assembly (you use LoadAssembly() probably?)...but here I am showing my inexperience with this topic. =)
ASKER
Quite alright. Just tested the other code. Had to make one minor tweek but works great.
The value I needed was from glSortOrderFieldType + x....not glSortOrderFieldName + x. Probably an overlook.
The value I needed was from glSortOrderFieldType + x....not glSortOrderFieldName + x. Probably an overlook.
Just FYI, there is an alternative to Reflection using the legacy CallByName() method from VB6. It has a limitation on it, however, in that it only works on PUBLIC fields. Many find this syntax easier to stomach...it's just not as powerful as Reflection:
http://msdn.microsoft.com/en-us/library/chsc1tx6(VS.80).aspx
Similar example to original using CallByName():
http://msdn.microsoft.com/en-us/library/chsc1tx6(VS.80).aspx
Similar example to original using CallByName():
Public Class Form1
' They have to be PUBLIC for CallByName() to work:
Public glSortOrderFieldName1 As String = "a"
Public glSortOrderFieldName2 As String = "b"
Public glSortOrderFieldName3 As String = "c"
Public glSortOrderFieldName4 As String = "d"
Public glSortOrderFieldName5 As String = "e"
Public glSortOrderFieldName6 As String = "f"
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim varBaseName As String = "glSortOrderFieldName"
Dim varName, value As String
For i As Integer = 1 To 6
varName = varBaseName & i
value = CallByName(Me, varName, CallType.Get)
MessageBox.Show(varName & " = " & value, "Isn't Reflectoin Cool?", MessageBoxButtons.OK, MessageBoxIcon.Information)
CallByName(Me, varName, CallType.Let, value & " (touched)")
Next
End Sub
End Class
(2) Show us the declaration for your private variables.
(3) Can you show us the relationshiop between the controls and the variables you want to access? That is to say...for instance, given the name of the control, can you can easily determine the name of the variable you want?