I m using the binding in Silverlight. I have binded the TextBox with Decimal entity. Below is the Code snipts of bindings.
<TextBox x:Name="AmountBox" Text="{Binding SelectedEntity.Amount,Mode=TwoWay,StringFormat=\{0:n2\},Converter={StaticResource DecimalBlankValueConverter}}" Validate="True" TextChanged="AmountBox_TextChanged" LostFocus="AmountBox_LostFocus"/>
Below is the converter code.
decimal result;
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!Decimal.TryParse(value.ToString(),out result) || (decimal)value == decimal.Zero)
return null;
return decimal.Parse(value.ToString());
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null || !Decimal.TryParse(value.ToString(), out result))
return 0.00;
return decimal.Parse(value.ToString());
}
on lost focus I am updating the source with GetBindingExpression(TextBox.TextProperty).UpdateSource();
Everything is workig well, But convert is not called on lost focus and when I am entering string in the textbox, than convert is not called and it will not convert the textBox text to blank.
Can anyone please suggest me , what is the probelm in the code.
Thanks in advance. ----Raj
TwoWay
mode binding with TextChanged
and LostFocus
events are definitely not the best approach. Why do you call GetBindingExpression(TextBox.TextProperty).UpdateSource();
in the LostFocus
if binding does it by default? If you want to update a binding manually, set UpdateSourceTrigger=Explicit
.
Anyway your converter seems fine, but I think you don't need it. If I understand right, you want to clear the text if it cannot be cast to decimal. In that case you have a few options, like creating your custom TextBox
that allows only digits, or you can check NumericUpDown
control from Silverlight Toolkit. Also I've found similar question here.
If you have installed Microsoft Expression Blend
(if don't, you can download BlendSLSDK_en.msi
from Microsoft Expression Blend Software Development Kit), add System.Windows.Interactivity
dll to your project and create simple Behavior
like this:
public class TextBoxClearTextBehavior : System.Windows.Interactivity.Behavior<System.Windows.Controls.TextBox>
{
protected override void OnAttached()
{
AssociatedObject.LostFocus += AssociatedObjectLostFocus;
base.OnAttached();
}
protected override void OnDetaching()
{
AssociatedObject.LostFocus -= AssociatedObjectLostFocus;
base.OnDetaching();
}
private void AssociatedObjectLostFocus(object sender, System.Windows.RoutedEventArgs e)
{
decimal result;
if (!decimal.TryParse(AssociatedObject.Text, out result))
AssociatedObject.Text = string.Empty;
}
}
and use it like
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
...
<TextBox Text="{Binding Amount, Mode=TwoWay, StringFormat=\{0:n2\}}">
<i:Interaction.Behaviors>
<Behavior:TextBoxClearTextBehavior/>
</i:Interaction.Behaviors>
</TextBox>