Project structure and UserControl:
Formularios = Form = Form1
Controles de Usuario = User Controls = uc1
All UserControl Code:
Option Explicit
Public Property Get AddType() As String
AddType = cmbAddExample.Text
End Property
Public Property Let AddType(ByVal Value As String)
cmbAddExample.Text = Value
End Property
Public Property Get AddNumber() As String
AddNumber = Text1.Text
End Property
Public Property Let AddNumber(ByVal Value As String)
Text1.Text = Value
End Property
Button Add(Añadir) Code:
Option Explicit
Dim indice As Integer
Private Sub btnAñadir_Click()
indice = indice + 1
Load uc1(indice)
Set uc1(indice).Container = Picture1
uc1(indice).Visible = True
uc1(indice).Top = IIf(indice = 1, 0, uc1(indice - 1).Top + uc1(indice - 1).Height + 20)
Load cmbAddExample(indice)
Set cmbAddExample(indice).Container = uc1(indice)
cmbAddExample(indice).Visible = True
cmbAddExample(indice).Top = cmbAddExample(indice - 1).Top
CargaIDTipoNumero
Load Text1(indice)
Set Text1(indice).Container = uc1(indice)
Text1(indice).Visible = True
Text1(indice).Top = Text1(indice - 1).Top
uc1(indice).AddType = uc1(0).AddType
uc1(indice).AddType = ""
Picture1.Visible = True
If indice = 3 Then
Me.btnAñadir.Enabled = False
End If
End Sub
Black Circle is a UserControl with a TextBox and a ComboBox inside. Red Circle is a PictureBox.
So, the problem is that i need copy values from uc1 in PictureBox when i press the button add. But when i press the button, it shows me the next error:
Compilation Error: Method or data member not found.
In this line:
uc1(index).AddType = uc1(0).AddType
So, any sugerence?
In your post, you say the object circled in black is a UserControl when in fact it is a PictureBox named uc1(0). Since a PictureBox does not have an AddType property, you receive the error.
Replacing this PictureBox with a UserControl will resolve the error.
Related
I have a query, I have this interface:
The ComboBox are inside a UserControl, pressing the Add this UserControl button with the ComboBox adds the UserControl / ComboBox in a PictureBox:
What I want is that, for example, when the user selects values of the two ComboBox and press the button add these selected values go to the PictureBox (below) and the values that are selected in the UserControl are cleaned.I leave a picture of what I say, suppose the user selected the values of the combos:
Once you have selected them, the add these button is enabled, they pass below and those above are cleaned:
But, if I press the remove button you must remove the last loaded object and move to the top. I leave a descriptive image, press the remove button:
The bottom disappears and goes up:
Currently this is the code I use to add:
Option Explicit
Dim indice As Integer
Public Property Let AddType(ByVal Value As String)
cmbAddExample.Text = Value
End Property
Private Sub btnAñadir_Click()
indice = indice + 1
Picture1.Visible = True
Load uc1(indice)
Set uc1(indice).Container = Picture1
uc1(indice).Visible = True
uc1(indice).Top = IIf(indice = 1, 0, uc1(indice - 1).Top + uc1(indice - 1).Height + 20)
Load cmbAddExample(indice)
Set cmbAddExample(indice).Container = uc1(indice)
cmbAddExample(indice).Visible = True
cmbAddExample(indice).Top = cmbAddExample(indice - 1).Top
CargaIDTipoNumero
uc1(indice).AddType = uc1(0).AddType
uc1(indice).AddType = ""
If indice = 3 Then
Me.btnAñadir.Enabled = False
End If
End Sub
So, does anyone have any idea how I can do what I am looking for? Or yes, is it possible?
Button Remove:
Private Sub btnQuitar_Click()
indice = cmbAddExample().Count - 1
If indice > 0 Then
Unload cmbAddExample(indice)
End If
End Sub
Using this answer as the starting point, you can implement these requirements fairly easily. I have copied relevant code from the other answer and modified it:
Private Sub btnAdd_Click()
index = index + 1
Load uc1(index)
Set uc1(index).Container = Picture1
uc1(index).Visible = True
uc1(index).Top = IIf(index = 1, 0, uc1(index - 1).Top + uc1(index - 1).Height + 20)
'copy the information down
uc1(index).AddType = uc1(0).AddType
uc1(0).AddType = ""
Picture1.Visible = True
End Sub
Private Sub btnRemove_Click()
If index = 0 Then Exit Sub
'copy the information back up and remove the control
uc1(0).AddType = uc1(index).AddType
Unload uc1(index)
index = index - 1
If index = 0 Then Picture1.Visible = False
End Sub
I have only coded for one control to illustrate the concept. You can add other controls as needed.
At run-time I add a textbox with
Dim MRNCell As New TableCell
MRNCell.ID = "MRNCell"
Dim txtMRN As New TextBox
txtMRN.ID = "NewMRN"
MRNCell.Controls.Add(txtMRN)
MRNRow.Cells.Add(MRNCell)
I then attempt to access the Text property in a public readonly Property using PreviousPage. Below are three renditions of the Property, none of which works.
Public ReadOnly Property NewMRN() As String
Get
Dim NewMRNNum As TextBox = CType(Me.FindControl("NewMRN"), TextBox)
'NewMRNNum = Nothing
Return NewMRNNum.Text
End Get
End Property
Public ReadOnly Property NewMRN() As String
Get
Dim sNewMRN As String = String.Empty
For Each MyRow As TableRow In MyTable.Rows
For Each MyCell As TableCell In MyRow.Cells
If MyCell.ID = "MRNCell" Then
For Each MyControl As Control In MyCell.Controls
Dim MRNBox As New TextBox
MRNBox = TryCast(MyControl, TextBox)
If Not (MRNBox Is Nothing) Then
sNewMRN = MRNBox.Text
End If
Next
End If
Next
Next
'There is only one TextBox in the table and sNewMRN = ""
Return sNewMRN
End Get
End Property
Public ReadOnly Property NewMRN() As String
Get
'For this one the TextBox is declared Public in the class
'The Text property = ""
Return txtMRN.Text
End Get
End Property
I have two public readonly properties. The first one returns the Text property from a TextBox created in the designer and the other attempts to return the Text property created at run-time. One works and the other either throws an exception or returns an empty string, depending on which of the three methods I use.
If Not PreviousPage Is Nothing Then
'Works
Dim sMessageID As String = PreviousPage.MessageID
'Does not work
Dim sNewMRN As String = PreviousPage.NewMRN
Literal1.Text = "<p>" & sMessageID & "</p><p>" & sNewMRN & "</p>"
End If
So, how can I access the Text property of a Textbox created at run-time, have that value returned in a public readonly property, so I can access it with PreviousPage?
Greg
Once again, writing the question made me think about it enough that I came up with a solution. I add the textbox at design-time and set the visible property to false. Then at run-time I make it visible and add it to the table row cell.
Greg
i can add a value to array(0), but when i then add a value to array(1) it clears the value for array(0). I've tried every way I can think of to declare and create the array. My code looks like this:
Dim aryEstimateInfo() As String = New String(7) {}
Private Sub wzrdEstimateWizard_NextButtonClick(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.WizardNavigationEventArgs) Handles wzrdEstimateWizard.NextButtonClick
Select Case wzrdEstimateWizard.ActiveStepIndex
Case 0 'first estimate wizard step
aryEstimateInfo(0) = rad_lstVehicleType.SelectedItem.ToString
Case 1 'second estimate wizard step
Dim DamageZoneSelected As Boolean = False
For Each cntrl As Control In pnlDamageZone.Controls
If TypeOf cntrl Is RadioButton Then
Dim RadButton As RadioButton = cntrl
If RadButton.Checked Then
DamageZoneSelected = True
DamageZone = RadButton.Text.ToString
Exit For
Else
DamageZoneSelected = False
End If
End If
Next
If DamageZoneSelected = True Then
lblDamageZoneError.Visible = False
aryEstimateInfo(1) = DamageZone
Else
'if no damage zone is selected a message is displayed
wzrdEstimateWizard.ActiveStepIndex = 2
wzrdEstimateWizard.ActiveStepIndex = 1
lblDamageZoneError.Visible = True
End If
Case 2 'third estimate wizard step
'assigns the number of dents to the estimate array
aryEstimateInfo(2) = ddlNumberOfDents.SelectedValue.ToString
'sets the average dent size in the estimate arrau
aryEstimateInfo(3) = ddlDentSize.SelectedValue.ToString
'sets the add-on code and number of oversized dents
If ddlOverSized.Enabled = True Then
'aryEstimateInfo.SetValue("3", 4)
aryEstimateInfo(4) = "3"
aryEstimateInfo(7) = ddlOverSized.SelectedValue.ToString
Else
End If
Case 3 'fourth estimate wizard step
Case Else
End Select
End Sub
I'm using this in an ASP.Net wizard control and in basic, visual studio 2010.
The problem is that each button click is posting back the page, which causes your aryEstimateInfo to be re-created on each postback.
In order to handle this situation elegantly, improve the maintenance of the page, and make it easier to debug this sort of situation in the future, I recommend the following changes:
1) Change the array to a class with properties:
Public Class EstimateInfo
Public VehicleType As String = ""
Public DamageZone As String = ""
Public NumberOfDents As String = ""
Public DentSize As String = ""
Public AddOnCode As String = ""
Public Oversized As String = ""
End Class
Note that all of the properties are declared as string, but the data types should probably be changed to more accurately reflect the underlying content.
This approach will help debugging because you can change the auto-implemented property to a getter/setter so that you can place a breakpoint to see where the value is getting cleared:
Private m_sVehicleType As String = ""
Public Property VehicleType As String
Get
Return m_sVehicleType
End Get
Set (Value As String
' You could set a breakpoint here to discover where the value is getting cleared.
m_sVehicleType = Value
End Set
End Property
And if you need to have the values in a string array for export to a different application or database, for example, you could add a method to the class to produce an appropriate string array.
2) Add a property to the page to store the current answer class in the page's ViewState so that you won't have to continuously re-populate the array. For example:
Private Property EstimateInfo As EstimateInfo
Get
' Add a new record to the viewstate if it doesn't already exist
If ViewState("EstimateInfo") Is Nothing Then
Me.EstimateInfo = New EstimateInfo
End If
Return ViewState("EstimateInfo")
End Get
Set (value As EstimateInfo)
ViewState("EstimateInfo") = value
End Set
End Property
Once you do this, your wizard code becomes much easier to understand and maintain:
Select Case wzrdEstimateWizard.ActiveStepIndex
Case 0 'first estimate wizard step
Me.EstimateInfo.VehicleType = rad_lstVehicleType.SelectedItem.ToString
when you declare the new array someehere in the code you cannot reuse it again after post back.
I suggest to build the array on finish wizard event
you can use the controls in whole steps where ever step you in
I guess it will be fine
otherwise you need to store the array after every update in session or view state but I don't like both
sorry I couldn't view example becoz I'm using mobile
I am new in dev express technology. I am having a problem with devexpress XtraTreeList because i am unable to get node "NAME" and "TEXT" property.Please any one help me out through code.
One thing you need to keep in mind is that each node can be made up of multiple values. Based on the number of columns that are displayed. So, what you actually want to access is the particular column of a node in order to access or set the values for that column in the node.
For example:
TreeListColumn columnID1 = treeList1.Columns["Budget"];
// Get a cell's value in the first root node.
object cellValue1 = treeList1.Nodes[0][columnID1];
and
string columnID2 = "Budget";
// Get the display text of the focused node's cell
string cellText = treeList1.FocusedNode.GetDisplayText(columnID2);
Check out the devExpress documentation too. It's pretty helpful.
Maybe this example can help you:
Public Sub LoadTree()
TreeList1.Columns.Add().Name = "DisplayColumn"
Dim node1 = TreeList1.Nodes.Add("Father")
node1.Tag = "Father"
Dim node1_1 = TreeList1.Nodes.Add("Child Node")
node1_1.Tag = "Child Node"
Dim node1_1_1 = node1.Nodes.Add("This is a grandchild node")
node1_1_1.Tag = "Grandchild 1"
Dim node1_1_2 = node1.Nodes.Add("Another grandchild node")
node1_1_2.Tag = "Grandchild 2"
End Sub
Public Sub DisplayNodeValue(ByVal tag As String)
Dim valueToPresent = FirstTagValueInNode(TreeList1.Nodes, tag)
MsgBox(valueToPresent.ToString)
End Sub
Public Function FirstTagValueInNode(ByVal nodes As DevExpress.XtraTreeList.Nodes.TreeListNodes, ByVal tagSearch As Object)
For Each node As DevExpress.XtraTreeList.Nodes.TreeListNode In nodes
If node.Tag = tagSearch Then
Return node.GetValue(TreeList1.Columns(0))
End If
If node.Nodes.Count > 0 Then
Return FirstTagValueInNode(node.Nodes, tagSearch)
End If
Next
Return Nothing
End Function
In .Net you can use reflection to get access to an enumeration of all properties of a class. Can this be done too with a VB6 class module?
Found it!
You need to set a reference to the TypeLib library (tlbinf32.dll) and then you can use code like (this is class module):
EDIT: Unfortunately, while the code below works as expected when run in debug mode inside the VB6 IDE, it fails when compiled. After compiling any attempt to read the .Members propery causes an 'Object doesn't support this action' error (445). I have given up on it, unless someone can make the code below work both in and outside of the IDE.
Option Explicit
Private TLI As TLIApplication
Private m_clsInterface As InterfaceInfo
Private m_clsClassUnderInvestigation As Object
Private Sub Class_Terminate()
Set m_clsClassUnderInvestigation = Nothing
Set m_clsInterface = Nothing
Set TLI = Nothing
End Sub
Public Sub FillListBoxWithMembers(pList As ListBox, Optional pObject As Object)
Dim lMember As MemberInfo
If pObject = Empty Then
Set pObject = ClassUnderInvestigation
End If
Set m_clsInterface = TLI.InterfaceInfoFromObject(pObject)
For Each lMember In m_clsInterface.Members
pList.AddItem lMember.Name & " - " & WhatIsIt(lMember)
Next
Set pObject = Nothing
End Sub
Public Function GetPropertyLetNames() As Collection
Dim filters(1 To 1) As InvokeKinds
filters(1) = INVOKE_PROPERTYPUT
Set GetPropertyLetNames = Filter(filters)
End Function
Public Function GetPropertySetNames() As Collection
Dim filters(1 To 1) As InvokeKinds
filters(1) = INVOKE_PROPERTYPUTREF
Set GetPropertySetNames = Filter(filters)
End Function
Public Function GetPropertyLetAndSetNames() As Collection
Dim filters(1 To 2) As InvokeKinds
filters(1) = INVOKE_PROPERTYPUT
filters(2) = INVOKE_PROPERTYPUTREF
Set GetPropertyLetAndSetNames = Filter(filters)
End Function
Public Function GetPropertyGetNames() As Collection
Dim filters(1 To 1) As InvokeKinds
filters(1) = INVOKE_PROPERTYGET
Set GetPropertyGetNames = Filter(filters)
End Function
Private Function Filter(filters() As InvokeKinds) As Collection
Dim Result As New Collection
Dim clsMember As MemberInfo
Dim i As Integer
For Each clsMember In m_clsInterface.Members
For i = LBound(filters) To UBound(filters)
If clsMember.InvokeKind = filters(i) Then
Result.Add clsMember.Name
End If
Next i
Next
Set Filter = Result
End Function
Private Function WhatIsIt(lMember As Object) As String
Select Case lMember.InvokeKind
Case INVOKE_FUNC
If lMember.ReturnType.VarType <> VT_VOID Then
WhatIsIt = "Function"
Else
WhatIsIt = "Method"
End If
Case INVOKE_PROPERTYGET
WhatIsIt = "Property Get"
Case INVOKE_PROPERTYPUT
WhatIsIt = "Property Let"
Case INVOKE_PROPERTYPUTREF
WhatIsIt = "Property Set"
Case INVOKE_CONST
WhatIsIt = "Const"
Case INVOKE_EVENTFUNC
WhatIsIt = "Event"
Case Else
WhatIsIt = lMember.InvokeKind & " (Unknown)"
End Select
End Function
Private Sub Class_Initialize()
Set TLI = New TLIApplication
End Sub
Public Property Get ClassUnderInvestigation() As Object
Set ClassUnderInvestigation = m_clsClassUnderInvestigation
End Property
Public Property Set ClassUnderInvestigation(clsClassUnderInvestigation As Object)
Set m_clsClassUnderInvestigation = clsClassUnderInvestigation
Set m_clsInterface = TLI.InterfaceInfoFromObject(m_clsClassUnderInvestigation)
End Property
I am heavily endebted to this post.