Reputation: 1482
I have a problem with Float data type while using UpdateSourceTrigger in WPF.I have a property with float data type and it is binded it to a TextBox and set its UpdateSourceTrigger of the binding to PropertyChanged,but WPF dosen't let me type '.' in the TextBox unless i change UpdateSourceTrigger to LostFocus.I think it's because of we can not type '.' in the end of float value.I don't have any idea how can i fix it because i need to type '.' and set UpdateSourceTrigger to PropertyChanged.
I have designed my textbox in such a way that it can take only 7 characters for example 1) 12.3456 2) 1234.56 e.t.c
The property is:`
public float? Expenditure
{
get;set;
}
And in the XAML:
<TextBox Text="{Binding Expenditure, UpdateSourceTrigger=PropertyChanged}"/>
StringFormat does not help as decimal can be put anywhere. Any help would be great.
Upvotes: 2
Views: 4224
Reputation: 63
I wrote a value converter, that solves your problem:
Usage:
<Window x:Class="BindingExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BindingExample"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:DoubleToStringConverter x:Key="DoubleToStringConverter" DigitsCount="5"/>
</Window.Resources>
<StackPanel>
<TextBox Text="{Binding FloatProperty, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource DoubleToStringConverter}}" Margin="5"/>
</StackPanel>
</Window>
Converter:
[ValueConversion(typeof(double), typeof(string))]
public class DoubleToStringConverter : IValueConverter
{
#region IValueConverter Members
public DoubleToStringConverter()
{
// Default value for DigitsCount
DigitsCount = 7;
}
// Convert from double to string
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return null;
double doubleValue = System.Convert.ToDouble(value);
// Calculate digits count
int digitsBeforePoint = System.Convert.ToInt32(Math.Ceiling(Math.Log10(doubleValue)));
int digitsAfterPoint = DigitsCount - digitsBeforePoint;
// TODO: You have to handle cases where digitsAfterPoint < 0
// Create formatString that is used to present doubleValue in desired format
string formatString = String.Format("{{0:F{0}}}", digitsAfterPoint);
return String.Format(formatString, doubleValue);
}
// Convert from string to double
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return null;
double? result = null;
try
{
result = System.Convert.ToDouble(value);
}
catch
{
}
return result.HasValue ? (object)result.Value : DependencyProperty.UnsetValue;
}
public int DigitsCount { get; set; }
#endregion
}
Upvotes: 2
Reputation: 63
Just change StringFormat property of the binding to display two decimal places of the property:
<TextBox Text="{Binding Expenditure, UpdateSourceTrigger=PropertyChanged, StringFormat='{}{0:F2}'}"/>
Also you can write a custom FloatToStringConverter (here is an example). Your own float-to-string and string-to-float conversion methods will allow you to handle empty text field of TextBox and convert it to null.
Upvotes: 2