Dishant
Dishant

Reputation: 1595

UWP Binding to ConverterParameter not working

I am binding a VM property to my ConverterParemeter, but it always appear to be null in Converter, is there any alternative to pass property to the converter.

As I can't share the original code, below is the replica of the issue that I am facing. In my DummyConverter parameter is always null even though FilterType value is set.

Xaml:

<Grid>
        <ComboBox x:Name="myComboBox" ItemsSource="{Binding ComboBoxList, Converter={StaticResource DummyConverter}, ConverterParameter={Binding FilterType}}" SelectedItem="{Binding SelectedPerson, Mode=TwoWay}" HorizontalAlignment="Center" VerticalAlignment="Center" Height="50" Width="150">
        </ComboBox>
    </Grid>

VM:

public class MainViewModel : INotifyPropertyChanged
    {
        private string header;

        public string Header
        {
            get { return header; }
            set
            {
                header = value;
                RaisePropertyChange(nameof(Header));
            }
        }

        private Person selectedPerson;

        public Person SelectedPerson
        {
            get { return selectedPerson; }
            set { selectedPerson = value; RaisePropertyChange(nameof(SelectedPerson)); }
        }


        private ObservableCollection<Person> comboBoxList;

        public ObservableCollection<Person> ComboBoxList
        {
            get { return comboBoxList; }
            set { comboBoxList = value; }
        }

        public FilterType FilterType { get; set; }

        public DelegateCommand DropDownClosedCommand { get; set; }

        public MainViewModel()
        {
            Header = "My Header";

            FilterType = FilterType.None;

            ComboBoxList = new ObservableCollection<Person> {
                 new Person() { Name = "Person 1", IsChecked = false },
                      new Person() { Name = "Person 2", IsChecked = false },
                      new Person() { Name = "Person 3", IsChecked = false },
                      new Person() { Name = "Person 4", IsChecked = false }
            };

            DropDownClosedCommand = new DelegateCommand(OnDropDownClosed);

        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChange(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private void OnDropDownClosed(object e)
        {
            //CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
            //() =>
            //{
                SelectedPerson = ComboBoxList.FirstOrDefault(x => x.IsChecked);
            //});
        }
    }

Converter:

public class DummyConverter : 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)
        {
            return value;
        }
    }

In WPF, I can do with MultiBinding but in UWP MultiBinding is not available.

EDIT:

From this blog post I found out the reason of getting null values is "The reason why is that the ConverterParameter IS NOT a dependency property but a “simple” object."

So below is the modified code:

Xaml:

<Page.Resources>
        <converters:DummyConverter x:Name="DummyConverter" FilterType="{Binding FilterType}"/>
</Page.Resources>

<Grid>
         <ComboBox x:Name="myComboBox" ItemsSource="{Binding ComboBoxList, Converter={StaticResource DummyConverter}}" SelectedItem="{Binding SelectedPerson, Mode=TwoWay}" HorizontalAlignment="Center" VerticalAlignment="Center" Height="50" Width="150">
          <interactivity:Interaction.Behaviors>
            <core:DataTriggerBehavior Binding="{Binding IsDropDownOpen, ElementName=myComboBox}" ComparisonCondition="NotEqual" Value="True">
                <core:InvokeCommandAction Command="{Binding DropDownClosedCommand}"/>
            </core:DataTriggerBehavior>
          </interactivity:Interaction.Behaviors>
    </ComboBox>
    </Grid>

Converter:

  public class DummyConverter : DependencyObject, IValueConverter
    {
        public FilterType FilterType
        {
            get { return (FilterType)GetValue(FilterTypeProperty); }
            set { SetValue(FilterTypeProperty, value); }
        }

        public static readonly DependencyProperty FilterTypeProperty =
        DependencyProperty.Register("FilterType",
                                    typeof(FilterType),
                                    typeof(DummyConverter),
                                    new PropertyMetadata(null));

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

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

MainViewModel.cs

private void OnDropDownClosed(object e)
        {
            //CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
            //() =>
            //{
                SelectedPerson = ComboBoxList.FirstOrDefault(x => x.IsChecked);
                FilterType = FilterType.Descending;
                this.RaisePropertyChange(nameof(ComboBoxList));
            //});
        }

I am changing the value of FilterType in OnDropDownClosed but it's not affecting in the converter.

Upvotes: 1

Views: 1752

Answers (1)

Dishant
Dishant

Reputation: 1595

I figured out the issue why FilterType was not changing, it's because PropertyChangedEvent was not firing. I updated the code as below and it's working now as expected.

private void OnDropDownClosed(object e)
{
   SelectedPerson = ComboBoxList.FirstOrDefault(x => x.IsChecked);
   FilterType = FilterType.Descending;
   this.RaisePropertyChange(nameof(FilterType));
   this.RaisePropertyChange(nameof(ComboBoxList));
 }

Upvotes: 1

Related Questions