10

Here's a little XAML fragment. You will see

<StackPanel>
     <TextBox x:Name="txtValue">250</TextBox>
     <Slider x:Name="slide" 
             Value="{Binding ElementName=txtValue, Path=Text, 
                             Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" 
            Minimum="0" Maximum="500"></Slider>
</StackPanel>
  1. when you change the textbox value, the slider updates
  2. If you change the slider value explicitly, the previous behavior breaks a.k.a. stops working.

If I remove the Mode=OneWay set directive, (defaults to two-way) everything works perfectly.

Why is this happening?

akjoshi
  • 15,374
  • 13
  • 103
  • 121
Gishu
  • 134,492
  • 47
  • 225
  • 308

3 Answers3

13

Use mode=TwoWay and set the UpdateSourceTrigger=Explicit.

Barry Kaye
  • 7,682
  • 6
  • 42
  • 64
h4444
  • 131
  • 1
  • 2
2

Your data binding is not broken but deactivated (http://en.wikipedia.org/wiki/Euphemism):

System.Windows.Data Warning: 75 : BindingExpression (hash=52697953): Deactivate
System.Windows.Data Warning: 99 : BindingExpression (hash=52697953): Replace item at level 0 with {NullDataItem}
System.Windows.Data Warning: 59 : BindingExpression (hash=52697953): Detach

Setting the trace level to high will produce this message in the VS output window in case you move the slider:

<Slider xmlns:trace="clr-namespace:System.Diagnostics;assembly=WindowsBase"
        Value="{Binding trace:PresentationTraceSources.TraceLevel=High,
            ElementName=txtValue, Path=Text, Mode=OneWay,
            UpdateSourceTrigger=PropertyChanged}"
        Minimum="0" Maximum="500"></Slider>
Alex Janzik
  • 3,742
  • 1
  • 20
  • 17
  • 5
    Why does it detach? It kind of defeats the purpose of one-way binding if doing something like moving the thumb on the bound control deactivates or unhooks the binding. By broken, I meant the expected behavior isn't seen anymore. – Gishu Sep 09 '09 at 04:48
  • That's the way it is implemented :-( If it does not meet your needs don't use WPF data binding. – Alex Janzik Sep 09 '09 at 07:18
0

If you create a control which inherits from Slider, then override the Value property and use DependencyObject.SetCurrentValue when changing the value rather than DependencyOpbject.SetValue, then your databindings will be preserved when changing the values programmatically.

Sorry this isn't particularly exhaustive, will update this answer to include a basic implementation of this at a later date.

Alternatively, a UserControl which contains both the textbox and the slider would make for a very reusable implementation, in which you could bind them both to the same custom dependencyproperty, make the binding oneway, hijack the valuechanged event of the slider, set e.Handled = true, and call the SetCurrentValue function from that.

IAmJersh
  • 742
  • 8
  • 25