Unable to set ViewModel property when bound to UWP ComboBox

421 views Asked by At

In a UWP/Template10 app we have a ComboBox bound to a ViewModel property. The value of the ViewModel property is set in OnNavigatedToAsync. If we remove the ComboBox binding the property in the ViewModel is set appropriately. But if the ComboBox is bound to the property, the ViewModel property remains null.

The XAML looks like this

<ComboBox 
    Name="JobTypeComboBox" 
    ItemsSource="{x:Bind JobViewModel.JobTypes}" 
    SelectedItem="{x:Bind JobViewModel.JobType,Mode=TwoWay,Converter={StaticResource ChangeTypeConverter}}"/>

The ViewModel looks like this

JobType _JobType = default(JobType);
public JobType JobType { get { return _JobType; } set { Set(ref _JobType, value); } }
public ObservableCollection<JobType> JobTypes = new ObservableCollection<JobType>(JobTypeService.GetJobTypes());

public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary<string, object> state)
    {
            this.JobType = job.JobType;

EDIT 1: The converter looks like this

public class ChangeTypeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (targetType.IsConstructedGenericType && targetType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
        {
            if (value == null)
            {
                return null;
            }
            targetType = Nullable.GetUnderlyingType(targetType);
        }

        if (value == null && targetType.GetTypeInfo().IsValueType)
            return Activator.CreateInstance(targetType);

        if (targetType.IsInstanceOfType(value))
            return value;

        return System.Convert.ChangeType(value, targetType);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return Convert(value, targetType, parameter, language);
    }
}

In the execution of the line this.JobType = job.JobType; there are 6 calls to the converter:

Convert is called with the correct value for JobType and returns the correct value.

ConvertBack is called with value = null and returns null;

Convert is called with value = null and returns null;

Convert is called with value = null and returns null;

ConvertBack is called with value = null and returns null;

Convert is called with value = null and returns null;

So it looks like the binding is bouncing the value back to ConvertBack as null.

Job.JobType is returned correctly. If the binding is removed from JobTypeComboBox, this.jobType is set correctly. When the binding is added to JobTypeComboBox, this.JobType remains null.

How do I set the value of this.jobType when JobTypeComboBox is bound to it?

1

There are 1 answers

1
Jerry Nixon On

Well, using this view-model:

public class MainPageViewModel : ViewModelBase
{
    public MainPageViewModel()
    {
        ComboBoxItem = ComboBoxItems.First();
    }

    string _ComboBoxItem = default(string);
    public string ComboBoxItem { get { return _ComboBoxItem; } set { Set(ref _ComboBoxItem, value); } }

    public ObservableCollection<string> ComboBoxItems { get; } = new ObservableCollection<string>(new[] { "1", "2", "3", "4" });
}

And this XAML:

<ComboBox x:Name="testComboBox"
            ItemsSource="{Binding ComboBoxItems}"
            RelativePanel.AlignLeftWith="parameterResizer"
            RelativePanel.Below="stateTextBox"
            SelectedItem="{Binding ComboBoxItem, Mode=TwoWay}" />

<TextBlock x:Name="testTextBlock"
            RelativePanel.AlignLeftWith="parameterResizer"
            RelativePanel.Below="testComboBox"
            Text="{Binding ComboBoxItem}" />

I got this to happen:

enter image description here

Thanks for using Template 10 - though I think this has nothing to do with T10. :-)