WPF 之事件綁定(八)


一、System.Windows.Interactivity 的使用

對於 Button 等控件,在 MVVM 中我們能通過 Command 綁定解決 Click 事件,具體如下:

    <Button Margin="10" Height="50" Content="Clear" Command="{Binding Path=Clear}"></Button>

此時,當我們單擊 Clear 按鈕時,會執行 “Clear“ 命令。若我們需要傳遞參數,則使用 CommandParameter,如下所示傳遞:

    <Button Margin="10" Height="50" Content="Clear" Command="{Binding Path=Clear}" CommandParameter="{Binding Path=Student}"></Button>

那當我們使用 Button 的 其他事件,例如MouseMove 事件呢?甚至 TextBox 控件沒有 Command 屬性, 該如何使用 Command 呢?

這就需要我們通過 Nuget 添加 “System.Windows.Interactivity” 包后,引入如下命名控件:

 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

例如,我們實現一個 TextBox的 TextChanged事件,當文本內容發生變化,彈出踢提示信息:

  <TextBox  Height="50" VerticalContentAlignment="Center" Margin="10" BorderBrush="Black" >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="TextChanged">
                    <i:InvokeCommandAction Command="{Binding DisplayMessage}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBox>

二、帶事件參數(EventArgs)的事件綁定

​ 上面介紹的事件綁定並不足以應對所有的情況,因為很多情況下我們還需要從事件的EventArgs中獲取數據,例如從MouseMove事件參數中獲取鼠標位置和按鍵狀態等。但InvokeCommandAction在未對CommandParameter綁定的情況下給Execute方法傳遞的參數為null。因此我們需要自己寫一個類來處理事件到命令的綁定。自定義 EventCommand 如下所示:

  class EventCommand : TriggerAction<DependencyObject>
    {

        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Command.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.Register("Command", typeof(ICommand), typeof(EventCommand), new PropertyMetadata(null));



        public object CommandParameter
        {
            get { return (object)GetValue(CommandParameterProperty); }
            set { SetValue(CommandParameterProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CommandParameter.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.Register("CommandParameter", typeof(object), typeof(EventCommand), new PropertyMetadata(null));



        protected override void Invoke(object parameter)
        {
            if (CommandParameter != null)
            {
                parameter = CommandParameter;
            }
            Command?.Execute(parameter);
        }
    }

例如,我們要實現對一個 TextBox 鼠標位置信息的獲取,具體綁定如下:

   <TextBox Height="150" Margin="10" Background="LightSteelBlue" Text="獲取鼠標位置" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" >
          <i:Interaction.Triggers>
              <i:EventTrigger EventName="MouseMove">
                  <local:EventCommand Command="{Binding GetPositionCommand}"></local:EventCommand>
              </i:EventTrigger>
          </i:Interaction.Triggers>
        </TextBox>

如此,ViewModel 的綁定命令就可以收到事件參數了:

      public ICommand GetPositionCommand { get; set; }
        private void GetPositionCommandExecute(object obj)
        {
            var args = obj as MouseEventArgs;
            if (args != null)
            {
                var pos = args.GetPosition(args.Device.Target);
                CurrentPosition = new Position()
                {
                    X = pos.X,
                    Y = pos.Y,
                };
            }
        }
        public WindowVM()
        {
            _position = new Position();
            GetPositionCommand=new RelayCommand(GetPositionCommandExecute, null);
        }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM