Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to bind to a ValueTuple field in WPF with C#7

If I have a viewmodel property

public (string Mdf, string MdfPath) MachineDefinition { get; set; }

and I try to bind to it in XAML / WPF

<Label Content="{Binding Path=MachineDefinition.Item2}" />

or

<Label  Content="{Binding Path=MachineDefinition.MdfPath}" />

I get the same error

enter image description here

I see that ValueTuple fields are really fields not properties. Is this the problem?

like image 438
bradgonesurfing Avatar asked Apr 04 '17 13:04

bradgonesurfing


People also ask

How do I bind a text box in WPF?

One-Way Data Binding First of all, create a new WPF project with the name WPFDataBinding. The following XAML code creates two labels, two textboxes, and one button and initializes them with some properties.

How many types of binding are there in WPF?

WPF binding offers four types of Binding. Remember, Binding runs on UI thread unless otherwise you specify it to run otherwise. OneWay: The target property will listen to the source property being changed and will update itself.


2 Answers

The confusion is that for old style Tuple ( pre C#7 ) all the Items were properties

https://msdn.microsoft.com/en-us/library/dd386940(v=vs.110).aspx

and thus bindable. For ValueTuple they are fields

https://github.com/dotnet/runtime/blob/5ee73c3452cae931d6be99e8f6b1cd47d22d69e8/src/libraries/System.Private.CoreLib/src/System/ValueTuple.cs#L269

and not bindable.

If you google "WPF Tuple Binding" you get loads of false positives because old style tuples are bindable but the new ones are not.

like image 82
bradgonesurfing Avatar answered Oct 22 '22 01:10

bradgonesurfing


Something you could try is to implement a value converter. Here is an example...

public class TupleDisplayNameConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var tuple = value as (Int32 Id, String Name)?;

        if (tuple == null)
            return null;

        return tuple.Value.Name;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}


<TextBlock Text="{Binding Converter={StaticResource TupleDisplayNameConverter}, Mode=OneWay}" />

Hope this helps.

like image 38
sergio Avatar answered Oct 22 '22 01:10

sergio