CSLA 1.52 issue implementing binding? Or bad design strategy?

CSLA 1.52 issue implementing binding? Or bad design strategy?

Old forum URL: forums.lhotka.net/forums/t/2469.aspx


Q Johnson posted on Friday, March 02, 2007

CSLA 1.52 - VS2003 - VB.NET - Binding question, I think.

I'm building a private vehicle registration system. 

What I'm trying to do

I want to show the user a list of items in list-type controls (presently using DevExpress LookUpEdit) as an aid in populating a related field on my form bound to a CSLA Editable Root Object (vehicle).  The values in the lists are simply the result of a query against the Vehicle table for all values ever entered in the related field (Select Distinct blah, blah).  I use ReadOnly Collection objects to hold these lists.  This is for things like Make, Model, Year, BodyType, etc.

I expected to be able to let the user either pick a value from the list or enter a new value.  I put code in my U.I. to re-Get the ROCs after the ERO is Saved, so that they will include a new value if one was offered.

What happens instead

But I'm finding that the control won't allow the new value typed in by the user to remain in the textbox of the LookUpEdit control.  It changes it to the next closest value in the list.

The control fires an event (ProcessNewValue) when the user does this and, had I used an Editable Root Collection object, I could use code in that event to simply add the item to the list. 

It looks to me like I have three options to get this to work:

1) Fix the binding technique(s) I'm using on the form if they're amiss somehow and causing the problem.  (I show them below.)

2) Change my list's collection object from a ROC to an ERC and use the control's event to add a new item to the list.  (I.E., add it to the collection, but not make any attempt to persist it since there's no supporting table.  I would still re-popluate the list after saving the form's Main ERO.  This ERC wouldn't need implementation of DP_Update.)

3) Drop the strategy of populating from that Distinct query altogether and, instead, create tables to hold allowable values.  Then I have a couple of options.  (a) I can provide a different screen on which they can add items and just prohibit the use of items not in the list on my ERO's screen. (b) Use the control's Validated event to Save new values whenever they are entered.

My preferences for these are in the order I offered them (I really don't care for that last one at all, actually).  But I'm also open to other suggestions.

Binding in the form presently:

At startup, the ROC is instantiated with typical ROC.GetROC() call and then bound to the control with code like this:
         With cboMakeList
            .Properties.DataSource = moMakeList
            .Properties.Columns.Clear()
            col = New DevExpress.XtraEditors.Controls.LookUpColumnInfo
            col.FieldName = "Make"
            .Properties.Columns.Add(col)
            .Properties.ValueMember = "Make"
            .Properties.DisplayMember = "Make"
            .Properties.BestFit()
            .Properties.PopupWidth = 150
            .Properties.AutoSearchColumnIndex = 1
         End With

And the related field in the Vehicle object is bound with a call in the CSLA 1.x standard technique:

 BindField(cboMakeList, "EditValue", moVehicle, "Make")

It seems to be a simple enough piece of functionality.  But I must be botching it up some how.

Thanks in advance.

 


 

Q Johnson replied on Friday, March 09, 2007

Wow, 58 views and no replies.  Oh well. 

I got some help from the DevExpress forum and found out how to handle that ProcessNewValue event better.  I simply add the item typed by the user to the list object.  I don't have to save it since I'll read the value next time the form opens if the user saved the vehicle record with the new value for that field.  Of course, that meant that I had to re-create all these ReadOnlyCollection objects as EditableRootCollections with Children.

So, this experience has shown off the flexibility of CSLA even further to me.  I just ran the code generator (I use MyGeneration, but it doesn't have any bearing on the outcome) and made new objects for my five lists (and their children) and substituted their types for my list object declarations in the UI.  Everything that worked before worked now and all I needed to do was handle that ProcessNewValue event with code like:

      If e.DisplayValue.ToString = "" Then
         Exit Sub
      End If
      moModelList.Add()
      moModelList(moModelList.Count - 1).ModelID = e.DisplayValue.ToString
      e.Handled = True

To build the ten new classes (five lists and their child classes) and create the handlers for all five ProcessNewValue events took about an hour. 

And now, should I choose to do so, I can also switch to the table-based list strategy just by modifying the query called in the DP_Fetch event of each List and easily create an update query for implementing the DP_Update routine (for which code has already been created by the code generator but isn't presently called with the current design). 

I hope this was useful for any of you other DevExpress users with similar design goals for a data entry form.

Regards,

Copyright (c) Marimer LLC