I am using WPF 4.0 TextBox and binding. I am using StringFormat to format the number as currency. the XAML looks like this:
<TextBox Text="{Binding Path=ValueProperty, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, StringFormat={}{0:C}, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
Everything seems to work correctly except for a strange behavior:
When for example a user types in 12: right after typing 1, the value in the textbox becomes $1.00 and the weird thing is the the cursor is moved to be between the $ and the 1.
So when a user simply types in 12, the result becomes $21.00.
How can I fix this strange behavior?
I'd change your UpdateSourceTrigger back to the default (for TextBox) of LostFocus.
By setting it to PropertyChanged, you're forcing your validation, and the string format, to run every time the user types a character. This causes very odd behavior, such as what you're seeing.
If you leave it the default (or set it back to LostFocus explicitly), the formatting + validation will happen when the user finishes typing completely. This will eliminate the strange problems that happen by StringFormat inserting new characters, validation breaking part way through, and other issues you will run into using PropertyChanged.
you can use this string format it'll fix this issue
"$###\,##0.0##"
your code should looks like
<TextBox Text="{Binding Path=ValueProperty, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, StringFormat=$###\,##0.0##, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
This issue has been fixed in .NET 4.5. For .NET 4, I had to remove StringFormat in order to keep UpdateSourceTrigger=PropertyChanged
Related
I have binding in TextBox
<TextBox x:Name="TbxActiveSourceNameSourceNameSourceName" IsEnabled="True" Text="{Binding ViewAudioAudio_ActiveSourceNameModel.ActiveSourceName_SourceName,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Padding="0,-2,0,0" Height="15" VerticalAlignment="top" Margin="127,10,0,0" FontSize="10" BorderBrush="#FF918D8D" TextAlignment="Center" Width="75px" HorizontalAlignment="Left" HorizontalContentAlignment="Right" />
But characters run from right-to-left.
How do I must to characters run from left-to-right(normal) when I input words in textBox
Many Thanks
I know this is old question but if anyone runs into this issue it happens to deal with
<TextBox Text={..., UpdateSourceTrigger=PropertyChanged}
it seems that when the property changes via keystroke it automatically detects the property change and so it updates the property it's binding to as well. Because of this it resets the cursor to the very left of the textbox rather than leaving where it was last left off.
Or at least I've been only able to reproduce this issue by changing a textbox to textblock and then back to a textbox and changing the UpdateSourceTrigger to a type that isn't PropertyChanged and would correct the issue and have the text flow right to left.
Set the FlowDirection property to LeftToRight. Reference here.
I'm having a problem with data entry since switching to .NET 4.0.
In my Xceed 3.7 grid, the user used to be able to type a value into a cell, and when they clicked away or hit enter, the bound converter's ConvertBack method would be called, parsing the user input value and storing in the desired format.
Now all of the sudden, this is happening every keystroke - which is causing a huge problem, because if the user erases a number and starts typing another one, (lets say -100), as soon as they type the negative sign, the convertback fires and throws an exception because "-" is not a parsable string, and the value is reverted.
I think the problem is pretty clear, so now I'll paste in some code.
Columns for user input appear as follows:
<xcdg:DataGridControl x:Name="AggCatGrid01"
ItemsSource="{Binding Source={StaticResource myDataSource}}" >
<xcdg:DataGridControl.Columns>
...
<xcdg:Column VisiblePosition="0" FieldName="SomeValue" Title="Some Value"
CellEditor="{StaticResource PercentageEditor}"
CellContentTemplate="{StaticResource EditablePercent2CellContentTemplate}" />
Datagrids all share the same style:
<Style x:Key="{x:Type xcdg:DataGridControl}" TargetType="{x:Type xcdg:DataGridControl}">
<Setter Property="UpdateSourceTrigger" Value="CellEndingEdit"/>
<Setter Property="AutoCreateColumns" Value="False"/>
<Setter Property="EditTriggers" Value="BeginEditCommand, CellIsCurrent, ActivationGesture"/>
<Setter Property="CellEditorDisplayConditions" Value="CellIsCurrent"/>
<Setter Property="NavigationBehavior" Value="CellOnly"/>
Notice that UpdateSourceTrigger is set to CellEndingEdit. I would have thought that this right here would be responsible for when the converters get called and the bound value is updated. Whatever controls that changed just by switching .NET4 though.
Here's the data template for the column you saw used above:
<!-- Styles used when editable cells are being edited. -->
<xcdg:CellEditor x:Key="PercentageEditor">
<xcdg:CellEditor.EditTemplate>
<DataTemplate>
<xcdg:AutoSelectTextBox Style="{StaticResource DefaultAutoSelectTextBox}"
Text="{xcdg:CellEditorBinding Converter={StaticResource EditablePercentageConverter}}" />
</DataTemplate>
</xcdg:CellEditor.EditTemplate>
</xcdg:CellEditor>
I think the converter code itself is irrelevant, so I'll leave it out unless it's requested. The problem is that it's getting called every keystroke.
If you can shed any light on this, I'd be ecstatic. I mean, I might have to roll back all my .NET 4.0 enhancements, or delay my next release by upwards of a month rewriting all my datagrids to no longer use xceed if there isn't a solution to this. Thanks guys.
Update #1
I actually came up with a moderately clever workaround (in my modest opinion) where I introduce a dummy textblock to hold the CellEditorBinding xceed forces us to use in the datatemplate. I then changed my input control to bind to the textblock's text property rather than the CellEditorBinding directly, which allowed me to specify my own binding mode. Here I was able to set the mode to 'lostFocus' and the major problem was solved! Converter is no longer being called on every keystroke, but only when the user leaves the cell or hits enter.
<xcdg:CellEditor x:Key="PercentageEditor">
<xcdg:CellEditor.EditTemplate>
<DataTemplate>
<Grid>
<TextBlock x:Name="bind_source" Text="{xcdg:CellEditorBinding}" Visibility="Collapsed"/>
<xcdg:AutoSelectTextBox Style="{StaticResource DefaultAutoSelectTextBox}"
Text="{Binding ElementName=bind_source, Path=Text, Mode=TwoWay, UpdateSourceTrigger=LostFocus, Converter={StaticResource EditablePercentageConverter}}" />
</Grid>
</DataTemplate>
</xcdg:CellEditor.EditTemplate>
</xcdg:CellEditor>
As you can imagine though, this layer of indirection has cause a few other minor issues, such as breaking validation. Oddly enough, now when the user types invalid data, the converter throws an exception which xceed catches and uses to turn on the cell's error template, but correcting the error and hitting enter no longer works. The user's only option is to hit the ESC key, causing the cell value to revert and lose focus, before they can correct their entry.
I'm still hoping for a more elegant solution that will fix this.
Update #2
I found a developer on Xceed support forums which presented the same issue as me in this post: http://silverlightdatagrid.com/CS/forums/permalink/31548/31516/ShowThread.aspx#31516.
Many users seem totally confused by your examples (which are largely out of date for .Net 4.0) and only target your own controls using the xcdg:CellEditorBinding which only seems to support PropertyChanged validation.
Unfortunately no solution was ever offered. He did present a strategy for changing the update source trigger more elegantly which I was able to adopt, but I still have the problem of the validation error freezing the cell until the user hits ESC.
<xcdg:AutoSelectTextBox Style="{StaticResource DefaultAutoSelectTextBox}"
Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=xcdg:DataCell},
Path=Content, UpdateSourceTrigger=LostFocus,
Converter={StaticResource EditablePercentageConverter}}" />
Update #3
I have confirmed that by updating to Xceed DataGrid version 4.3 (on trial), the problem went away all on its own, as in that version, Xceed updated its xcdg:CellEditorBinding UpdateSourceTrigger incompatibility with .Net4.0. Since, however, a license for Xceed only includes 6 months of bug fix updates before you have to pay for a whole new license (ridiculous), and I don't see any company authorizing an outrageous $1200 single developer license fee to use the latest Xceed dll just for this one minor bug, I'm still going to strive to find a complete workaround in the 3.7 version of Xceed. I'll present this 'solution' for the developers that have access to money to burn.
As it turns out, upgrading to 4.3 didn't solve the problem. It only appeared to because I'd forgotten to back out my previous change. Even in the latest version, Xceed still hasn't exposed the UpdateSourceTrigger property on on CellEditorBinding.
The solution is:
<xcdg:AutoSelectTextBox Style="{StaticResource DefaultAutoSelectTextBox}"
Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=xcdg:DataCell},
Path=Content, UpdateSourceTrigger=LostFocus,
Converter={StaticResource EditablePercentageConverter}}" />
There's really no other way to do it. If you aren't using the latest version of Xceed, this will also lead to validation errors, but in the latest version, using this new binding path works perfectly. I still think it's a hack, and hopefully xceed will realize it needs to expose a few more properties on its CellEditorBinding.
I don't know XCeed controls, so this is just educated guess.
I personally would place the UpdateSourceTrigger to the binding declaration like it is done in a regular .NET control:
Text="{xcdg:CellEditorBinding Converter={StaticResource EditablePercentageConverter}, UpdateSourceTrigger=CellEndingEdit}"
Also, since the control is commercial, you should be entitled to some tech support from XCeed.
I've got the following Situation:
TextBox which is bound to a property:
<TextBox Text="{Binding Settings.ClientName, UpdateSourceTrigger=PropertyChanged}"/>
The property ClientName stores its value in the unterlying structures and does NOT call Notifyon the property changed event. instead the underlying structures send an event to refresh the UI after they processed the value . If such an event is fired, the ClientNameProperty is set correctly and Notify is called for this property.
the problem is that if i enter any text, the caret seems to jump to the first position in the textbox, actuall reversing any string i enter. "abcd" becomes "dcba"
I noticed that this behaviour occured after we migrated to Net 4.0.
Are there any good solutions out there?
Many thanks
There is no built-in behavior that would do that. That problem is likely to come from your processing.
On a side note, if you want the TextBox to change from code-behind as well as from user input, you want to make it Two-Way:
<TextBox Text="{Binding Settings.ClientName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
EDIT:
You could also make the ClientName a dependency property (propdp snippet in vs2010). That would automatically fully support binding(/styling/animation), and gives you the possibility to act when the value changes as well as to coerce it back through callback delegates.
Last but not least, you still wouldn't need your Settings class to implement INotifyPropertyChanged.
Here is a place to start (msdn).
I suspect you are suffering from this behavior change in the WPF TextBox: https://connect.microsoft.com/VisualStudio/feedback/details/588343/changed-behaviour-from-net-3-5-to-net-4-0-of-wpf-textbox-formatting-when-propertychanged-is-used-as-updatesourcetrigger (Changed behaviour from .Net 3.5 to .Net 4.0 of WPF TextBox formatting when PropertyChanged is used as UpdateSourceTrigger)
Here's my code snippet :
<TextBox Text="{Binding Path=Amount, Mode=TwoWay, StringFormat=\{0:N\}}" />
If the user enters letters or a large number etc, the stringformat dies silently. How can i raise an exception instead ?
Thanks
Bindings swallow exceptions thrown when text input cannot be converted to the data type required by the property on source object. However you can specify ValidatesOnException in the binding. That will cause the standard red border reporting of a conversion problem. BTW this is unrelated to the string format property which is only relevant for displaying the current value, it isn't in play when user is entering data.
<TextBox Text="{Binding Path=Amount, Mode=TwoWay, StringFormat=\{0:N\}, ValidatesOnExceptions=True}" HorizontalAlignment="Left" Width="200"/>
Note I've limited the width and aligned to left. One of the problems with the default validation popup is that is that it is always displayed to the right, which is a bit of a problem when the text box right border is flush with the right edge of the silverlight control's right edge.
Have you thought of writing a filter behavior that allows you to control exactly what goes into the text box?
I am binding an object to a TextBox with the following XAML:
<TextBox Name="MyTextBox" Text="{Binding Path=MyValue, Mode=TwoWay, StringFormat={}{0:F2}}" />
Naturally when I bind a new object (which values are all still zero) the Text property is set to 0.00. I have several of these TextBoxes, which makes it tedious to delete every value before entering a new one.
At the moment I'm clearing these boxes in the Window_Loaded method using the FindVisualChildren method.
It just feels clunky though. Is there a neat way of doing this?
Try the following:
StringFormat={}{0:#.##}
It will format to two decimal places and won't show zeroes.