问题
I have an application which allows for multiple NSDocuments to be open. In this application is a single utility window that contains some functionality that I want to apply to the frontmost document.
I am trying to use bindings here, so the trick is how to cleanly bind the user interface of the utility window to the frontmost document. The goal is that then switching the frontmost document window will update the view in the utility window; controls that are bound to properties of the frontmost document's model would be updated appropriately when state changes in the document's model, etc.
For sending actions from such a window, it's easy to just use first responder; the document object can intercept actions via the responder chain. But I want more than this, and of course you can't bind to the first responder.
A few ideas that I have:
- put an object controller in my nib for the shared window. When a document window changes frontmost status, change the content of that binding. A disadvantage of this is that if I were to have another kind of utility window, I'd have to remember to hook up the bindings from the document window to that utility window too!
- Make an accessor in the application delegate that gets the frontmost document window by traversing the window list. My utility window would just bind through the application delegate's method. A disadvantage here is that it's not KVO compliant
- Have a getter and setter in the application delegate to determine (and perhaps set to be KVO-compliant? would that make sense?) the frontmost document. Perhaps use window notifications set an ivar to the appropriate value when a window loses main status. Update: I'm using this for now, and it actually seems pretty clean. I set the value from the windowDidBecomeMain notification of my doc window and clear it (if it's the current value) in windowWillClose. Unless there is any major objection, this is probably the approach I'll use.
- One idea was to bind to mainWindow.windowController.document ... this comes close, except that when my shared window becomes main, then this binding goes away. So really I need to find the frontmost document window's controller (and of the right class).
None of these seem quite right. Is there a better way to do this that I'm missing?
回答1:
I’ve always bound through Shared Application, mainWindow.document
, which works fine. if you have windows w/o documents, you may want to add a mainYourKindOfWindow
key that is implemented by watching mainWindow
and updating the value based on some filter criteria.
回答2:
Leopard's TextEdit does this for its inspector. Check it out in file:///Developer/Examples/AppKit/TextEdit.
回答3:
- put an object controller in my nib for the shared window. When a document window changes frontmost status, change the content of that binding.
That makes the most sense to me. You'd change the content to the document instance ([NSDocumentController currentDocument]
).
A disadvantage of this is that if I were to have another kind of utility window, I'd have to remember to hook up the bindings from the document window to that utility window too!
Huh? I don't understand this.
回答4:
Leopard's TextEdit does this for its inspector. Check it out in >file:///Developer/Examples/AppKit/TextEdit.
In TextEdit, inspector values are bound via an intermediate object controller. The controller content object is bound to the shared application mainWindow.
You may bind the content to mainWindow.firstResponder and uncheck "Raises for not applicable keys".
回答5:
Use the key window, not the main window. KVO might not be supported for NSApplication's keyWindow property, but you can still use NSNotifications if it doesn't work. The reason for this is that NSDocumentController's currentDocument uses the keyWindow, so it better represents the built in functionality. Also, panels can be set to avoid becoming key window.
来源:https://stackoverflow.com/questions/223966/whats-a-good-way-to-bind-from-a-shared-utility-window-and-the-frontmost-documen