Reputation: 344
I have sliders with twoway binding enabled at startup. But when I move them, moving is not smooth enought. So, I decide to change binding mode from twoway to onewaytosource after Thumbs.DragStarted event is called, but this lead to immediate changing value from 1 to 0.
My question is: How to prevent slider from changing its value during new binding?
My code behind is below.
private void SliderCameraZ_OnDragStarted(object sender, DragStartedEventArgs e)
{
try
{
BindingExpression bindingExpression = ((Slider) sender).GetBindingExpression(Slider.ValueProperty);
BindingOperations.ClearBinding((Slider) sender, Slider.ValueProperty);
Binding binding = new Binding();
binding.Path = bindingExpression.ParentBinding.Path;
binding.Mode = BindingMode.OneWayToSource;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
((Slider)sender).SetBinding(Slider.ValueProperty, binding);
}
catch (Exception exception)
{
MessageBox.Show(exception.Message + exception.StackTrace + exception.TargetSite);
}
}
Upvotes: 2
Views: 1379
Reputation: 344
All was simple. I just need to store value of slider and restore it after new binding is set.
Upvotes: 0
Reputation: 17063
In most cases it should be enough using the Delay
Property introduced in .Net 4.5 to reduce the update calls taking to much time. For a sample see Adding a delay to your binding updates to reduce noise:
<StackPanel>
<Slider x:Name="ValueSlider"
Minimum="0" Maximum="100"
Margin="20" Height="25"
Value="{Binding ElementName=ValueText, Delay=500, Path=Text, Mode=TwoWay}" />
<TextBox x:Name="ValueText" Text="50"
Width="100" Height="50" FontSize="20"
HorizontalAlignment="Center" />
</StackPanel>
If you really need an immediate update you can still call BindingExpression.UpdateSource Method respective BindingExpression.UpdateTarget Method:
BindingExpression bindingExpression = ValueSlider.GetBindingExpression(Slider.ValueProperty);
bindingExpression.UpdateSource();
But your question is about preventing the value change after changing the binding mode. I've noticed that this only appears with BindingMode.OneWayToSource
. Maybe you can avoid this by changing the sample above to
<StackPanel>
<Slider x:Name="ValueSlider"
Minimum="0" Maximum="100"
Margin="20" Height="25"
Value="50" />
<TextBox x:Name="ValueText"
Text="{Binding ElementName=ValueSlider, Path=Value, Mode=TwoWay}"
Width="100" Height="50" FontSize="20"
HorizontalAlignment="Center" />
</StackPanel>
Now the TextBox
is bound to Slider
and not the other way round. BindingMode.OneWayToSource
would be BindingMode.OneWay
and a binding change shouldn't cause a value change.
BindingExpression bindingExpression = ValueText.GetBindingExpression(TextBox.TextProperty);
Binding binding = new Binding();
binding.Source = bindingExpression.DataItem;
binding.Path = bindingExpression.ParentBinding.Path;
binding.Mode = BindingMode.OneWay;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
ValueText.SetBinding(TextBox.TextProperty, binding);
Upvotes: 1