On 01/11/10 19:21, John wrote:
> On Monday 11 January 2010 06:58:19 am Ed Leafe wrote:
>   
>> On Jan 11, 2010, at 8:13 AM, Paul McNett wrote:
>>     
>>>> In other words we are talking about new values that the user adds, he
>>>> just wants to be able to see them after he adds them.
>>>> For this to work, the only things that need to be done is to add user as
>>>> a ValueMode option and to have it save the value on LostFocus when the
>>>> ValueMode is user.
>>>>         
>>> Yes you would otherwise be using a textbox for free-form textual entry,
>>> so you want to populate the Choices with ["A", "B", "C"] but allow *any*
>>> textual entry.
>>>       
>>      Which is what dComboBox does right now.
>>
>>     
>>> I agree
>>> that Dabo's dComboBox should support such usage out of the box, without
>>> raising 'string must be present in the choices'.
>>>       
>>      I disagree. List controls simply do not work that way, and trying to 
>> munge
>> the data binding code to accommodate a use case that is better served by
>> alternative approaches is a bad idea.
>>
>>      Here's another approach: make a composite control with a dTextBox and a
>> dBitmapButton. The text box is bound to the column, and the button (with a
>> down triangle image, as in a combo box) brings up a context menu with the
>> A,B,C options. If a user selects one of the options, it populates the
>> textbox and the column.
>>
>>      So rather than mess with the data binding concept and design, build a
>> custom control with the behavior that is needed.
>>
>>
>> -- Ed Leafe
>>
>>     
> +1 I agree with Ed. And it does not take a lot of code get Ed's solution 
> working and the technique should also work in ClassDesigner.  However, I do 
> believe that the naming of the control is an issue. Dabo's "dComboBox " isn't 
> what I'd call a combobox (at least from a VFP point of view).   However, Dabo 
> is just following the lead of wxPython (and I guess wxPython is following the 
> lead of wx) in naming the control.  I believe following the wxPython naming 
> conventions is a good thing.
>
> Bottom line it is the wx.ListCtrl class that is giving Dabo fits.  On one 
> hand 
> we would like a popup/dropdown list to contain only vaild choices.  On the 
> other hand we want to have some way to deal with dynamic entries.  
>
> Therefore, I offer a $25.00 bounty to anyone that comes up with a good 
> solution (good to be determined by Ed and Paul).  It should allow a fixed 
> list and still be bound to a data field with dynamic text allowed.  The data 
> should not raise an exception if not in the list.  And should work 
> transparently with Dabo's data schema.  In other words just turning off the 
> exception is not a good solution.
> Johnf
>   
My solution is to use the dComboBox and add a new ValueMode called user,
which uses the UserValue that is already part of the class. The only new
functionality this enters is to save to and read from the database while
in ValueMode=="user".

I extended the dComboBox class, but this could just as easily be put in
the dComboBox. The only other thing I did here was setup the GotFocus
and LostFocus events so that if the data changes and the user clicks off
instead of hitting Enter, it will save it as well.

Here is my class, works like a charm:
import dabo, dabo.ui
from dabo.dLocalize import _
import dabo.dEvents as dEvents
from dabo.ui import makeDynamicProperty
from dabo.dEvents import Hit
import wx


class dComboBox2(dabo.ui.dComboBox):
    def __init__(self, parent, properties=None, attProperties=None,
*args, **kwargs):
        dabo.ui.dComboBox.__init__(self, parent,  *args, **kwargs)
        self.changed=False
        self.startValue=None

    def _initEvents(self):
        super(dComboBox2, self)._initEvents()
        self.bindEvent(dEvents.LostFocus, self.onLostFocus)
        self.bindEvent(dEvents.GotFocus, self.onGotFocus)

    def onGotFocus(self,evt):
        self.startValue=self.Value
       
    def onLostFocus(self,evt):
        if self.Value<>self.startValue and self.ValueMode=="user":
            myevt=wx.CommandEvent(wx.wxEVT_COMMAND_TEXT_ENTER,self.GetId())
            wx.PostEvent(self,myevt)

    def _getValueMode(self):
        try:
            vm = {"p": "position", "s": "string", "k": "key", "u":
"user"}[self._valueMode]
        except AttributeError:   
            vm = self._valueMode = "string"
        return vm
       
       
    def _setValueMode(self, val):
        val = str(val).lower()[0]
        if val in ("p", "s", "k","u"):
            self._valueMode = val

    def _getValue(self):
    #    print "getvalue"
        if self.ValueMode == "position":
            ret = self.PositionValue
        elif self.ValueMode == "key":
            ret = self.KeyValue
        elif self.ValueMode =="user":
            ret=self.UserValue
            if ret=="":
                ret=None
        else:
            ret = self.StringValue
        return ret
       
       
    def _setValue(self, value):
    #    print "value=%s"%value
        if not value:
            value=""
        if self.ValueMode == "position":
            self.PositionValue = value
        elif self.ValueMode == "key":
            self.KeyValue = value
        elif self.ValueMode == "user":
            self._userVal = True
            self.UserValue = value
        else:
            self.StringValue = value

    Value = property(_getValue, _setValue, None,
            _("""Specifies which item is currently selected in the list.
            -> Type can vary. Read-write at runtime.
            Value refers to one of the following, depending on the
setting of ValueMode:
                + ValueMode="Position" : the index of the selected
item(s) (integer)
                + ValueMode="String"   : the displayed string of the
selected item(s) (string)
                + ValueMode="Key"      : the key of the selected item(s)
(can vary)""") )

    ValueMode = property(_getValueMode, _setValueMode, None,
            _("""Specifies the information that the Value property
refers to.
            -> String. Read-write at runtime.
            'Position' : Value refers to the position in the choices
(integer).
            'String'   : Value refers to the displayed string for the
selection (default) (string).
            'Key'      : Value refers to a separate key, set using the
Keys property (can vary).""") )

    DynamicValue = makeDynamicProperty(Value)
    DynamicValueMode = makeDynamicProperty(ValueMode)

_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-users
Searchable Archives: http://leafe.com/archives/search/dabo-users
This message: http://leafe.com/archives/byMID/[email protected]

Reply via email to