Use Binding as ConverterParameter

20,818

Solution 1

ConverterParameter is not a Dependency Property, hence you won't be able to bind any property. However, you can try using MultiBinding with MultiValueConverter.

Code:

<TextBox>
    <TextBox.Text>
        <MultiBinding Converter="{StaticResource MultiValueConverter}">
            <Binding Path="property1"/>
            <Binding Path="property2"/>
        </MultiBinding>
    </TextBox.Text>
</TextBox>
public class MultiValueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, 
           object parameter, System.Globalization.CultureInfo culture)
    {
         property1 = values[0];
         property2 = values[1];
         // Do your logic with the properties here.
    }
    public object[] ConvertBack(object value, Type[] targetTypes, 
           object parameter, System.Globalization.CultureInfo culture)
    {

    }
}

Solution 2

Another, potentially simpler way to do this is to define a bindable property on the converter itself.

public class CompareConverter: IValueConverter, INotifyPropertyChanged{
  private ComparisonType _comparison = ComparisonType.Equals;
  public ComparisonType Comparison {
    get {return _comparison; }
    set { _comparison = value; OnPropertyChanged(); }
  }

  private string _compareTo = null;
  public string CompareTo {
    get {return _compareTo; }
    set { _compareTo = value; OnPropertyChanged(); }
  }

  public event PropertyChangedEventHandler PropertyChanged;

  protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  { 
    if (PropertyChanged != null) 
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
  } 

  public object Convert (object value, Type targetType, object parameter, 
     System.Globalization.CultureInfo culture)
  {
    bool result = false;
    switch (Comparison)...
    return result;
  } 
  ...
}

You can also do this by inheriting BindableObject and implementing bindable properties, you may need to do that if the binding context isn't carried into the resources. If that's the case you can set it from code behind once in the constructor, after the Initialize method is called.

Your xaml would look like this:

..
<ResourceDictionary>
  <myPrefix:CompareConverter x:Key="compareToY" Comparison="Equals" CompareTo="{Binding... }"/>
</ResourceDictionary>
...
<Control Value="{Binding X, Converter={StaticResource compareToY}}"/>

It may take a bit of tweaking by the result should be cleaner than multi-bindings

Solution 3

I was struggling with the same problem and not getting the data that i wanted. You can't bind to a "converterParameter", thats just how its made at the current date. But i really wanted to get some kind of data sent to the parameter. so i found a simple yet working solution and i hope it could work for you aswell. Start with giving CompareTo a x:Name="CompareTo" or whatever you want to call it.

         <Element
          Attribute="{Binding Value,
          Converter={StaticResource EqualityConverter},
          ConverterParameter={x:reference CompareTo}}" />

By doing x:reference its actually sending some data now, you just have to grab it. For me the value i needed was the "string" value so that i could do certain "If" statements. So you could do something similar to:

    if(CompareTo == "myCoolString")
    {
      Value = "Well i guess i'm not so cool!"
    }

This is how i got my data from the parameter:

   public class MyConverter : IValueConverter
    {

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (parameter != null)
        {
            try
            {
                var image = parameter as Image;
                var src = image.Source as FileImageSource;

                if (src.File.ToString() == "coolimage.png")
                {
                    return "thumbsup.png";
                }
            }
            catch
            {
            }
        } 
    }

In my case i was working with and image and needed the to know if one image was "A" then "B" needed to change into image "C". This should work with other objects aswell. With a little luck this will get you somewhat closer to a kind of simplistic "Multibinding" and answer.

Hope this was helpful as its my first ever post on Stackoverflow!

Share:
20,818
Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin almost 2 years

    I'm trying to use a value binding as converter parameter as shown in the code snippet below:

    <Element
      Attribute="{Binding Value,
                  Converter={StaticResource EqualityConverter},
                  ConverterParameter={Binding CompareTo}}" />
    

    The problem is, that the EqualityConverter::Convert() method is called with an instance of Binding as converter parameter (CompareTo) rather than the concrete value of the binding.

    Is there a smarter way to solve it? I could obviously provide the converted property in my view model, but I would like to know if there is a similar working solution to the above one.