Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UWP - Bind TextBox.Text to Nullable<int>

Is it correct that it is not currently possible to bind to any Nullable<T> in Universal XAML Apps?

I found this link from 2013:

https://social.msdn.microsoft.com/Forums/en-US/befb9603-b8d6-468d-ad36-ef82a9e29749/textbox-text-binding-on-nullable-types?forum=winappswithcsharp

Stating that:

Binding to nullable values isn't supported in Windows 8 Store apps. It just didn't make it into this release. We've already got bugs on this behavior for v.Next.

But can it really be that this has not been fixed yet?

My Binding:

<TextBox Text="{Binding Serves, Mode=TwoWay}" Header="Serves"/>

My Property:

public int? Serves
{
    get { return _serves; ; }
    set
    {
        _serves = value;
        OnPropertyChanged();
    }
}

And the error I get in my output:

Error: Cannot save value from target back to source. 
BindingExpression: 
    Path='Serves' 
    DataItem='MyAssembly.MyNamespace.RecipeViewModel, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Windows.UI.Xaml.Controls.TextBox' (Name='null'); target property is 'Text' (type 'String').
like image 663
Troels Larsen Avatar asked Oct 31 '15 16:10

Troels Larsen


1 Answers

Seems like it's not fixed. As XAML is using a build-in converter, in this case you can probably exchange it with your own, dealing with nullables:

XAML:

<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel.Resources>
        <local:NullConverter x:Key="NullableIntConverter"/>
    </StackPanel.Resources>
    <TextBox Text="{Binding Serves, Mode=TwoWay, Converter={StaticResource NullableIntConverter}}" Header="Serves"/>
</StackPanel>

Code behind:

public class NullConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    { return value; }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        int temp;
        if (string.IsNullOrEmpty((string)value) || !int.TryParse((string)value, out temp)) return null;
        else return temp;
    }
}

public sealed partial class MainPage : Page, INotifyPropertyChanged
{
    private int? _serves;

    public event PropertyChangedEventHandler PropertyChanged;
    public void RaiseProperty(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));

    public int? Serves
    {
        get { return _serves; }
        set { _serves = value; RaiseProperty("Serves"); }
    }

    public MainPage()
    {
        this.InitializeComponent();
        DataContext = this;
    }
}
like image 119
Romasz Avatar answered Nov 14 '22 23:11

Romasz