Cursor misbehaving in UWP TextBox - c#

Let's say I have a ViewModel with a data type of float and implements INotifyPropertyChanged interface.
private float Amount;
And then in my UI:
<TextBox Text="{x:Bind Amount, Mode=TwoWay}" />
What happens is that when I'm trying to type the character . (period), the text cursor goes back to the start and just appears right after two presses of period. What could be causing this behavior?

I have tested the code when UpdateSourceTrigger=PropertyChanged as mentioned in the comments. The problem is that PropertyChanged causes the binding to update immediately after each keystroke. Because of this the behavior is quite upredicatable when the input does not contain a valid float. I have seen three different behaviors so far. Once only one digit is entered and period right after that, the binding sometimes converts it to a decimal:
But sometimes this did not happen and the control just let me enter 3. without any change. The behavior is seems really random. The key is that the value that is set to the backing property is then reflected in the UI by virtue of PropertyChanged event and data binding, which causes the text to change and cursor to jump.
Simply said, the problem here is the fact that the property is a float while the input accepts any string. The solution to your problem could be to use a string property for the binding, like AmountText and then in the setter verify that the text is actually a valid float, parse it and manually set the Amount property. This way you would preserve the "immediate" updating of the value as soon as a valid input is entered while you would also avoid the weird behavior you are seeing.
Also check out the WinRTXamlToolkit and its NumericUpDown control, which might be a better solution for your goal as it provides a natural way for the user to enter numeric values.

Related

Binding double to Textbox with validation in windows store apps

I am using prism for windows 8 the BindableBase class to validate the properties, till now I can bind the string properties and validate them with custom validator.
Now I want to bind the double value directly to the view with two way binding.the problem is when user enters any alphabetical character then the setter of that double property doesn't gets fire cause its not a double value and might fires a conversion exception but because of that I cant validate my property.
may I go for the converter ?, but how can I raise validation exception and make the property invalid in converter
Does anyone know how to do this?
Two way binding a double does indeed give some issues in Windows Store apps (input validation, localization, ...). What I usually do is have another property that represents this double as a string and bind the string value. You can also add validation on this string property and check if it does parse to a double with double.TryParse().
Hopefully a better solution for Windoew 10 UWP will be announced in the near future to prevent the need for this hack.

C# XAML Binding of a default with IValueConverter

I'm looking for a reason why my code isn't doing its job:
In XAML I use:
<TextBox Text="{Binding Path=Txt_8, Converter={StaticResource DefKonverter}, ConverterParameter='UserAlias'}"/>
In C# there are an IValueConverter which giving me a default value when the ConverterParameter='UserAlias'. For ex. the string 'Jettero'. This works well for that point I see in my TextBox the text 'Jettero'.
I saving my record to database, but in the record Txt_8 still NULL ! (Other fields are saved well)
Looks like the Binding not updating the record field behind the TextBox.
=========== Update start
CONCLUSION: This is not working because the Binding working in one direction. The Converter good for showing special things what makes your user experince better but not to save it.
=========== Update end
A similar issue backward happens also, In XAML:
<TextBox Text="{Binding Path=Date_1, Converter={StaticResource DefKonverter}, ConverterParameter='\{0:yyyy-MM-dd\}TimeStamp'}"/>
This working as it should in the record behind: when I write in the TextBox the '.' character it 'translates' to the today's date. After I save the record, it contains the date.
But in the TextBox I still see the written '.'.
In this sit the Binding not updating the TextBox over the record.
=========== Update start
CONCLUSION: This is not working well because the Binding working in one direction. The Converter good for change the data in that shape how you wanna store.
What is still not answered: when I convert '.' into the present date, it is not showing that - now I see the reason. BUT in the Converter if I'm using a Modal window to somehow extend the data what I wrote in (finding a full text for a keyword), that extended information SHOWS UP in my TextBox beside to store of it.
=========== Update end
I don't know what I miss... I checked lot of using of the default and IValueConverter solutions, but this simple sit never came up. Can anyone help?
I think you might be expecting behaviour from a value converter for which it wasn't designed. What is happening is:
On rendering the textbox, the binding reads a value, let's say null, from your property Txt_8, passes that to the converter, which gives it the value to render, in your example 'Jettero'. This means that the visual representation of your null is Jettero. This isn't meant to (and won't) consequently replace your null with 'Jettero' because, according to the binding engine, it has successfully loaded the value from the source and returned it to the target.
The ConvertBack method of the value converter is supposed to cater for the scenario where the value is changed on the UI and needs to be converted back for storage.
Moral of the story: don't use a value converter for specifying a "default" value for the binding. If your property needs a default value, assign it that in your constructor or initializer. If you want your property value to change itself as it is assigned a value, implement it there, instead of in the converter.
For instance, you can define a Date property like this instead of using a converter:
// disclaimer: untested pseudo-code
private DateTime? _dateTimeField;
public string SomeDateProperty
{
get { return _dateTimeField.ToString('dd-MM-yyyy'); }
set
{
if (value == '.')
value = DateTime.Today.ToString();
_dateTimeField = DateTime.Parse(value);
}
}

TwoWay binding is not really Two Way?

I have a two way binding on a string dependency property to the Text of a TextBox.
The binding looks like this:
Text="{Binding MyValue, Mode=TwoWay}"
I have some code that fires in OnKeyUp (in an attached property) that sets MyValue. But rather than taking my value and applying it to the Text property, it is going the other way around.
Here are the sequence of events:
The user enters a string of text that looks like this: 0299900650
The user presses enter.
In my on key up I set MyValue to 2999 and move to the focus to the next field.
The setter for MyValue fires and does a NotifiyPropertyChanged with 2999
The LostFocus fires.
The setter for MyValue fires and does a NotifiyPropertyChanged with 0299900650.
It seems to me that my value is not making it back to "TextBox.Text" somehow. When I loose focus the TextBox is updating the value of the string with what it has in the Text property (the unchanged value because my change did not get back.)
Is there some WPF magic I am not aware of here?
NOTE: I have double checked my bindings. (Besides they work from the UI so I imagine they are correct going to the UI.)
NOTE II: When I say the "user enters a string", it is really a scanned barcode. But since I am using a keyboard wedge, it is as if it was typed in. (However, the whole point of setting the value is because I am doing something different if the user scans as apposed to typing.)
UPDATE: I found this was due to another property having a side effect. I was able to fix the problem.
You simply jump into the concurency conflict on WPF binding messaging.
To prove that, do the following:
remove your OnKeyUp even handler
and do the same you did. On Enter click binding mechanism fires and sets your code behind property.
In case when you make on KeyUp, you new value 2999 is surpressed by the binding after.
To manage this correctly make use of Converter and get rid of OnKeyDown even subscription.
I found this was due to another property having a side effect. I was able to fix the problem by fixing that side effect.

Caliburn Micro: Disable button on form validation error

I have a form with a textbox bound to an integer, and a button. Now, when the value of the textbox is invalid, I want to immediately disable the button.
Normally, one would put a Can() method in the VM, and trigger a NotifyOfPropertyChange in the property's setter. However, if the user inputs a non numeric value for example, the textbox is invalid, but the property setter is never called, so I can't notify/disable the button.
So, how do I disable the button, when the user inputs an invalid value that doesn't cause the property setter to get called? My knowledge of CM is limited as I've just started out.
I've found the best approach to this problem is to make the property a string instead and do the necessary string to integer conversion in your property setter. If the conversion is invalid, then you could reset the TextBox value to a default value. This way your property setter will always get fired.
If your model has an integer property, then it makes sense to place the string version on the view model, as this is only really related to the UI, rather than business logic.
If you don't wish the user to be able to input non digit characters, then you can use a masked text box, such as the one included in the Extended WPF Toolkit, or in a third party control suite such as those offered by Telerik or Infragistics.
I'd use a MaskedTextBox instead and set the mask to integer only.

C# Input validation for a Textbox: float

This supposedly easy task gave me some headache. I simply want to let the user enter any text that succeeds float.TryParse into a Textboxish control.
I could use a normal TextBox and check the Text in some btnOK_Click, but this is obviously lame. Also, there is a nice built-in MaskedTextBox control, but I failed to set it's mask to be equal to float.TryParse. Also, it seems to check for validity only when a focus change occurs.
Digging around on the net brought some interesting ideas, but none of them as nice as I would like.
How did you solve this problem? Did I simply miss an obvious solution, or do I have to implement this functionality myself?
I'm aware of a few similar threads on SO, but there was no feasible solution to be found.
Update: Yes, WinForms.
Edit
Well that makes it alot easier... Just add a Validating Event Handler to your textbox
and do the TryParse in the code behind. If its invalid, prompt the user as such.
Validating will fire when the user is finished typing and moves focus from the TextBox so if you need to do on the fly checking, you could handle the TextChanged or on of the KeyPress/KeyUp Event handlers instead
Original
Is this in asp.net or winforms/wpf
If its asp.net, you could use a combination of RegularExpressionValidator (to account for comma seperation, 1 decimal point, etc...) and a RangeValidator to set the min/max values for a float.
Aside from that, the only way to guarantee it would be to wrap the textbox in an updatepanel, stick a CustomServerValidator on it, and in the server validate function, do a TryParse on the TextBox.Text value, if it succeeds, IS VALID, if it fails, NOT VALID
Be careful using Validating and validating to false. You might find that, unless you enter valid data, you can't move focus off the textbox which is a really big usability pain.
I solve this by simply trying a TryParse() on LostFocus and if the TryParse fails I color the textbox background a reddish tint to make it obvious that something is wrong.

Categories