WPF binding on Slider does not update on Maximum change
combobox1.SelectedItem
is bound toSelectedItemProperty
.- The when
SelectedItemProperty
is set,MaxValueProperty
is calculated MaxValueProperty
is bound toslider1.Maximum
slider1.Value
is bound toSliderValueProperty
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, becauseMaxValueProperty
was changed,slider1.Value
is set toslider1.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>
精彩评论