> > As best I can tell, it should work. Please try to show me the exact
> > point
> > where I'm wrong.
>
> There are several, presented in-line.
Thanks, Ed. I'm at work now, not home where I have this set up. But I can
respond to some of this now in hopes that by the time I get home I'll have
something I can use.
> >
> > # Code from the wiki How-To (don't know why; it doesn't
> > # seem to serve any purpose, like giving me a form-level
> > # reference to the biz object that I can use, but if
> > # I comment it out, the grid doesn't populate):
> > # Add it to the form's collection of bizobj references
> > self.Form.addBizobj(biz)
>
> You say you don't know why you tell the form about this; the reason
>is that the form acts as the central mediator for all the UI
>controls, and it needs to know the bizobjs it has to deal with.
Thanks.
Please note the following sequence of code, which *works perfectly* despite
the lack of OO righteousness.
> > # Code from the wiki How-To:
> > # These items are correct, as the grid will demonstrate.
> > # Now set up the fields
> > biz.addField("pkid")
> > biz.addField("songname")
> > biz.addField("compdate")
> >
> > # Code from the wiki How-To:
> > # Run the query
> > biz.requery()
> >
> > # Code from the wiki How-To (works perfectly; if I
> > # don't enter a number in the keyBox textbox, all of my
> > # songs appear in the grid. This indicates that:
> > # 1. The MySQL database is configured properly for
> > # Dabo.
> > # 2. The connection is configured properly in Dabo.
> > # 3. I'm referring to the proper fields and DataSource.
> > # 4. There is data in the table.)
> > # The grid may not exist yet; it may be created after
> > # this method is run. So use 'callAfter()' to delay
> > # populating the grid until we know it is ready.
> > dabo.ui.callAfter(self.Form.populateGrid)
>
> Actually, this code was written before I added the 'afterInitAll()'
>method. Were it written today, I would put the code in that method,
>eliminating the need for callAfter(). I've just updated the wiki to
>note this.
Very useful. Thanks.
> > # Now try to show just one song in the thisSong textbox,
> > # assuming the user entered a number in the keyBox. If
> > # s/he didn't, the following code doesn't do anything
> > # that I can see.
> > myPK = self.Form.keyBox.Value
> >
> > # Assuming I put 3 in the keyBox,Prints 3, as I'd expect.
> > print myPK
> >
> > biz.setWhereClause("musSongs.pkid = " + myPK)
> >
> > # Assuming I put 3 in the keyBox, this prints
> > # "musSongs.pkid = 3", also as I'd suspect.
> > # This tells me that the query is going to be correct.
> > print biz._CurrentCursor.sqlManager._whereClause
> >
> > Or, more simply, biz.getWhereClause().
> >
> > biz.requery()
>
> This has to be started at the form level. Dabo uses the Chain of
>Responsibility pattern, and you're bypassing the initial part of the
>chain by jumping directly to the bizobj. The form needs to be in the
>call, because the bizobj might raise an exception which the form is
>designed to catch. The form also causes the value of the active
>control to be flushed to the bizobj, preventing things from being out
>of sync. After the query, it raises events and refreshes the controls
>on the form.
Okay, so:
biz = dabo.biz.dBizobj(conn)
isn't really the right way to go no matter what level in the OO hierarchy
I'm at? Then why does the grid work when I call biz.requery()?
> > # At this point, the grid shows one row--the row I
> > # wanted--but the thisSong texbox shows nothing.
> > dabo.ui.callAfter(self.Form.showSong)
>
> That's because a) the textbox doesn't have a DataSource/DataField
>set, and b) you bypassed the form in the requery call, which would
>have refreshed all controls to the current state of the data.
Believe me, I've tried this too. Everything works for the grid. Nothing I
try works for the textbox.
> > ## *!* ## Dabo Code ID: dForm-top
> > def afterInit(self):
> > # Even though I do this again in the button's onHit,
> > # I do it here because the form will not run if there's
> > # no code in this method.
> > self.Application.addConnectFile("C:\DaboProjects\MyMusic
> > \mymusic.cnxml")
>
> This should only be done once. All it does is register the
>connection definition with the app. It doesn't actually connect.
It makes sense not to do it twice, though the docs say (somewhere) that
doing it twice shouldn't cause a problem. Leaving it in the onHit method
was an oversight.
> > def populateGrid(self):
> > # Just like in the Wiki How-To:
> > self.gridKen.DataSource = "musSongs"
> >
> > def showSong(self):
> > # Just like in the Wiki How-To except it's a dTextBox
> > # instead of a dGrid.
> > self.Form.thisSong.DataSource = "musSongs"
>
> I'm guessing this is probably some vestigial VFP thinking going on
>here. VFP has a single property to bind controls to data:
>ControlSource. In Dabo we've separated this into two logical pieces:
>DataSource and DataField. The reason we only set the DataSource in
>the grid is because the DataField is at the column level; columns in
>a grid share a common DataSource.
Nope, I had no problem with this at all. The problem is that doing it this
way works fine with the grid, but not with the textbox. That's the key
issue all along.
> > Here's the .cdxml file for the form:
>
> This looks fine, but you really should set the data binding props
>for the control in the Designer, and not in code at runtime.
As I noted, my grid works just fine. I have to assume that, because the
grid works *just fine*, that none of the other OO issues above should have
the ability to cause my textbox to NOT work just fine.
I was following the How-To for populating grids, where the grid's
DataSource isn't set until everything else is ready--including after the
biz object is queried. I was trying to do the same with my textbox, but it
didn't work. In the .cdxml I submitted, I forgot to set the DataField. In
a subsequent post, I noted that I'd fixed that and tried it again. It still
didn't work.
The instructions for the grid How-To warn that we can't just set the
DataSource of the grid immediately because that data source may not yet be
ready. So why is that a good thing to do for the textbox?
The question is, why doesn't the textbox behave just like the grid with
regard to data binding?
>
> So step one is to refactor this into a couple of form methods. One
>that does the setup stuff and happens automatically at startup (e.g.,
>creates the bizobj), and one that responds to the click event. Then
>move all of your button code out of the button, and put it where it
>belongs: in the form.
>
I know all this good OO stuff. I don't do VFP the way most people seem to;
I'm already doing n-tier in VFP. I was simply struggling to try to get
something--anything--to work in Dabo. When I prototype in VFP, I put
everthing in one place until I get it working. Then I refactor. I expected
to be able to do that in Dabo also.
In an earlier attempt, I had all the setup stuff in the form's afterInit()
method,--just like in the grid How-To on the wiki. The problem then was, I
couldn't find a way to get an object reference to the biz object from the
onHit method. I didn't know about Form.requery(); the How-To didn't use
it--but it doesn't matter, because doing it that way *still* doesn't work
with the textbox. As I've said, just about any way I configure this, the
grid works fine, but the textbox does not.
In an even earlier attempt, I tried to create a custom biz object class
that had some of this code. In my opinion, virtually none of this stuff
should be in the GUI. The biz object should handle all communication with
the data and make the data available via a standard interface. The GUI,
whatever it is, should be able to pick data off the biz object via that
interface when it needs to display it (and not just by deterministic data
binding) and vice versa, without knowing anything about how the biz object
works. That's how I do stuff in VFP.
I orginally wanted to pull in a data set to the biz object and add standard
methods to access it. But I soon found that trying to set up and access a
custom biz object, let alone trying to parse data out of a list of dicts,
was well beyond my rudimentary understanding of the system, and of Python.
Ultimately, though, that's what I think I should be doing.
So thanks, Ed. I'm having difficulty communicating what the real issue is
here: that the grid works, but the textbox doesn't. Doing the textbox the
"right way" still doesn't work. I've tried it and posted code earlier.
Doing the grid "any old way" works.
Can you please provide some insight on this issue?
Thanks.
Ken
_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-users