【发布时间】:2010-08-30 20:13:37
【问题描述】:
首先对我的“pidgin”英语感到抱歉,:(
应用程序基于 MVVM 模式构建。 ViewModel 通过命令公开其功能并具有特殊命令 - DispatchCommand 接收(在 CommandParameter 中)其他命令/参数对并使用接收到的参数执行接收到的命令。该功能(对主题而言并不重要)是 DispatcherCommand 在主应用程序线程中执行,其他 ViewModel 命令(由 DispatcherCommand 调用)是异步的,并且每个命令都在单独的线程中执行其 Execute() 委托。这种方法(通过 DispatchCommand 间接执行异步 ViewModel 命令)用于管理内部 ViewModel 状态(例如,DispatchCommands 在执行其他异步命令时拒绝调用特定的异步命令等)。
在代码中是这样的:
// Dispatcher command
public class DispatcherCommand : ICommand { }
// async command
public interface IAsyncCommand : ICommand { }
public class AsyncCommand : IAsyncCommand { }
// view model
public class AsyncModel
{
public DispatcherCommand Dispatcher { get {...} }
// async commands - current model capabilities
public AsyncCommand FirstCapability { get {...} }
public AsyncCommand SecondCapability { get {...} }
...
}
// using example
AsyncModel model = new AsyncModel();
model.Dispatcher.Execute(
new { Command = model.FirstCapability, Parameter = "string param" });
我想以同样的方式在 XAML 中提供对异步命令的访问:
<Button Command="{Binding Path=DispatcherCommand}">
<Button.CommandParameter>
<local:CurrentCommandParameters Command="{Binding Path=FirstCapability}"
Parameter="string param"/>
</Button.CommandParameter>Use first capability</Button>
在哪里
// DispatcherCommand parameter class
public class DispatcherCommandParameters : DependencyObject
{
// target async command
public IAsyncCommand Command
{
set { SetValue(CommandProperty, value); }
get { return (IAsyncCommand)GetValue(CommandProperty); }
}
// its parameter
public object Parameter
{
set { SetValue(ParameterProperty, value); }
get { return GetValue(ParameterProperty); }
}
public static readonly DependencyProperty CommandProperty;
public static readonly DependencyProperty ParameterProperty;
static CurrentCommandParameters()
{
CommandProperty = DependencyProperty.Register("Command",
typeof(IAsyncCommand),
typeof(CurrentCommandParameters),
new PropertyMetadata());
ParameterProperty = DependencyProperty.Register("Parameter",
typeof(object),
typeof(CurrentCommandParameters),
new PropertyMetadata());
}
}
但它不起作用。 DispatcherCommand.Execute(object parameter) 接收到一个 DispatcherCommandParameters 类的实例,但它的 Command 属性为空。
在这种情况下可以做什么?
在窗口构造函数中,与在 xaml 中失败的相同绑定创建成功:
<Button Name="StupidButton" Command="{Binding Path=DispatcherCommand}">
...
public MainWindow()
{
InitializeComponent();
// set up data context
AsyncModel model = new AsyncModel();
this.DataContext = model;
// set up binding
DispatcherCommandParameters dcp = new DispatcherCommandParameters();
dcp.Parameter = "string parameter value set in code";
Binding myBinding = new Binding("FirstCapability");
myBinding.Source = model;
BindingExpressionBase be = BindingOperations.SetBinding(dcp,
DispatcherCommandParameters.CommandProperty, myBinding);
StupidButton.CommandParameter = dcp;
// now when "StupidButton" is pressed,
// DispatcherCommand.Execute(object parameter)
// receives correct reference to AsyncModel.FirstCapability command in
// ((DispatcherCommandParameters)parameter).Command property
}
【问题讨论】: