WPF binding not working properly with properties of int type

24,556

Solution 1

I had the similar problem.

You just need to update the code as:

<TextBox Text="{Binding Path=MaxOccurrences, Mode=TwoWay, TargetNullValue={x:Static sys:String.Empty},
NotifyOnSourceUpdated=True,  UpdateSourceTrigger=PropertyChanged}"  
HorizontalAlignment="Center" Width="30" Margin="0,0,5,0"/> 

Solution 2

This is partially a guess (I haven't got VS handy right now to try it out), but I think it's because a cleared text box is an empty string (""), which can't be implicitly converted to an int. You should probably implemented a type converter to provide the conversion for you. (you probably want to do something like convert "" to 0)

Solution 3

If you don't want to use a Nullable integer, you can use a converter that converts the empty string to 0, see the code below:

public class EmptyStringToZeroConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null || string.IsNullOrEmpty(value.ToString())
            ? 0
            : value;
    }

    #endregion
}

Solution 4

Akjoshi, I have a working solution!

You need to change your integer property to Naullable<int> (i.e. int? ), see the following snippet:

private int? _maxOccurrences;
public int? MaxOccurrences
{
    get { return _maxOccurrences; }
    set { _maxOccurrences = value; }
}

You also need to add a value converter to convert the empty string to null value, see the following code snippet:

public class EmptyStringToNullConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null || string.IsNullOrEmpty(value.ToString())
            ? null
            : value;
    }

    #endregion
}

The XAML code:

<Window x:Class="ProgGridSelection.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:System="clr-namespace:System;assembly=mscorlib" 
    xmlns:local="clr-namespace:ProgGridSelection"
    Title="MainWindow"
    Height="136" Width="525"
    Loaded="OnWindowLoaded">
<Window.Resources>
    <local:EmptyStringToNullConverter x:Key="EmptyStringToNullConverter"/>
</Window.Resources>
<StackPanel>
    <Button Content="Using Empty String to Null Converter"/>
    <TextBox Name="empNameTextBox"
             Text="{Binding Mode=TwoWay, Path=MaxOccurrences,
                RelativeSource={RelativeSource FindAncestor, AncestorType=Window},
                Converter={StaticResource EmptyStringToNullConverter}}"/>
</StackPanel>

[Note: this is just a proof of concept, and for the sake of simplicity I didn't use any patterns or best practices]

Share:
24,556
akjoshi
Author by

akjoshi

Dot net developer having expertise in WPF. http://weblogs.asp.net/akjoshi

Updated on February 13, 2020

Comments

  • akjoshi
    akjoshi about 4 years

    I am having a property of int type in my view model which is bound to a TextBox. Everything works properly, TwoWay binding works fine except in one case -

    If I clear the value of TextBox, property setter doesn't gets called and although value is cleared in TextBox, property still holds the previous value.

    has anyone faced similar issue? is there any workaround for this?

    Here is the property -

    public int MaxOccurrences
    {
        get
        {
            return this.maxOccurrences;
        }
        set
        {
            if (this.maxOccurrences != value)
            {
                this.maxOccurrences = value;
                base.RaisePropertyChanged("MaxOccurrences");
            }
        }
    }
    

    Here is how I am binding the property in xaml -

    <TextBox Text="{Binding Path=MaxOccurrences, Mode=TwoWay, 
        NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" 
        HorizontalAlignment="Center" Width="30" Margin="0,0,5,0"/>
    
    • akjoshi
      akjoshi over 13 years
      I am curious to know whether this behavior is same in silverlight or not? Anyone!
    • Matt Casto
      Matt Casto over 13 years
      Same behavior in Silverlight, except for data binding properties like NotifyOnSourceUpdated and UpdateSourceTrigger that aren't supported in Silverlight.
  • Tiberiu Ana
    Tiberiu Ana almost 15 years
    Easiest way to check -- run your project in Visual Studio and watch the Output window (View-Output). When you clear the textbox, you should see the Binding error Simon is talking about.
  • Didier Supernover
    Didier Supernover almost 15 years
    I don't see anything wrong with it. Have a +1 from me. Although I think the preferred way would be a type converter rather than a duplicate property.
  • akjoshi
    akjoshi about 13 years
    Thanks Mohammed, but this solution was already mentioned by 'Simon' a year back.
  • Alain
    Alain almost 12 years
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
  • JsAndDotNet
    JsAndDotNet about 9 years
    For the benefit of searchers, I found this value converter (codecisions.com/…) kept the textbox showing as empty rather than changing it to a zero in the foreground as this answer seems to do. Obviously depends on requirements as to which you go for.
  • walterhuang
    walterhuang almost 8 years
    for .net 3.5 or above, try TargetNullValue=''