简体   繁体   中英

Cannot Assign a Null Value to a Nullable Int32? via Binding

Cannot assign a null value via a TextBox Binding to Int32?. If the TextBox is empty then Int32Null Set is not called.
A red border is around the TexBox indicating a validation exception.

This just does not make sense as Int32? is nullable. If the user removes the integer value from the TextBox I want the Set called so the property is assigned to null.

When it starts int32Null = null and the TextBox is not red.

I tried implementing Validation and set validation = true if the TextBox is empty. But Set is still not called and TextBox is red indicating a validation error.

It seems like I should be able to assign a null value to a nullable via binding.

    <Window x:Class="AssignNull.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            DataContext="{Binding RelativeSource={RelativeSource self}}"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <TextBox Grid.Row="0" Grid.Column="0" Text="{Binding Path=Int32Null, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
            <TextBox Grid.Row="2" Grid.Column="0" Text="{Binding Path=StringNull, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
        </Grid>
    </Window>
    public partial class MainWindow : Window
    {
        private Int32? int32Null = null;
        private string stringNull = "stringNull";
        public MainWindow()
        {
            InitializeComponent();
        }
        public Int32? Int32Null
        {
            get { return int32Null; }
            set { int32Null = value; }
        }
        public string StringNull
        {
            get { return stringNull; }
            set { stringNull = value; }
        }
    } 

Set StringNull does get called and value passed is not null but rather string.empty.

Since Set is not called on Int32Null I don't know what is getting passed.

It was also passing a string.empty to Int32?. Had to convert an empty string to null.

    [ValueConversion(typeof(Int32?), typeof(String))]
    public class Int32nullConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Int32? int32null = (Int32?)value;
            return int32null.ToString();
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string strValue = value as string;
            if(string.IsNullOrEmpty(strValue.Trim())) return null;
            Int32 int32;
            if (Int32.TryParse(strValue, out int32))
            {
                return int32;
            }
            return DependencyProperty.UnsetValue;
        }
    }

You make a false assumption on how the type converters ought to handle this. So if they do not do what you want, namely turn an empty string into null you'll either have to write your own or use a Binding.Converter that does the conversion for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM