1

我有一个提供 RelayCommand LoadImage 的视图模型。

通常我会使用一个按钮并将命令绑​​定到这个按钮。

但是我想从视图的代码隐藏中调用 LoadImage 命令(我需要做一些不能放入视图模型的视图相关的东西)

我知道的一种方法是为按钮创建一个事件处理程序,例如 Button_Click。在 Button_Click 我会将 DataContext 转换为相应的 ViewModel 并使用此实例调用(DataContext as MyViewModel).LoadImage.Execute(...)

这很奇怪,因为我需要知道视图模型。

我正在尝试将 LoadImage 绑定到视图中的资源而不是按钮,因此 Button_Click 事件只需要使用给定名称调用 FindResource 并将其转换为 ICommand 而无需知道特定的 ViewModel。

这可能吗?命令本身不是静态的,因为它需要知道它被调用的上下文。

4

2 回答 2

1

您可以通过创建一个行为来实现它,这需要在您的项目中引用 Prism:

public class LoadImageBehavior : Behavior<Button>
{
    public public static static readonly DependencyProperty CommandProperty =
        DependencyProperty.Register("Command", typeof (ICommand), typeof (LoadImageBehavior));

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

    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.Click += AssociatedObject_Click;
    }

    private void AssociatedObject_Click(object sender, RoutedEventArgs e)
    {
        //Logic...

        if(Command != null && Command.CanExecute(null))
            Command.Execute(null);

        //Logic...
    }
}

在 Xaml 上:

    <Button>
        <i:Interaction.Behaviors>
            <Behaviors:LoadImageBehavior Command="{Binding LoadImageCommand}"/>
        </i:Interaction.Behaviors>
    </Button>
于 2013-07-26T12:58:39.567 回答
0

基于 Bill Zhang 的行为理念,我创建了一个通用版本,它与控制无关并且允许重用。所需的组件是

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

我创建了一个触发操作,将执行传递给事件处理程序:

using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;
using System;

namespace Misc
{
   public class CommandWithEventAction : TriggerAction<UIElement>
   {
      public event Func<object, object> Execute;

      public static DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(CommandWithEventAction), null);
      public ICommand Command
      {
         get
         {
            return (ICommand)GetValue(CommandProperty);
         }
         set
         {
            SetValue(CommandProperty, value);
         }
      }


      public static DependencyProperty ParameterProperty = DependencyProperty.Register("Parameter", typeof(object), typeof(CommandWithEventAction), null);
      public object Parameter
      {
         get
         {
            return GetValue(ParameterProperty);
         }
         set
         {
            SetValue(ParameterProperty, value);

         }
      }

      protected override void Invoke(object parameter)
      {
         var result = Execute(Parameter);
         Command.Execute(result);
      }

   }
}

为了避免自定义行为中的任何逻辑,这允许将任何事件连接到事件回调,然后是命令调用。

XAML:

<Button>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <misc:CommandWithEventAction Command="{Binding LoadImageCommand}" Parameter="Custom data"  Execute="CommandWithEventAction_OnExecute"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    Execute
</Button>

这会将作为对象装箱的“自定义数据”字符串传递给一个名为

CommandWithEventAction_OnExecute

它的签名Func<object,object>可能会使用参数,并且需要返回一些东西,然后将这些东西装箱到对象中并传递给LoadImageCommand

于 2013-07-26T13:57:24.257 回答