سؤال

I seem to have this same problem with any implementation of a RangeSlider (or more simply, a slider with 2 thumbs).

I want to bind both thumbs to a datacontext and have that binding be 2-way. Unfortunately, I only seem to be able to bind to SET the sliders' positions. If I move them with the mouse they lose their binding.

I have used several range sliders, but to keep it simple, in this example I'm using one from thejoyofcode.com. (I haven't modified it, so I'm not including it here just now, but I can if it helps). I consume it using the XAML below, with the intention of letting the framework sliders (named "MinSlider" and "MaxSlider") also be bound to the same datasources.

When I move the framework sliders, all of the bound items follow them, including the range slider, but then if I move one of the thumbs on the range slider it does not update the datasource or the framework slider.

My Window XAML...

        <Separator></Separator>

        <controls:RangeSlider x:Name="Slider" 
                              Minimum="10"
                              Maximum="20"
                              LowerValue="{Binding Min, UpdateSourceTrigger=PropertyChanged}"
                              UpperValue="{Binding Max, UpdateSourceTrigger=PropertyChanged}"
                              />
        <TextBlock Text="{Binding LowerValue, ElementName=Slider}"/>
        <TextBlock Text="{Binding UpperValue, ElementName=Slider}"/>

        <Separator></Separator>

        <Slider x:Name="MaxSlider" Minimum="10" Maximum="20" Value="{Binding Max}"/>
        <TextBlock Text="{Binding Value, ElementName=MaxSlider}"/>

        <Separator></Separator>

        <TextBlock Text="{Binding Min}"/>
        <TextBlock Text="{Binding Max}"/>
    </StackPanel>
</Window>

...and the MySource class...

public class MySource : INotifyPropertyChanged
{
    private double _min;
    public double Min
    {
        get { return _min; }
        set
        {
            _min = value;
            RaisePropertyChanged("Min");
        }
    }

    private double _max;
    public double Max
    {
        get { return _max; }
        set
        {
            _max = value;
            RaisePropertyChanged("Max");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        var handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, e);
        }
    }

    protected void RaisePropertyChanged(String propertyName)
    {
        OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }

}
هل كانت مفيدة؟

المحلول

It is because you need to set the BindingMode=TwoWay in your Bindings.

A Control author can make this the default behavior (the WPF Slider does this), but unless the dependency property is registered with FrameworkPropertyMetadata.BindsTwoWayByDefault, then OneWay is the mode that will be used.

MSDN explains BindingModes.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top