C# 如何创建可绑定的命令代理
我目前正在使用MVVM模式开发一个Windows应用商店应用程序。ViewModel实现视图使用的两个命令。在某些情况下,我希望视图触发多个命令。因此,我创建了一个CommandGroup类,该类派生自ICommand,并保存一个可观察的命令集合。为了能够使用XAML填充此集合,我创建了另一个名为CommandProxy的类,该类派生自DependencoObject,还实现了ICommand 其想法是在视图中支持类似的内容:C# 如何创建可绑定的命令代理,c#,mvvm,windows-8,windows-runtime,windows-store-apps,C#,Mvvm,Windows 8,Windows Runtime,Windows Store Apps,我目前正在使用MVVM模式开发一个Windows应用商店应用程序。ViewModel实现视图使用的两个命令。在某些情况下,我希望视图触发多个命令。因此,我创建了一个CommandGroup类,该类派生自ICommand,并保存一个可观察的命令集合。为了能够使用XAML填充此集合,我创建了另一个名为CommandProxy的类,该类派生自DependencoObject,还实现了ICommand 其想法是在视图中支持类似的内容: <Button Content="Test"> &
<Button Content="Test">
<Button.Command>
<vm:CommandGroup>
<vm:CommandGroup.Commands>
<vm:CommandProxy Command="{Binding Command1}" CommandParameter="{Binding ElementName=Object1}"/>
<vm:CommandProxy Command="{Binding Command2}" CommandParameter="{Binding ElementName=Object2}"/>
<vm:CommandProxy Command="{Binding Command3}" CommandParameter="{Binding ElementName=Object3}"/>
</vm:CommandGroup.Commands>
</vm:CommandGroup>
</Button.Command>
</Button>
在执行语法检查时,一切看起来都很好,但绑定在运行时没有解析。假设ViewModel实现了命令MyCommand,并且视图包含一个名为MyElement的元素,则可以使用以下示例再现此情况:
<Button Content="Test">
<Button.Command>
<vm:CommandProxy Command="{Binding MyCommand}" CommandParameter="{Binding ElementName=MyElement}"/>
</Button.Command>
</Button>
这是CommandProxy类的简化版本,可用于重现问题:
public class CommandProxy : DependencyObject, ICommand
{
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(object), typeof(CommandProxy), new PropertyMetadata(null));
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(object), typeof(CommandProxy), new PropertyMetadata(null));
/// <summary>
/// Command
/// </summary>
public ICommand Command
{
get
{
return (ICommand)GetValue(CommandProperty);
}
set
{
SetValue(CommandProperty, value);
}
}
/// <summary>
/// Command Parameter
/// </summary>
public object CommandParameter
{
get
{
return GetValue(CommandParameterProperty);
}
set
{
SetValue(CommandParameterProperty, value);
}
}
/// <summary>
/// Event used to singnal that CanExecute has changed
/// </summary>
public event EventHandler CanExecuteChanged;
/// <summary>
/// Create new CommandGroupElement
/// </summary>
public CommandProxy()
{
}
/// <summary>
/// Determine whether command can be executed
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
public bool CanExecute(object parameter)
{
if (Command != null)
return Command.CanExecute(CommandParameter);
return false;
}
/// <summary>
/// Execute Command
/// </summary>
/// <param name="parameter">Parameter</param>
public void Execute(object parameter)
{
if (Command != null)
Command.Execute(CommandParameter);
}
/// <summary>
/// Raise CanExecuteChanged event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void raiseCanExecuteChanged()
{
raiseCanExecuteChanged(this, EventArgs.Empty);
}
/// <summary>
/// Raise CanExecuteChanged event
/// </summary>
/// <param name="sender">Parameter</param>
/// <param name="e"></param>
protected void raiseCanExecuteChanged(object sender, EventArgs e)
{
if (CanExecuteChanged != null)
CanExecuteChanged(this, EventArgs.Empty);
}
}
公共类CommandProxy:DependencyObject,ICommand
{
公共静态只读DependencyProperty CommandProperty=
Register(“Command”、typeof(object)、typeof(CommandProxy)、newpropertyMetadata(null));
public static readonly dependencProperty命令参数解释属性=
Register(“CommandParameter”、typeof(object)、typeof(CommandProxy)、newpropertyMetadata(null));
///
///命令
///
公共ICommand命令
{
得到
{
返回(ICommand)GetValue(CommandProperty);
}
设置
{
SetValue(CommandProperty,value);
}
}
///
///命令参数
///
公共对象命令参数
{
得到
{
返回GetValue(CommandParameterProperty);
}
设置
{
设置值(CommandParameterProperty,value);
}
}
///
///用于标记CanExecute已更改的事件
///
公共事件处理程序CanExecuteChanged;
///
///创建新CommandGroupElement
///
公共命令代理()
{
}
///
///确定是否可以执行该命令
///
///
///
公共布尔CanExecute(对象参数)
{
if(命令!=null)
return命令.CanExecute(CommandParameter);
返回false;
}
///
///执行命令
///
///参数
public void Execute(对象参数)
{
if(命令!=null)
Command.Execute(CommandParameter);
}
///
///升起CanExecuteChanged事件
///
///
///
受保护的无效raiseCanExecuteChanged()
{
raiseCanExecuteChanged(此,EventArgs.Empty);
}
///
///升起CanExecuteChanged事件
///
///参数
///
受保护的无效raiseCanExecuteChanged(对象发送方,事件参数e)
{
如果(CanExecuteChanged!=null)
CanExecuteChanged(此为EventArgs.Empty);
}
}
有没有人能告诉我我做错了什么或解释我为什么这样做不起作用
问候
Thomas在运行时未解决您的意思是输出中存在数据绑定错误?请发布错误您能为您的CommandProxy提供一个用例场景吗?是否有一些原因不只是绑定到调用其他命令的命令?没有绑定错误。DependencyProperties始终包含属性元数据中指定的默认值(在本例中为null,但如果指定另一个默认值,DependencyProperties将包含此值)。看起来根本没有处理数据绑定。其背后的思想是分离视图和viewnodel,这样viewmodel就不需要知道任何有关视图的信息。在某些情况下,例如按钮可能必须保存数据并关闭弹出窗口或触发导航。当然,这可以通过使用特定于视图的命令或codebehind来解决,但是为了真正分离视图和编码,我希望我的viewmodelbase公开一组服务命令,这些命令可以被视图用于操作元素和导航,并且可以被XAML和数据绑定访问。因此,在viewmodel中不需要view spec.命令。