[litwindow-users] Re: NotifyChanged not causing update?
Status: Alpha
Brought to you by:
hajokirchhoff
From: Hajo K. <mai...@ha...> - 2005-04-19 08:19:22
|
Hi, > 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. > 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. > 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. > 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. > 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. > 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"); > 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); > 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(). Looks fine to me. But please post some more code. Best regards Hajo |