Wish [B4X] B4XComboBox ValueMember and DisplayMember

LucaMs

Expert
Licensed User
Longtime User
Not rarely (mainly in DBs managements) you need a ComboBox in which an Item is made of a display value and a diffent associated value, i.e. a "description field" of a table and the relative primary key (usually the classic Integer ID).

I found the B4XComboBox source code here but I know also that B4XComboBox is part of XUI Views.

What should I do? Just waiting? 😊
 

LucaMs

Expert
Licensed User
Longtime User
I modified B4XComboBox.bas so that it is possible to have what I was asking for, despite not having used those names (ValueMember and DisplayMember, as in VB Net). I also added two methods, to add a single item and to remove one.

I attach the .bas file (zipped) and the XUI Views.b4xlib library that I have updated to version 2.30.

These changes must first be approved by Erel.

[Erel, all my changes are signed with 'LM]


B4J example (but note that the main reason for my changes is to be able to make the best use of the B4XComboBox with DBs tables).
1.gif



P.S. Added another method: GetItemValue(Index As Int).


NOT APPROVED, FILES REMOVED.
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
It will not be added to XUI Views.
So it is better that I remove the 2 files attached.

It is trivial to implement this map in your own code
Sure but:
1 - it is not so trivial for beginners
2 - if it is already done internally, the user-programmer needs to do less work

1. Adding two events to a nice and simple class is a bad idea.
😲 All objects have more than one event.

2. Things will break if the user adds multiple items with the same "key".
I haven't tested the code much, since I knew that I would have to submit it to you, but I think I have avoided duplicate keys; i will check this.


So I will use the source of the class and make it a library just for me (with a different name).
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
So I will use the source of the class and make it a library just for me (with a different name).
You can follow the approach I follow with xCLV and create an extension class. The developer will pass B4XComboBox to your class and from that point will only use your class to access the items. This will give you freedom to extend it in many ways.
 

LucaMs

Expert
Licensed User
Longtime User
You can follow the approach I follow with xCLV and create an extension class. The developer will pass B4XComboBox to your class and from that point will only use your class to access the items. This will give you freedom to extend it in many ways.
I don't think I can do it.

Within my class, I cannot intercept the CmbBox_SelectedIndexChanged event or the setSelectedIndex setting, from the original B4XComboBox passed as argument to the class initialization.
 

zulkarkara

New Member
Use costumview like below may types of valuemember changes u can redesign
CustomCombo with valuemember and displaymember:
#Event: SelectedValueChanged(Value as Int,Text as String)
#DesignerProperty: Key: BooleanExample, DisplayName: Show Seconds, FieldType: Boolean, DefaultValue: True
#DesignerProperty: Key: TextColor, DisplayName: Text Color, FieldType: Color, DefaultValue: 0xFFFFFFFF, Description: Text color

Sub Class_Globals
    Private mEventName As String 'ignore
    Private mCallBack As Object 'ignore
    Public mBase As B4XView
    Private xui As XUI 'ignore
    Public Tag As Object
    Private mitems As List
    Private mvalue As String
    Private namelist As List
    Private cmb As ComboBox
    Private selected As Map
    Dim m As Map
End Sub
Public Sub setEnabled(Value As Boolean)
    cmb.Enabled=Value
End Sub

Public Sub Initialize (Callback As Object, EventName As String)
    mEventName = EventName
    mCallBack = Callback
'    items.Initialize
    namelist.Initialize
    cmb.Initialize("cmb")
End Sub

'Base type must be Object
Public Sub DesignerCreateView (Base As Object, Lbl As Label, Props As Map)
    mBase = Base
    Tag = mBase.Tag
    mBase.Tag = Me
    mBase.AddView(cmb,0,0,mBase.Width,mBase.Height)
'    mBase.LoadLayout("ComboExLay")
End Sub

Private Sub Base_Resize (Width As Double, Height As Double)
      cmb.SetSize(Width,Height)
End Sub

Public Sub Clear
    If    cmb.IsInitialized=True Then cmb.Items.Clear
End Sub

Private Sub AddList(Items As List,Display As String,ValueMember As String)
    For i=0 To Items.Size-1
        m = Items.Get(i)
        namelist.Add(m.Get(Display))
    Next
    cmb.Items.AddAll(namelist)
    mitems = Items
    mvalue=ValueMember
    namelist.Clear
End Sub

Public Sub ItemSource3(Items As List,Display As String,ValueMember As String,Default As Int,Text As String)
    Clear
    m=CreateMap(ValueMember:0,Display:Text)
    Items.InsertAt(0,m)
    AddList(Items,Display,ValueMember)
    cmb.SelectedIndex=Default
End Sub
Public Sub ItemSource2(Items As List,Display As String,ValueMember As String,Default As Int)
    Clear
    AddList(Items,Display,ValueMember)
    cmb.SelectedIndex=Default
    
End Sub
Public Sub ItemSource(Items As List,Display As String,ValueMember As String)
    Clear
    AddList(Items,Display,ValueMember)

End Sub
Private Sub cmb_SelectedIndexChanged(Index As Int, Value As Object)
    If Index < 0 Then Return
    If mitems.Size = 0 Then Return
    
    Dim i As Int=0
    selected = mitems.Get(Index)
    i=selected.Get(mvalue)
    CallSub3(mCallBack, mEventName & "_" & "SelectedValueChanged",i,Value)
End Sub
 
Top