• 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>

    效果如下:

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

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

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

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

    (1)下载或者复制C:Program Files (x86)Microsoft SDKsExpressionBlend.NETFrameworkv4.0LibrariesSystem.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呢?

     
  • 相关阅读:
    Git 分布式版本控制的常见命令
    Redis数据库的学习及与python的交互
    Flask项目中数据库迁移的使用
    Flask项目中的蓝图简介及使用方式
    window环境下创建Flask项目需要安装常见模块命令
    Flask数据库常见关系模板代码
    Flask-WTF表单
    SCRF的简介及防护手段
    【题目】求n以内的素数个数
    【题目】英文字符进行频率的统计,直方图输出
  • 原文地址:https://www.cnblogs.com/DreamRecorder/p/9850001.html
Copyright © 2020-2023  润新知