开发者

WPF binding on Slider does not update on Maximum change

开发者 https://www.devze.com 2023-02-17 15:24 出处:网络
combobox1.SelectedItem is bound to SelectedItemProperty. The when SelectedItemProperty is set, MaxValueProperty is calculated
  • combobox1.SelectedItem is bound to SelectedItemProperty.
  • The when SelectedItemProperty is set, MaxValueProperty is calculated
  • MaxValueProperty is bound to slider1.Maximum

  • slider1.Value is bound to SliderValueProperty

These all work fine, except when combobox1.SelectedItem changes, and MaxValueProperty is calculated, and comes out less than SliderValueProperty.

In the View:

  • slider1.Maximum is updated, because MaxValueProperty was changed,
  • slider1.Value is set to slider1.Maximum as default behavior of a slider when the max changes to less than the value.

However, when this happens, SliderValueProperty does not get up开发者_开发知识库dated to the new slider1.Value

<Slider Name="slider1" Maximum="{Binding Path=MaxValueProperty, Mode=TwoWay}" Value="{Binding Path=SliderValueProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

I know that slider1.Value is getting changed, because I have a label bound to it, and the label changes

<Label Content="{Binding ElementName=slider, Path=Value, Converter={StaticResource NumberToStringConverter}}" />

How can I ensure the binding is updated?


Rather than relying on the default behavior of the slider and a TwoWay binding, raise a PropertyChanged event after you compute the new maximum in your SelectedItemProperty setter, first on "SliderValueProperty" using the new maximum, and then second on "MaxValueProperty". Do your computations on your private backing fields, not on the public properties.

This will cause the system to adjust first the value of the slider, and then the maxvalue, and it should move the slider position for you.

Set the binding mode on slider1's Maximum to OneWay, as well; I think that will do the trick.

As follows with a viewmodel like this:

Class viewmodel
    Implements INotifyPropertyChanged
Private _selectedItemProperty As ComboBoxItem
Public Property SelectedItemProperty As ComboBoxItem

    Get
        Return _selectedItemProperty
    End Get
    Set(value As ComboBoxItem)
        MaxValueProperty = value.Content
        If _sliderValueProperty > _maxValueProperty Then _sliderValueProperty = _maxValueProperty
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("MaxValueProperty"))
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("SliderValueProperty"))
    End Set
End Property
Private _maxValueProperty, _sliderValueProperty as Single
Public Property MaxValueProperty As Single ' with setter that will raise PropertyChanged and use the backing field

'...

Public Property SliderValueProperty As Single ' with a setter that will raise PropertyChanged and use the backing field

'...

End Class

And the XAML looks a little like this:

    <Grid>
    <ComboBox Height="23" HorizontalAlignment="Left" Margin="40,38,0,0" Name="ComboBox1" VerticalAlignment="Top" Width="120" SelectedItem="{Binding SelectedItemProperty}">
        <ComboBoxItem Content="50" />
        <ComboBoxItem Content="30" />
        <ComboBoxItem Content="10" />
    </ComboBox>
    <Slider Name="slider1" Height="23" HorizontalAlignment="Left" Margin="87,135,0,0"  VerticalAlignment="Top" Width="100" Value="{Binding SliderValueProperty}" Minimum="1" Maximum="{Binding MaxValueProperty}" />
    <Label Content="{Binding ElementName=slider1, Path=Value}" Margin="40,174,293,96" />

</Grid>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号