I’m binding the value of a Slider to an integer property that represents the volume on a networked device. This network request takes a little time (usually <100 ms), and somehow causes the Slider to feel choppy.
Here’s my oversimplified code to clarify:
Private _playbackVolume As Integer
Private _deviceForDemonstrationPurposes As New Device
Public Property PlaybackVolume As Integer
Get
Return _playbackVolume
End Get
Set(value As Integer)
_deviceForDemonstrationPurposes.Volume = value
End Set
End Property
Friend Sub UpdateVolume(volume As Integer)
' this is called by the instance of Device whenever its volume changes.
_playbackVolume = volume
RaisePropertyChanged("PlaybackVolume") ' INotifyPropertyChanged implementation.
End Sub
Binding to the PlaybackVolume property will cause the setter to fire while still dragging the thumb. Because of the network latency issue, the slider is locked for however many miliseconds it takes for the request to complete.
What is considered the best approach to make the slider feel smooth again?
Consider decoupling the UI (the slider) from the component that actually gets and sets the volume. When the slider value changes, it should queue a request to change the volume to the new value, but continue on its merry way. Only set the slider position from the device’s volume when you first draw or refresh the UI from the device; you can probably get away with implying the volume is set at what the user dragged it to.
Edit
(Full disclosure: I’ve not done a lot of WPF myself)
So after looking into a practical example of what I mean, I learned about UpdateSourceTrigger, which provides you a number of ways to trigger a bound element to rebind. I found this example, which combines
UpdateSourceTriggerwith a timer. The idea being that dragging the slider begins a brief timeout, after whichUpdateSourceTriggeris told to update its databinding. The trick is that the timeout is interrupted as the user continues to change the slider value. So, the net effect is that your device wouldn’t actually be updated with the slider value until the user finally settled on the value they wanted, which should give you the smooth, responsive UI while sliding you are looking for. You can still keep the live update of the slider from the device as you have now. I hope that makes things a bit clearer.