(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 = 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>

效果如下:

(WPF, MVVM) Slider Binding.

如果不想显示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 = 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 = 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呢?

你可能感兴趣的:(slider)