I've got a textfield with number formatter which is bound to a variable with Cocoa bindings.
There's also a stepper which I've bound to the same variable to increment the value, I've used an NSLog to test and it works great.
My problem is: Whenever I type a number into the box the variable isn't updated unless i hit enter. How does NSTextBox know when the user is finished entering? Is there a way to dynamically update the variable after every digit entered?
Many thanks
Rich
First, are you sure you want it to update immediately? One of the user's keystrokes could be an invalid character (ie, not a number). An NSNumberFormatter can help but I believe you still have to "commit" the entry before it will validate it as a proper number entry.
Second, you could always implement the -textDidChange: NSTextDelegate method. Again, same problem as above, though. Invalid input could trigger. To work around this, you could try creating an NSNumber from the string input and if you don't get an NSNumber, don't bother reacting until you do (and if the field loses focus with invalid input, change it back to its last valid value) but then you're duplicating the "validate on commit" NSNumberFormatter behavior you get for free.
Switching on the "Continuous" property for the control in Interface Builder should make the field fire its binding as the value is changed.
Related
I am very new to LabVIEW and what I want is to know if it's possible to modify an indicator. I have a loop, and in every iteration I want to add a new value (given by the user via a control) to that string indicator, and to display it? I tried many ways, but since it is an output none of them worked. Is it possible to do that? Thank you.
I have also tried using a feedback node, but I think this somehow gives me an infinite loop.
In LabVIEW, an indicators state will be updated every time that it receives a new value.
By far the easiest way to do this is to simply run a data-flow wire into an indicator terminal.
Beyond that you have local variables, and property nodes which add additional concerns.
In your case it looks more to be an issue with the logic associated with your display update than with your actual updating of the value.
(Additionally, why are you using a string display to indicate a numeric value? Using a numeric suddenly simplifies all of your logic.)
To keep a running total - or similar value - in a loop, use a shift register.
This is just a minimal example in which the loop repeats every second until you click the stop button, but you can adapt it to how you want the control flow to work.
How to copy value from numeric indicator to Numeric control in Laview program? That is Numerical Control should use the value that is displayed in the indicator.
The easiest way is to use local variables. Right click on the indicator, create -> local variable.
Then you can change the local indicator to control and wire it to control' local variable.
There are several ways to do such thing:
The easiest way (if you need value from indicator, as an input value to another block - simply put together wire with block input.
If it has to be control itself, then use local variables as #KhachikSahakyan said. What's more after creating local variables you can change it behaviour from read to write by right mouse click.
You can also use shift registers to pass data in some cases.
If such explanation does not solve your problem please provide more info, such as screenshot with fragment of your code.
Having a bit of a problem doing this and not sure of it can be done. I have an edit control that a user types into, I would like for the input to be all in capital letters. I tried having a custom action on the edit control to get the property, convert to capital letters and set the property again each time a letter is set but it does not work. I guessed it wouldn't but no harm in trying..:)
Has anyone else solved this? I would like to do it without having a button to press if possible. The dialog in question is a twin dialog if that helps at all.
Thanks for your help
It's not possible using the native built-in Windows Installer UI. The underlying MaskedEdit Control is primitive. There are no events to tie into to validate and modify as the characters are entered. You can only ToUpper() the property when the user clicks Back or Next.
The alternative would be to go with an external UI handler which is a lot of learning and work.
I have a modal dialog thats building a string. The string is shown to the user, and the user presses checkboxes, radio boxes, etc to build the string. The string exists nowhere - I build it for display in -()builtString; from the configuration of the self.valuesDict.
I can easily wire up the checkboxes via bindings in IB: for example to the files owner (the controller) with self.valuesDict.checkbox1
Also I bound the display of the string to "self.builtString".
But every time any checkbox changes, I want to redisplay the string that's shown to the user.
If I abandon bindings, then I think I can use the [self willChangeValueForKey:#"builtString"], for each checkbox, etc, I think, but that is some messy looking code by the time I deal with them all.
So how do you tell a nstextfield in IB to update every time say self.valuesDict changes?
Thanks for any comments/suggestions.
--Tom
You can specify dependencies between bindings. Just write a class method +(NSSet*) keyPathsForValuesAffectingBuiltString that returns a set with all key paths of properties builtString depends on. Then things bound to your string will also be updated when one of the other properties is changed. For more details and step-by-step instructions you can look at this article.
I have several NSComboBoxes created in Interface Builder, and one created programmatically.
The NSComboBoxes created in Interface Builder are perfect. I have their Value bound to the Shared User Default Controller, and when their view is opened they are sitting there with the correct value. Importantly, this value is shown as "normal" text in the NSComboBox. In other words, the value doesn't appear selected. This is what I want.
For the NSComboBox that is created programmatically, I set the value using selectItemAtIndex:0. When I do this, the correct item is selected--but the text appears selected. I.e., it is highlighted and everything. I don't want this. Here are the workarounds I've attempted:
(i) Get the field editor and set insertion point to the end of the text. This doesn't work although, oddly, the field editor's string is either nil or empty when doing this. I'm not sure if this is correct behavior for the field editor.
(ii) Trying various other ways of setting the combo box's value, such as setObjectValue, takeStringValueFrom, etc.
(iii) Finally, and most frustratingly, I tried to set the value of the NSComboBox using [myComboBox setValue:#"The Default Item" forKey:#"value"]; This fails with objc_exception_throw, presumably because there is no such KVC key. But I know that the value of the combo box can be set by KVO, because it works in interface builder! I'm guessing that I don't know the correct key path. I tried to enumerate all the properties using introspection, but I can't get the code working right (objc_property_t isn't in the expected headers).
So, I have two questions:
First, does anyone know how to set a default value for NSComboBox programmatically, so that the text in the box isn't selected? I will go to any lengths to do this, including a new NSComboBoxCell subclass, if it comes to that.
Second, can somebody tell me what key or key path IB is using to set the value of an NSComboBox? Or alternatively, why my efforts to do this are failing?
I've been working on this for many hours now and I am truly disspirited!
THANK YOU, mustISignUp! So nice to have this fixed. A little bit of followup:
(i) Selection of the text is definitely caused by focus. Calling setRefusesFirstResponder:YES fixes the problem. Unfortunately, the window really wants to focus on this combo box, as setting refusesFirstResponder back to NO (later, after window inititation) causes text selection again (I do want the user to be able to focus on this box if he desires). Therefore, in my case, the definitive solution was to call [window makeFirstResponder:otherControl]. Oddly, though [window makeFirstResponder:nil] doesn't work. Any ideas why?
(ii) Thanks for pointing out the difference between bindings and properties. I learned a lot while looking into this question. For one, I learned that you can get a list of bindings by calling - (NSArray *)exposedBindings, which for NSComboBox returns (fontSize, alignment, toolTip, fontName, enabled, contentValues, fontFamilyName, font, hidden, fontItalic, textColor, value, content, editable, fontBold). Second, I was able to set the value using [myComboBox bind:#"value" toObject:[NSMutableString stringWithString:#"defaultValue"] withKeyPath:#"string" options:nil], where NSMutableString has a category on it that turns "string" into a property. Finally, this actually doesn't fix the text selection "problem". The difference between text selection with this combo box and those in Interface Builder must be their position in the window...I guess that this combo box is just slated to become initialFirstResponder while the others weren't.
So my only remaining question might be why [window makeFirstResponder:nil] doesn't work to take focus off the combo box. Not super-important, but I'd be curious if anybody has an idea.
Firstly, i think the text is selected because calling selectItemAtIndex: has made the comboBox the firstResponder. You could use setRefusesFirstResponder:YES or you could make another item the first responder to make the text not appear selected.
If i have understood correctly and you want to change the selection of the comboBox you are doing it the right way.
Secondly, you are confusing Bindings and KVC. NSComboBox has a binding called 'value', not a property called 'value'. It is meaningless to try to set it with setValue:forKey:, and Interface Builder definitely isn't doing this.
You would be right in thinking this is un-obvious and confusing and maybe better names could have been chosen for the bindings.