首页 > 代码库 > (WPF, MVVM) Slider Binding.

(WPF, MVVM) Slider Binding.

对于Button的Command的绑定可以通过实现ICommand接口来进行,但是Slider并没有Command属性。

另外如果要实现MVVM模式的话,需要将一些Method和Slider的Event进行绑定,如何进行呢?

(对于UIElement的一些Event进行绑定一定有一些通用的方法,目前还没有深入研究。)

 

首先,Slider Value的绑定是很简单的, 绑定Slider的Value属性即可。

(1)ViewModel

    public class SliderViewModel : ViewModelBase    {        private string selectedValue;        public SliderViewModel()        {        }        public string SelectedValue        {            get            {                return this.selectedValue;            }            set            {                if (this.selectedValue != value)                {                    this.selectedValue =http://www.mamicode.com/ value;                    base.OnPropertyChanged("SelectedValue");                 }            }        }    }

(2) View, 设定 DataContext 为ViewModel, 绑定SelectValue到 Slider的Value 和TextBlock的Text属性上。

这样当拖动Slider时,Slider的值会传给SelectedValue, 然后SelectValue会传给TexBlock上。

 x:Class="WpfApplication2.View.SliderView"             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"              xmlns:vm="clr-namespace:WpfApplication2.ViewModel"             mc:Ignorable="d"              d:DesignHeight="300" d:DesignWidth="300">    <UserControl.DataContext>        <vm:SliderViewModel />    </UserControl.DataContext>    <Grid>        <Slider HorizontalAlignment="Left"                Margin="28,102,0,0"                VerticalAlignment="Top"                Width="158"                 Minimum="0"                Maximum="100"                Value="{Binding SelectedValue}"/>        <TextBlock HorizontalAlignment="Left"                   Margin="203,102,0,0"                   TextWrapping="Wrap"                   Text="{Binding SelectedValue}"                   VerticalAlignment="Top" />    </Grid></UserControl>

效果如下:

如果不想显示double值,可以设定Slider的属性。

                TickFrequency="1"                IsSnapToTickEnabled="True"                TickPlacement="None" />

其次, 当用鼠标或者键盘移动滑块结束的时候,需要进行一些处理。如果不用MVVM的方式的话,可以在Slider的Event里面增加处理。

用MVVM的话,就稍微麻烦一些。

(1)下载或者复制C:\Program Files (x86)\Microsoft SDKs\Expression\Blend\.NETFramework\v4.0\Libraries\System.Windows.Interactivity.dll

        在工程中Reference 这个dll,命名空间里面增加:using System.Windows.Interactivity

 (2)新写个SliderValueChangedBehavior 继承Behavior<Slider>

    /// <summary>    /// Helps find the user-selected value of a slider only when the keyboard/mouse gesture has ended.    /// </summary>    public class SliderValueChangedBehavior : Behavior<Slider>    {        /// <summary>        /// Keys down.        /// </summary>        private int keysDown;        /// <summary>        /// Indicate whether to capture the value on latest key up.        /// </summary>        private bool applyKeyUpValue;        #region Dependency property Value        /// <summary>        /// DataBindable value.        /// </summary>        public double Value        {            get { return (double)GetValue(ValueProperty); }            set { SetValue(ValueProperty, value); }        }        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(            "Value",            typeof(double),            typeof(SliderValueChangedBehavior),            new PropertyMetadata(default(double), OnValuePropertyChanged));        #endregion        #region Dependency property Value        /// <summary>        /// DataBindable Command        /// </summary>        public ICommand Command        {            get { return (ICommand)GetValue(CommandProperty); }            set { SetValue(CommandProperty, value); }        }        public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(            "Command",            typeof(ICommand),            typeof(SliderValueChangedBehavior),            new PropertyMetadata(null));        #endregion        /// <summary>        /// On behavior attached.        /// </summary>        protected override void OnAttached()        {            this.AssociatedObject.KeyUp += this.OnKeyUp;            this.AssociatedObject.KeyDown += this.OnKeyDown;            this.AssociatedObject.ValueChanged += this.OnValueChanged;            base.OnAttached();        }        /// <summary>        /// On behavior detaching.        /// </summary>        protected override void OnDetaching()        {            base.OnDetaching();            this.AssociatedObject.KeyUp -= this.OnKeyUp;            this.AssociatedObject.KeyDown -= this.OnKeyDown;            this.AssociatedObject.ValueChanged -= this.OnValueChanged;        }        /// <summary>        /// On Value dependency property change.        /// </summary>        private static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)        {            var me = (SliderValueChangedBehavior)d;            if (me.AssociatedObject != null)                me.Value = (double)e.NewValue;        }        /// <summary>        /// Occurs when the slider‘s value change.        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)        {            if (Mouse.Captured != null)            {                this.AssociatedObject.LostMouseCapture += this.OnLostMouseCapture;            }            else if (this.keysDown != 0)            {                this.applyKeyUpValue = http://www.mamicode.com/true;            }            else            {                this.ApplyValue();            }        }        private void OnLostMouseCapture(object sender, MouseEventArgs e)        {            this.AssociatedObject.LostMouseCapture -= this.OnLostMouseCapture;            this.ApplyValue();        }        private void OnKeyUp(object sender, KeyEventArgs e)        {            if (this.keysDown-- != 0)            {                this.ApplyValue();            }        }        private void OnKeyDown(object sender, KeyEventArgs e)        {            this.keysDown++;        }        /// <summary>        /// Applies the current value in the Value dependency property and raises the command.        /// </summary>        private void ApplyValue()        {            this.Value = http://www.mamicode.com/this.AssociatedObject.Value;            if (this.Command != null)                this.Command.Execute(this.Value);        }    }

 (3) 在View中为Slider的行为添加Command

            <i:Interaction.Behaviors>                <helper:SliderValueChangedBehavior Command="{Binding ValueChangedCommand}"                                                  />            </i:Interaction.Behaviors>

(4)在ViewModel中实现当Slider值个改变的时候进行一些处理。

        public ICommand ValueChangedCommand        {            get            {                if (this.valueChangedCommmand == null)                {                    this.valueChangedCommmand = new RelayCommand(                        param => this.PopValue(),                        null);                }                return this.valueChangedCommmand;             }        }        private void PopValue()        {            MessageBox.Show(String.Format("Selected value is {0}", this.selectedValue));         }

最后,进行调试,发现ValueChangedCommand当每次Silder值变更的时候都会被执行

那么如何实现最后一次值变更时,才执行Command呢?