Discussion:
NotifyChanged not causing update?
yrs90
2005-04-19 06:02:24 UTC
Permalink
I used RapidUI with wxWizard as suggested. It worked great, even
interfacing to the class data through member functions.

Since the UI and data are updated without regard to whether the user cancels
the action, I passed a new instance of the data structure to RapidUI. If the
user "Finish"es the wizard, the data is copied into the real data structure.
I presume that this is the expected usage pattern?

After copying the wizard changes, I called NotifyChanged(g_data). Nothing
happened. Not until I did an insert operation (which also triggers a
NotifyChanged) did the UI update and show the changes introduced by the
wizard.

At first I thought that the NotifyChanged might be interacting with my local
instance of RapidUI, wiz_mediator, instead of m_rapidUI, but none of the
variations I've tried has yielded any updates. I even tried creating an
accessor and using m_rapidUI->ValueChanged(..). (I used recursion=false,
but I even tried naming the particular attribute that changed.) How do I
convince RapidUI to reevaluate the rules?

I also found myself asking these questions: Can NotifyChanged be called on
any sub-element of the data structure? If I call NotifyChanged on some leaf
of data will RapidUI know that a Rule referencing a branch containing the
changed data needs to be reevaluated?

By the way, the rule that I am expecting to update is of the form:
RULE("ID_FRAME.Title", make_const<wxString>("MyProg: ") +
make_expr<wxString>("Name"))

where Name resolves to GetName().

Regards,
Joel




---
[This E-mail scanned for viruses by Declude Virus]



-------------------------------------------------------
This SF.Net email is sponsored by: New Crystal Reports XI.
Version 11 adds new functionality designed to reduce time involved in
creating, integrating, and deploying reporting solutions. Free runtime info,
new features, or free trial, at: http://www.businessobjects.com/devxi/728
Hajo Kirchhoff
2005-04-19 08:18:24 UTC
Permalink
Hi,
Post by yrs90
I used RapidUI with wxWizard as suggested. It worked great, even
interfacing to the class data through member functions.
I am glad to hear that.
Post by yrs90
Since the UI and data are updated without regard to whether the user cancels
the action, I passed a new instance of the data structure to RapidUI. If the
user "Finish"es the wizard, the data is copied into the real data structure.
I presume that this is the expected usage pattern?
For the moment being, yes.

Later I'll introduce the notion of "commit levels". Commit levels are a
classification of when the relevant rules will be evaluated. For GUI
elements there could be
+ immediate - useful for buttons of all kind including checkboxes etc...
+ focus lost - useful for textcontrols etc...
+ explicit - commit must be triggered explicitly, such as with an
apply/ok button.
Post by yrs90
After copying the wizard changes, I called NotifyChanged(g_data). Nothing
happened. Not until I did an insert operation (which also triggers a
NotifyChanged) did the UI update and show the changes introduced by the
wizard.
Please post some code.

NotifyChanged accepts three parameters.
1. An accessor pointing to the element that has changed.
2. bool recursive - true meaning that a subelement (member, inherited
etc...) has changed, false meaning only the topmost view of the element
will be evaluated. useful for aggregates and containers only.
3. bool immediate - if true, triggers reevaluation immediately, if
false, wait for another call to NotifyChanged with immediate=true

If you've set up everything correctly and have Start()ed the rapidUI
mechanism, then NotifyChanged should update all widgets immediately.
Post by yrs90
At first I thought that the NotifyChanged might be interacting with my local
instance of RapidUI, wiz_mediator, instead of m_rapidUI, but none of the
NotifyChanged sends its events to all RapidUI objects currently
instantiated.
Post by yrs90
variations I've tried has yielded any updates. I even tried creating an
accessor and using m_rapidUI->ValueChanged(..). (I used recursion=false,
but I even tried naming the particular attribute that changed.) How do I
convince RapidUI to reevaluate the rules?
If it does not reevaluate the rules it probably means that you are
passing in an object that does not appear in the rules anywhere. No rule
depends on it. For example, if you pass a local copy of the data to
RapidUI, then call NotifyChanged(g_data) for the gobal instance, nothing
will change.
Post by yrs90
I also found myself asking these questions: Can NotifyChanged be called on
any sub-element of the data structure? If I call NotifyChanged on some leaf
Yes. Either call

NotifyChanged(g_data.this_has_changed);

or use the other version:

NotifyChanged(g_data, "this_has_changed");
Post by yrs90
of data will RapidUI know that a Rule referencing a branch containing the
changed data needs to be reevaluated?
Aahh, now we are coming to the juicy details :)

Suppose you have a data structure:

Top.Middle.Leaf

and these rules:

Rule_1: widget.property = Leaf
Rule_2: widget2.property = Middle

Your question is, if I understand it correctly, if you call
NotifyChanged for leaf, will Rule_2 be reevaluated as well, since if
Leaf has changed, Middle has changed implicitly as well.

This situation can get very complex, especially if you consider side
effects where the value of one leaf is calculated from the value of a
different leaf such as

bool IsEnabled() const { return m_admin_rights && m_logged_in; }

If you have

Data.Enabled
Data.AdminRights
Data.LoggedIn

properties and change LoggedIn, Enabled will change as well.

For now the library ignores these side effects if you call NotifyChanged
for the Leaf only. In such situations you must call NotifyChanged for
the node above the changes and set the 'recursive' parameter to true.

NotifyChanged(Data, true, true);

RapidUI expands this to
NotifyChanged(Data.Enabled, false, false);
NotifyChanged(Data.AdminRights, false, false);
NotifyChanged(Data.LoggedIn, false, false);
NotifyChanged(Data, false, true);
Post by yrs90
RULE("ID_FRAME.Title", make_const<wxString>("MyProg: ") +
make_expr<wxString>("Name"))
where Name resolves to GetName().
Looks fine to me. But please post some more code.

Best regards

Hajo



-------------------------------------------------------
This SF.Net email is sponsored by: New Crystal Reports XI.
Version 11 adds new functionality designed to reduce time involved in
creating, integrating, and deploying reporting solutions. Free runtime info,
new features, or free trial, at: http://www.businessobjects.com/devxi/728
Loading...