如何在 MVVM 中处理事件时发送事件处理程序的第二个参数



我有一个树视图。使用代码隐藏方法处理事件TreeViewItem.ExpandedtreeView_Expanded(object sender, RoutedEventArgs e)有两个参数:

XAML:

<TreeView Name="treeView" TreeViewItem.Expanded="treeView_Expanded"/> 

代码隐藏:

private void treeView_Expanded(object sender, RoutedEventArgs e)
{ 
     //***I take THE SECOND PARAMETER to work ***
     TreeViewItem item = e.Source as TreeViewItem;
}

但是,当我使用 MVVM 规则处理TreeViewItem.Expanded事件时,我总是采用第一个参数object sender。但我想RoutedEventArgs e第二个参数:

XAML:

<TreeView ItemsSource="{Binding Person}">
   <i:Interaction.Triggers>
      <helper:RoutedEventTrigger RoutedEvent="TreeViewItem.Expanded">
         <prism:InvokeCommandAction Command="{Binding GetNewTreeViewItemCommand}"/>
      </helper:RoutedEventTrigger>
   </i:Interaction.Triggers>
</TreeView>

视图模型:

public DelegateCommand<RoutedEventArgs> GetNewTreeViewItemCommand { get; set; }
public MainWindowViewModel()
{
   GetNewTreeViewItemCommand = new DelegateCommand<RoutedEventArgs>(LoadNewTreeViewITem);
}
private void LoadNewTreeViewITem(RoutedEventArgs e)
{
   //e is "object sender"(the FIRST parameter), but I want to take  
   //RoutedEventArgs e(the SECOND parameter)             
}           

MVVM 中处理事件时如何发送第二个参数?

您可以使用另一个 TriggerAction 在 VM 中调用命令,该命令也将传递参数:

<TreeView ItemsSource="{Binding Person}">
  <i:Interaction.Triggers>
     <helper:RoutedEventTrigger RoutedEvent="TreeViewItem.Expanded">
        <local:CustomCommandAction Command="{Binding GetNewTreeViewItemCommand}"/>
     </helper:RoutedEventTrigger>
  </i:Interaction.Triggers>

自定义命令操作

public sealed class CustomCommandAction : TriggerAction<DependencyObject>
{
    public static readonly DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter", typeof(object), typeof(CustomCommandAction), null);
    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
        "Command", typeof(ICommand), typeof(CustomCommandAction), null);
    public ICommand Command
    {
        get
        {
            return (ICommand)this.GetValue(CommandProperty);
        }
        set
        {
            this.SetValue(CommandProperty, value);
        }
    }
    public object CommandParameter
    {
        get
        {
            return this.GetValue(CommandParameterProperty);
        }
        set
        {
            this.SetValue(CommandParameterProperty, value);
        }
    }
    protected override void Invoke(object parameter)
    {
        if (this.AssociatedObject != null)
        {
            ICommand command = this.Command;
            if (command != null)
            {
                if (this.CommandParameter != null)
                {
                    if (command.CanExecute(this.CommandParameter))
                    {
                        command.Execute(this.CommandParameter);
                    }
                }
                else
                {
                    if (command.CanExecute(parameter))
                    {
                        command.Execute(parameter);
                    }
                }
            }
        }
    }
}

更新

XAML

    <TreeView ItemsSource="{Binding Person}" Grid.Row="1" >
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Path=Description}" />
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
        <i:Interaction.Triggers>
            <local:RoutedEventTrigger RoutedEvent="TreeViewItem.Expanded">
                <local:CustomCommandAction Command="{Binding GetNewTreeViewItemCommand}"/>
            </local:RoutedEventTrigger>
        </i:Interaction.Triggers>
    </TreeView>

虚拟机

    private ObservableCollection<Person> _people = new ObservableCollection<Person>();
    public ObservableCollection<Person> Person
    {
        get { return _people; }
    }

    private DelegateCommand _getNewTreeViewItemCommand = null;
    public ICommand GetNewTreeViewItemCommand { get { return _getNewTreeViewItemCommand; } }

    private void LoadNewTreeViewITem(object param)
    {
        var tuple = (Tuple<object, object>)param;
        object sender = tuple.Item1;
        RoutedEventArgs e = tuple.Item2 as RoutedEventArgs;
        System.Diagnostics.Debug.WriteLine(sender);
        System.Diagnostics.Debug.WriteLine(e.RoutedEvent);
    }
    public MainWindowViewModel()
    {
        _getNewTreeViewItemCommand = new DelegateCommand(LoadNewTreeViewITem, (o) => true);
        for (int i = 0; i < 10; i++)
        {
            var newPerson = new Person() { Description = i.ToString() };
            for (int j = 0; j < 10; j++)
            {
                newCode.Children.Add(new Person() { Description = i.ToString() + j.ToString() });
            }
            _people.Add(newCode);
        }
    }

public class Person
{
    public string Description { get; set; }
    public ObservableCollection<Person> Children { get; set; } = new ObservableCollection<Person>();
}

命令

public class DelegateCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Func<object, bool> _canExecute;
    public event EventHandler CanExecuteChanged;

    public DelegateCommand(Action<object> execute, Func<object, bool> canExecute)
    {
        _execute = execute;
        _canExecute = canExecute;
    }
    public bool CanExecute(object parameter)
    {
        return _canExecute(parameter);
    }
    public void Execute(object parameter)
    {
        _execute(parameter);
    }
}

路由事件触发器

public class RoutedEventTrigger : EventTriggerBase<DependencyObject>
{
    RoutedEvent _routedEvent;
    public RoutedEvent RoutedEvent
    {
        get { return _routedEvent; }
        set { _routedEvent = value; }
    }
    public RoutedEventTrigger()
    {
    }
    protected override void OnAttached()
    {
        Behavior behavior = base.AssociatedObject as Behavior;
        FrameworkElement associatedElement = base.AssociatedObject as FrameworkElement;
        if (behavior != null)
        {
            associatedElement = ((IAttachedObject)behavior).AssociatedObject as FrameworkElement;
        }
        if (associatedElement == null)
        {
            throw new ArgumentException("Routed Event trigger can only be associated to framework elements");
        }
        if (RoutedEvent != null)
        {
            associatedElement.AddHandler(RoutedEvent, new RoutedEventHandler(this.OnRoutedEvent));
        }
    }
    void OnRoutedEvent(object sender, RoutedEventArgs args)
    {
        base.OnEvent(args);
    }
    protected override string GetEventName()
    {
        return RoutedEvent.Name;
    }
}

自定义命令操作

public sealed class CustomCommandAction : TriggerAction<DependencyObject>
{
    public static readonly DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter", typeof(object), typeof(CustomCommandAction), null);
    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
        "Command", typeof(ICommand), typeof(CustomCommandAction), null);
    public ICommand Command
    {
        get
        {
            return (ICommand)this.GetValue(CommandProperty);
        }
        set
        {
            this.SetValue(CommandProperty, value);
        }
    }
    public object CommandParameter
    {
        get
        {
            return this.GetValue(CommandParameterProperty);
        }
        set
        {
            this.SetValue(CommandParameterProperty, value);
        }
    }
    protected override void Invoke(object parameter)
    {
        if (this.AssociatedObject != null)
        {
            ICommand command = this.Command;
            if (command != null)
            {
                if (this.CommandParameter != null)
                {
                    if (command.CanExecute(this.CommandParameter))
                    {
                        command.Execute(this.CommandParameter);
                    }
                }
                else
                {
                    if (command.CanExecute(parameter))
                    {
                        command.Execute(new Tuple<object, object>(this.AssociatedObject, parameter));
                    }
                }
            }
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新