我有一个提供RelayCommand LoadImage的视图模型。
通常我会使用一个按钮并将命令绑定到此按钮。
但是我想从视图的代码隐藏中调用LoadImage命令(我需要做一些不能放入视图模型的视图相关内容)
我知道的一种方法是为按钮创建一个事件处理程序,例如Button_Click。
在Button_Click中,我将DataContext转换为相应的ViewModel,并使用此实例调用(DataContext as MyViewModel).LoadImage.Execute(...)
这很奇怪,因为我需要知道视图模型。
我正在尝试的是将LoadImage绑定到按钮而不是绑定到视图中的资源,因此Button_Click事件只需要调用具有给定名称的FindResource并将其强制转换为ICommand,而无需知道特定的ViewModel
这可能吗?命令本身不是静态的,因为它需要知道它所调用的上下文。
答案 0 :(得分: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>
答案 1 :(得分:0)
根据Bill Zhangs对行为的看法,我创建了一个非常控制并且允许重复使用的通用版本。 所需的程序集是
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
我创建了一个Trigger操作,将执行传递给事件处理程序:
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