0

I've generated a CustomControl that includes (among other elements) a TextBox. Binding a value works:

(Code-Snippet from Generic.xaml)

<TextBox Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ParameterValue, Mode=TwoWay }"/>

Now, i wanted to add some ValueConverter to my Binding, so i implemented a ParameterConverter. Using the Converter works also (so far), i can see the value being converted.

<TextBox Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ParameterValue, Mode=TwoWay, Converter={StaticResource ParameterConverter}}"/>

Now as my converters logic got more complex, i wanted to use the parameter Property on my ParameterConverter. But unfortunately, as parameter is no DependencyProperty, i cannot bind anything to it. I've registered some DependencyProperty in my CustomControl, but i wasn't able to bind it to the ConverterParameter in my XAML. The desired ConverterParameter i want to bind to is a Enum called ParameterUnit. What i expected the result should look like is something like this:

<TextBox Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ParameterValue, Mode=TwoWay, Converter={StaticResource ParameterConverter}, ConverterParameter='{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ParameterUnit}'}"/>

I've got a solution, but looks really nasty and violates the CCD-principles i'd like to follow always as far as possible. I added some code in my ParameterControl-Class:

public ParameterControl()
    {
        _textBox = (TextBox)Template.FindName("ParameterValueTextBox", this);
        this.Loaded += (s, e) => SetupControl();
    }

public void SetupControl()
    {
        var textBinding = new Binding();
        textBinding.RelativeSource = RelativeSource.TemplatedParent;
        textBinding.Path = new PropertyPath("ParameterValue");
        textBinding.Converter = new ParameterToHumanFormatConverter();
        textBinding.ConverterParameter = ParameterUnit;
        textBinding.Mode = BindingMode.TwoWay;
        textBinding.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;  
        _textBox.SetBinding(TextBox.TextProperty, textBinding);
    }

Isn't there no better, cleaner and easier solution? I just can't believe there is no way to bind a ConverterParameter.

ElGaucho
  • 408
  • 2
  • 14

1 Answers1

1

If you need more than one value binding just use a MultiBinding.

H.B.
  • 166,899
  • 29
  • 327
  • 400
  • I know i could use a MultiBinding if i wanted to pass more than one value. But is this the most common way to pass several arguments to a ValueConverter? Then i really don't understand what for the `parameter` argument in a `IValueConverter` was introduced. – ElGaucho Dec 02 '11 at 08:19
  • 1
    @ElGaucho: It's for static parameters that do not change. – H.B. Dec 02 '11 at 08:23
  • Perhaps i'm getting something wrong using a MultiValueConverter, but how can I implement the `ConvertBack` Method when i got no information about the `parameter`on which my convert method depends? It's something similar to convert "1000" (Value) and "grams" (parameter) to "1" (Kilogram). On the `ConvertBack`method, i gain only informations about the "1", but nothing about the parameter ("Is it kilogram? Is the value measured in feet? Or shall i convert pressure, time... ?") – ElGaucho Dec 02 '11 at 09:25
  • @ElGaucho: Well, do you need to convert back? If not you can just throw a NotSupportedException and be done with it. – H.B. Dec 02 '11 at 17:00
  • I wouldn't ask if i didn't need it. I need it, because it is used on a Textbox.Text Property. The Converter should be able to convert back (0.1 km --> 1000 m for example). – ElGaucho Dec 05 '11 at 15:34
  • @ElGaucho: Then you need to make sure that your initial conversion is reversible, otherwise you cannot do it, makes sense, doesn't it? – H.B. Dec 05 '11 at 20:59
  • And _just_ for this case i want to use the parameter argument, because this parameter is (for my use of my converter) always static, but can defer from the usage of the converter. So back to my initial question: Can't i bind the parameter argument in any way? Perhaps by binding Mode=OneTime or some other fancy stuff. – ElGaucho Dec 06 '11 at 10:50
  • 1
    You can set the parameter to a subclass of `DependencyObject` which then can host dependency properties which can be bound, but there is a break in the tree so you do not have a `DataContext` and you cannot use `ElementName` or `RelativeSource` either, see [this answer](http://stackoverflow.com/questions/8245116/bind-to-datacontext-property-inside-inline-array-delcaration/8247368#8247368) for possible workarounds in such a context. – H.B. Dec 06 '11 at 10:59