2

起動時に双方向バインディングが有効になっているスライダーがあります。しかし、それらを動かすと、動きがスムーズではありません。そのため、Thumbs.DragStarted イベントが呼び出された後にバインディング モードを twoway から onewaytosource に変更することにしましたが、これにより値が 1 から 0 にすぐに変更されます。

私の質問は次のとおりです。新しいバインディング中にスライダーが値を変更しないようにするにはどうすればよいですか?

私のコードビハインドは以下です。

    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);
        }
    }
4

2 に答える 2

1

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);
于 2013-09-03T10:29:39.460 に答える
0

すべてがシンプルでした。スライダーの値を保存し、新しいバインディングが設定された後に復元するだけです。

于 2013-09-04T12:49:29.333 に答える