Forcing a refresh on a bound control

  • Hi all,

    In my core data app I have an entity which I chose to derive from a
    NSManagedObject class because I wanted to do some formatting and data
    manipulation on one of the attributes which I have bound to a
    NSTextView. The formatting is conditional based on a chechbox on the
    UI (in the preferences panel).

    What I need to do is get the NSTextView to know to reload the
    attribute from my managed object when the checkbox changes. in other
    words, it must know to refresh the data in Attribute X even though the
    data in Attribute X hasn't changed.

    I've searched for some attribute of the NSTextView which I can bind to
    the user defaults (the checkbox updates the user defaults) but no
    luck. I can't find any examples anywhere to help me out either.

    Can anyone point me to some documentation I may have missed?

    Thanks!
  • You can force a KVO notification by sending a will/didChangeValueForKey:
    pair of messages.

    Christiaan

    On Thu, May 15, 2008 at 11:10 PM, Trent Jacobs <trent...> wrote:

    > Hi all,
    >
    > In my core data app I have an entity which I chose to derive from a
    > NSManagedObject class because I wanted to do some formatting and data
    > manipulation on one of the attributes which I have bound to a NSTextView.
    > The formatting is conditional based on a chechbox on the UI (in the
    > preferences panel).
    >
    > What I need to do is get the NSTextView to know to reload the attribute
    > from my managed object when the checkbox changes. in other words, it must
    > know to refresh the data in Attribute X even though the data in Attribute X
    > hasn't changed.
    >
    > I've searched for some attribute of the NSTextView which I can bind to the
    > user defaults (the checkbox updates the user defaults) but no luck. I can't
    > find any examples anywhere to help me out either.
    >
    > Can anyone point me to some documentation I may have missed?
    >
    > Thanks!
    > _______________________________________________
    > MacOSX-dev mailing list
    > <MacOSX-dev...>
    > http://www.omnigroup.com/mailman/listinfo/macosx-dev
    >
  • On May 15, 2008, at 2:35 PM, Christiaan Hofman wrote:

    > You can force a KVO notification by sending a will/
    > didChangeValueForKey:
    > pair of messages.
    >
    As has been said on numerous occasions, no, don't do this.

    On May 15, 2008, at 2:10 PM, Trent Jacobs wrote:

    > In my core data app I have an entity which I chose to derive from a
    > NSManagedObject class because I wanted to do some formatting and
    > data manipulation on one of the attributes which I have bound to a
    > NSTextView. The formatting is conditional based on a chechbox on the
    > UI (in the preferences panel).
    >
    It's not clear why the formatting should be part of the behaviour of
    the managed object class.  It would seem more appropriate to move the
    formatting logic to another object which then either has a reference
    to the checkbox or observes a value that the checkbox modifies.

    mmalc
  • On 18 May 2008, at 8:18 AM, mmalc Crawford wrote:

    >
    > On May 15, 2008, at 2:35 PM, Christiaan Hofman wrote:
    >
    >> You can force a KVO notification by sending a will/
    >> didChangeValueForKey:
    >> pair of messages.
    >>
    > As has been said on numerous occasions, no, don't do this.
    >

    I know it has been said. But I have never heard an alternative to
    forcing a KVO change notification. Given that dependent keys can only
    be set for the same object... And if you would think there may be an
    alternative in this particular situation (though I don't see it), I am
    talking about the general situation. Please proof me wrong, but I
    couldn't find it.

    Christiaan

    >
    > On May 15, 2008, at 2:10 PM, Trent Jacobs wrote:
    >
    >> In my core data app I have an entity which I chose to derive from a
    >> NSManagedObject class because I wanted to do some formatting and
    >> data manipulation on one of the attributes which I have bound to a
    >> NSTextView. The formatting is conditional based on a chechbox on
    >> the UI (in the preferences panel).
    >>
    > It's not clear why the formatting should be part of the behaviour of
    > the managed object class.  It would seem more appropriate to move
    > the formatting logic to another object which then either has a
    > reference to the checkbox or observes a value that the checkbox
    > modifies.
    >
    > mmalc
    >
    > _______________________________________________
    > MacOSX-dev mailing list
    > <MacOSX-dev...>
    > http://www.omnigroup.com/mailman/listinfo/macosx-dev
  • On Sun, May 18, 2008 at 3:20 AM, Christiaan Hofman <cmhofman...> wrote:
    >
    > On 18 May 2008, at 8:18 AM, mmalc Crawford wrote:
    >
    >>
    >> On May 15, 2008, at 2:35 PM, Christiaan Hofman wrote:
    >>
    >>> You can force a KVO notification by sending a will/didChangeValueForKey:
    >>> pair of messages.
    >>>
    >> As has been said on numerous occasions, no, don't do this.
    >>
    >
    > I know it has been said. But I have never heard an alternative to forcing a
    > KVO change notification.

    IME, needing to "force" KVO notifications is a sign that my design is
    deficient.

    > Given that dependent keys can only be set for the
    > same object...

    FYI, while true for 10.4, this is no longer the case with 10.5. Check
    out the +keyPathsForValuesAffectingValueForKey: method (and pay close
    attention to the fact that the returned set contains key *paths* not
    just keys).

    <http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Protoco
    ls/NSKeyValueObserving_Protocol/Reference/Reference.html
    >

    > And if you would think there may be an alternative in this
    > particular situation (though I don't see it), I am talking about the general
    > situation. Please proof me wrong, but I couldn't find it.

    One can use KVO directly. As Malcom mentioned, one can have an object
    observe whatever value the check box is bound to, and then, when a
    change is registered, that object can set/change the appropriate value
    in the model that is backing the text view.

    --
    Clark S. Cox III
    <clarkcox3...>
  • On 18 May 2008, at 12:34 PM, Clark Cox wrote:

    > On Sun, May 18, 2008 at 3:20 AM, Christiaan Hofman
    > <cmhofman...> wrote:
    >>
    >> On 18 May 2008, at 8:18 AM, mmalc Crawford wrote:
    >>
    >>>
    >>> On May 15, 2008, at 2:35 PM, Christiaan Hofman wrote:
    >>>
    >>>> You can force a KVO notification by sending a will/
    >>>> didChangeValueForKey:
    >>>> pair of messages.
    >>>>
    >>> As has been said on numerous occasions, no, don't do this.
    >>>
    >>
    >> I know it has been said. But I have never heard an alternative to
    >> forcing a
    >> KVO change notification.
    >
    > IME, needing to "force" KVO notifications is a sign that my design is
    > deficient.
    >

    That may be in some cases. But I have run into several situation where
    I could not change the design. E.g. when changes happen in code I
    don't control. Or when you want to force an update after a
    notification (in the sense of NSNotification) that is not necessarily
    associated to a change of an KVO observable property.

    >> Given that dependent keys can only be set for the
    >> same object...
    >
    > FYI, while true for 10.4, this is no longer the case with 10.5. Check
    > out the +keyPathsForValuesAffectingValueForKey: method (and pay close
    > attention to the fact that the returned set contains key *paths* not
    > just keys).
    >
    > <http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Protoco
    ls/NSKeyValueObserving_Protocol/Reference/Reference.html
    > >
    >

    Which is of course irrelevant if you're developing a Tiger compatible
    app (as I'm doing).

    Christiaan

    >> And if you would think there may be an alternative in this
    >> particular situation (though I don't see it), I am talking about
    >> the general
    >> situation. Please proof me wrong, but I couldn't find it.
    >
    > One can use KVO directly. As Malcom mentioned, one can have an object
    > observe whatever value the check box is bound to, and then, when a
    > change is registered, that object can set/change the appropriate value
    > in the model that is backing the text view.
    >
    > --
    > Clark S. Cox III
    > <clarkcox3...>
  • On May 18, 2008, at 3:20 AM, Christiaan Hofman wrote:

    > I know it has been said. But I have never heard an alternative to
    > forcing a KVO change notification. Given that dependent keys can
    > only be set for the same object... And if you would think there may
    > be an alternative in this particular situation (though I don't see
    > it), I am talking about the general situation. Please proof me
    > wrong, but I couldn't find it.
    >
    This is simply asinine.
    There's nothing to prove wrong.  As Clark suggested, the solution is
    to get the design right.

    mmalc
  • On 18 May 2008, at 4:25 PM, mmalc Crawford wrote:

    >
    > On May 18, 2008, at 3:20 AM, Christiaan Hofman wrote:
    >
    >> I know it has been said. But I have never heard an alternative to
    >> forcing a KVO change notification. Given that dependent keys can
    >> only be set for the same object... And if you would think there may
    >> be an alternative in this particular situation (though I don't see
    >> it), I am talking about the general situation. Please proof me
    >> wrong, but I couldn't find it.
    >>
    > This is simply asinine.
    > There's nothing to prove wrong.  As Clark suggested, the solution is
    > to get the design right.
    >
    > mmalc
    >

    Unless there is no way to get the design right. Perhaps in this
    particular case there is, but in some cases there isn't. In some cases
    there isn't. Two cases I know of are when you have dependent keys in
    different objects in a Tiger compatible app, and dependent keys where
    no KVO notification is send, only an NSNotification. In my apps I have
    both situations. If you can give a way to avoid this, I would be happy
    to hear it, but I don't know of one.

    Christiaan
  • On May 18, 2008, at 7:44 AM, Christiaan Hofman wrote:

    > Unless there is no way to get the design right.
    >
    If there is no way to achieve what you want directly with KVO/
    bindings, then the answer is not to use KVO/bindings, not to advocate
    a "solution" that is known to be wrong.

    > Two cases I know of are when you have dependent keys in different
    > objects in a Tiger compatible app, and dependent keys where no KVO
    > notification is send, only an NSNotification. In my apps I have both
    > situations. If you can give a way to avoid this, I would be happy to
    > hear it, but I don't know of one.
    >
    <http://developer.apple.com/documentation/Cocoa/Conceptual/CoreData/Articles
    /cdFAQ.html#//apple_ref/doc/uid/TP40001802-SW3
    >

    mmalc
  • On May 15, 2008, at 2:10 PM, Trent Jacobs wrote:

    > What I need to do is get the NSTextView to know to reload the
    > attribute from my managed object when the checkbox changes. in other
    > words, it must know to refresh the data in Attribute X even though
    > the data in Attribute X hasn't changed.

    The common solution to this is to bind the checkbox to the controller
    with a key like "shouldDisplayAsFormatted" and implement these methods
    in the controller:

    - (BOOL)shouldDisplayAsFormatted;
    - (void)setShouldDisplayAsFormatted:(BOOL)newValue;

    Or even better, with Objective-C 2.0 syntax:

    @property BOOL shouldDisplayAsFormatted;

    Inside the "-setShouldDisplayAsFormatted:", method, you use the input
    value to update the display of the NSTextField (which should be an
    IBOutlet).

    This is not the only way to do it, but I think it's the easiest and
    cleanest way to do what you want. You probably don't want to bind the
    checkbox to the Managed Object itself because the checkbox affects a
    view on the data, not the data itself.

    Hope that helps,

          - Scott
  • On 17 May 2008, at 23:18, mmalc Crawford wrote:

    >> You can force a KVO notification by sending a will/
    >> didChangeValueForKey:
    >> pair of messages.
    >>
    > As has been said on numerous occasions, no, don't do this.

    Having missed all the occasions, why not?

    I've got a key which is calculated (it's the number of topics which
    are filtered by a search string). As the user types into a search
    field, I need to update this derived value. How else can I let KVO
    know the calculated value has changed, so it can be displayed in the UI?

    (BTW, I'm not using Core Data, and need to work on 10.4.)

    David Dunham
    Voice/Fax: 206 783 7404            http://www.pensee.com/dunham/
    Imagination is more important than knowledge. -- Albert Einstein
  • On May 18, 2008, at 8:04 PM, David Dunham wrote:

    > I've got a key which is calculated (it's the number of topics which
    > are filtered by a search string). As the user types into a search
    > field, I need to update this derived value. How else can I let KVO
    > know the calculated value has changed, so it can be displayed in the
    > UI?

    In general, you can just set derived keys to be dependent on the
    "real" key, and the change notifications happen automatically. On
    Tiger, you use +setKeys:triggerChangeNotificationsForDependentKey: in
    +initialize.

    Are you able to use this?

          - Scott
  • Thanks, I'll give that a try and post here if I'm successful or not.

    Cheers.

    Scott Stevenson wrote:
    >
    > On May 15, 2008, at 2:10 PM, Trent Jacobs wrote:
    >
    >> What I need to do is get the NSTextView to know to reload the
    >> attribute from my managed object when the checkbox changes. in other
    >> words, it must know to refresh the data in Attribute X even though
    >> the data in Attribute X hasn't changed.
    >
    > The common solution to this is to bind the checkbox to the controller
    > with a key like "shouldDisplayAsFormatted" and implement these methods
    > in the controller:
    >
    > - (BOOL)shouldDisplayAsFormatted;
    > - (void)setShouldDisplayAsFormatted:(BOOL)newValue;
    >
    > Or even better, with Objective-C 2.0 syntax:
    >
    > @property BOOL shouldDisplayAsFormatted;
    >
    > Inside the "-setShouldDisplayAsFormatted:", method, you use the input
    > value to update the display of the NSTextField (which should be an
    > IBOutlet).
    >
    > This is not the only way to do it, but I think it's the easiest and
    > cleanest way to do what you want. You probably don't want to bind the
    > checkbox to the Managed Object itself because the checkbox affects a
    > view on the data, not the data itself.
    >
    >
    > Hope that helps,
    >
    > - Scott
    > _______________________________________________
    > MacOSX-dev mailing list
    > <MacOSX-dev...>
    > http://www.omnigroup.com/mailman/listinfo/macosx-dev
  • On 18 May 2008, at 23:42, Scott Stevenson wrote:

    >> I've got a key which is calculated (it's the number of topics
    >> which are filtered by a search string). As the user types into a
    >> search field, I need to update this derived value. How else can I
    >> let KVO know the calculated value has changed, so it can be
    >> displayed in the UI?
    >
    > In general, you can just set derived keys to be dependent on the
    > "real" key, and the change notifications happen automatically. On
    > Tiger, you use +setKeys:triggerChangeNotificationsForDependentKey:
    > in +initialize.
    >
    > Are you able to use this?

    There is no other key -- it's a value calculated by applying a test
    to all topics and counting the number of YESes.

    David Dunham    A Sharp, LLC
    Voice/Fax: 206 783 7404    http://a-sharp.com
    Efficiency is intelligent laziness.
  • On Mon, May 19, 2008 at 5:01 PM, David Dunham <dunham...> wrote:

    > There is no other key -- it's a value calculated by applying a test to all
    > topics and counting the number of YESes.

    The sum total is dependent on the filtered collection of topics, which
    in turn is dependent on the value of the search field.

    Hamish
  • On 19 May 2008, at 6:01 PM, David Dunham wrote:

    >
    > On 18 May 2008, at 23:42, Scott Stevenson wrote:
    >
    >>> I've got a key which is calculated (it's the number of topics
    >>> which are filtered by a search string). As the user types into a
    >>> search field, I need to update this derived value. How else can I
    >>> let KVO know the calculated value has changed, so it can be
    >>> displayed in the UI?
    >>
    >> In general, you can just set derived keys to be dependent on the
    >> "real" key, and the change notifications happen automatically. On
    >> Tiger, you use +setKeys:triggerChangeNotificationsForDependentKey:
    >> in +initialize.
    >>
    >> Are you able to use this?
    >
    >
    > There is no other key -- it's a value calculated by applying a test
    > to all topics and counting the number of YESes.
    >
    > David Dunham    A Sharp, LLC
    > Voice/Fax: 206 783 7404    http://a-sharp.com
    > Efficiency is intelligent laziness.

    Basically what mmalc is saying (as I understand it) is to /add/ a
    property for this derived key, and when the "real" keys update (i.e.
    from observeValue:...) you set the derived property using KVC
    compliant methods, so the change is noted. It's rather a hassle and
    needs extra ivars.

    Christiaan
  • On Tue, May 20, 2008 at 12:16 AM, Christiaan Hofman <cmhofman...> wrote:

    > Basically what mmalc is saying (as I understand it) is to /add/ a property
    > for this derived key, and when the "real" keys update (i.e. from
    > observeValue:...) you set the derived property using KVC compliant methods,
    > so the change is noted. It's rather a hassle and needs extra ivars.

    No need for extra ivars -- the sum total is a dynamic read-only
    property, dependent on the filtered collection of topics. If the
    dependency is set up using KVO, anything observing the sum total (e.g.
    a text view in the user interface) will be notified that it has
    changed when the filtered collection is changed. Likewise, the
    filtered collection is a read-only property dependent on the value of
    the search field, so typing in the search field will indirectly cause
    a notification that the sum total has changed.

    Hamish
  • On 19 May 2008, at 16:14, Hamish Allan wrote:

    > On Mon, May 19, 2008 at 5:01 PM, David Dunham <dunham...> wrote:
    >
    >> There is no other key -- it's a value calculated by applying a
    >> test to all
    >> topics and counting the number of YESes.
    >
    > The sum total is dependent on the filtered collection of topics, which
    > in turn is dependent on the value of the search field.

    Seems really backwards to bind my data model to a toolbar item that
    may or may not be present.

    There's also a related property: the total number of topics. This
    needs to be updated from time to time, and also doesn't seem
    dependent on any other property.

    David Dunham
    Voice/Fax: 206 783 7404            http://www.pensee.com/dunham/
    Imagination is more important than knowledge. -- Albert Einstein
  • On Tue, May 20, 2008 at 5:21 PM, David Dunham <dunham...> wrote:

    > On 19 May 2008, at 16:14, Hamish Allan wrote:
    >
    >> The sum total is dependent on the filtered collection of topics, which
    >> in turn is dependent on the value of the search field.
    >
    > Seems really backwards to bind my data model to a toolbar item that may or
    > may not be present.

    The sum total should not be part of your data model, given that it
    depends on something in the view.

    > There's also a related property: the total number of topics. This needs to
    > be updated from time to time, and also doesn't seem dependent on any other
    > property.

    Is it not dependent on the unfiltered collection of topics?

    Hamish
previous month may 2008 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Go to today