Take the 2-minute tour ×

In a legacy component I was troubleshooting, I stumbled across the following:

<CustomControls:DiscreteSlider x:Name="slider" Grid.Column="1">
    <MultiBinding Mode="TwoWay">
        <WinConverters:FeatureConverter />
      <Binding Path="Enabled" />
      <Binding Path="Value" />
      <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:DialogBase}}" />

This was a binding for a slider-like user control ("DiscreteSlider") that had the following code in code behind (control actually wraps a slider and performs operations on it):

public static readonly DependencyProperty ValueProperty =
        new FrameworkPropertyMetadata((double)0.0,
            new PropertyChangedCallback(OnValueChanged)));

public double Value
    get { return (double)GetValue(ValueProperty); }
    set { SetValue(ValueProperty, value); }

private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    DiscreteSlider obj = d as DiscreteSlider;
    if (obj != null)
        double oldValue = (double)e.OldValue;
        double newValue = (double)e.NewValue;
        obj._Slider.Value = newValue;
        obj.DoValueChanged(oldValue, newValue);


private void Thumb_DragCompleted(object sender, DragCompletedEventArgs e)
    _IsUserChange = true;
    Value = _Slider.Value;

What had been happening was that the value was not actually updating. The _Slider.Value was set properly, but after Value was assigned to it, Value was unchanged.

The only thing that had changed about/around this code was that we had gone from .NET 3.5 to 4.0. I was able to "fix" this by removing Mode="TwoWay" from the multibinding in XAML. But, I cannot stand programming by coincidence. I want to know why this happened.

Is anyone aware of an explanation as to why this XAML and code would be functional in 3.5 and not in 4? If you can think of some other potential explanation, I'm open to hear it, but neither the XAML nor the code behind of that control has been changed since it was deployed (and functional) in 3.5.


Here is the code for the value converter in question:

public class FeatureConverter : IMultiValueConverter
    private bool Enabled = true;
    private const int MinValue = MelodyConst.MinValue;

        if (values == null || values.Count() < 2) return null;

        double returnValue = MelodyConst.DisabledValue;

        bool featureEnabled;
        Int32 featureValue;

        bool.TryParse(values[0].ToString(), out featureEnabled);
        Int32.TryParse(values[1].ToString(), out featureValue);

        Enabled = featureEnabled;

        if (!featureEnabled)
            return returnValue;
            returnValue = (double)(featureValue);

        return returnValue;

        Int32 newSliderValue;
        Int32.TryParse(value.ToString(), out newSliderValue);

        object[] lsValues = new object[2];
        lsValues[0] = (object)Enabled;
        lsValues[1] = newSliderValue;

        return lsValues;
share|improve this question
You did have the FeatureConverter installed again? –  Henk Holterman Feb 16 '12 at 22:26
Yes - the converter was there and behaving appropriately, when hit in debugger. –  Erik Dietrich Feb 16 '12 at 23:03
Can we see the code for FeatureConverter? –  Phil Feb 20 '12 at 16:48
I just posted the converter's code. Glancing through quickly, the only domain specific thing I see is MelodyConst, and all that represents is some hard-coded min value that gets applied to the slider when the slider is disabled (general idea is that slider can be modified normally, but if the object it represents is 'disabled' the slider goes to its minimum value and is disabled) –  Erik Dietrich Feb 20 '12 at 17:58
The Value property bound the multi-converter is a double, but you do an int.Parse in the converter, so this nearly always fails. Shouldn't you be doing double.Parse(...) and casting to an int? –  Phil Feb 20 '12 at 18:54
show 3 more comments

3 Answers

up vote 3 down vote accepted

I have not personly experienced the problem that you ran into. But according to ScottGu's blog the Xaml/Baml parser has been replaced with a new one in WPF 4.0. So it is entirely possible there are some breaking changes between 3.5 and 4.0, though I did not find any specific references to your problem.

From above blog.

WPF 4 has replaced its implementation of XamlReader.Load(), BAML loading, Control & DataTemplates functionality with a new engine built on top of the new System.Xaml.dll. As part of this effort, we’ve fixed many bugs and made many functionality improvements.

share|improve this answer
I think now we're talking. Looking at the post, I neglected to mention that XAML in question occurs in a data template. I didn't really think it mattered, but based on what you've posted here about new Control/Data Template functionality, I think we're narrowing it down. –  Erik Dietrich Feb 22 '12 at 18:38
Well, I actually spent all day looking into this since my 'fix' took care of part of the problem, but not all, as it turns out. The exact reason is still unclear to me, but it's not going to matter in the end as, at this point, my course of action is likely going to be gutting this portion and refactoring its dependencies. This post was most instrumental in informing my scorched earth decision, so I'm marking it as the answer. With parser revamped a bizarre and awkward corner case like this is probably best reworked according to current best practices. Thanks to you and all others. –  Erik Dietrich Feb 23 '12 at 0:16
You are welcome, it is always frustrating when code that used to work breaks because of changes outside of our control. –  Mark Hall Feb 23 '12 at 1:17
add comment

I think this might be happening because you have three values bound to the MultiValue converter but in the ConvertBack method you are returning only two values; can you try removing third binding as you are not using it anyways.

Something might have changed in 4.0 which causes the bindings to fail if converter doesn't returns correct number of params, but I am not sure about this.

share|improve this answer
Good catch, but I deleted the extra parameter and still no joy. –  Erik Dietrich Feb 21 '12 at 18:50
Thanks for giving it a try Erik; Can you post the code for your Enabled property too, is it having a public setter! –  akjoshi Feb 22 '12 at 6:31
add comment

I haven't used XAML, but your code uses a tag of MultiBinding.Converter and I have always seen that as an attribute, i.e. MultiBinding Converter=""

share|improve this answer
Declaring it with the period delimiter allows you to specify the attribute in tag format, rather than just as a string in quotes. It's generally used anywhere that the value of the attribute is complex and/or nested. In the case above, there'd be no good way to specify the multiple binding paths with a single string attribute. Thanks for the thought, though. :) –  Erik Dietrich Feb 22 '12 at 6:22
Not arguing, as I'm definitely ignorant, but I've seen examples with multiple binding paths as different elements, but a single converter. Probably this is just me not understanding the terms correctly...and I've been unable to find anything specific on the difference in syntax, just that sometimes it does make a difference. –  jmoreno Feb 22 '12 at 6:56
add comment

Your Answer


