C# 如何在MVVM中使用应用程序命令
我想使用应用程序命令。剪切、复制、粘贴、保存,。。。它们看起来很有趣,因为命令路由、键绑定以及一些控件使用它们的事实。我了解如何绑定到VM上的中继/委派命令,但我似乎无法理解应用程序命令。我找到了一些旧答案,但没有其他信息,我有点不愿意遵循这些路线 这似乎很常见,但信息似乎非常有限。这通常是如何实现的?(带或不带棱镜、MVVM灯等) 旧答案: 但我觉得用行为来解决这个问题很奇怪 但我认为这不是公认的答案中的MVVMC# 如何在MVVM中使用应用程序命令,c#,wpf,mvvm,C#,Wpf,Mvvm,我想使用应用程序命令。剪切、复制、粘贴、保存,。。。它们看起来很有趣,因为命令路由、键绑定以及一些控件使用它们的事实。我了解如何绑定到VM上的中继/委派命令,但我似乎无法理解应用程序命令。我找到了一些旧答案,但没有其他信息,我有点不愿意遵循这些路线 这似乎很常见,但信息似乎非常有限。这通常是如何实现的?(带或不带棱镜、MVVM灯等) 旧答案: 但我觉得用行为来解决这个问题很奇怪 但我认为这不是公认的答案中的MVVM 在旧文章中使用附加属性:引用其他文章 我问这个问题已经有一段时间了,但看起来很多
在旧文章中使用附加属性:引用其他文章 我问这个问题已经有一段时间了,但看起来很多人都在看这个问题。我最终使用了一种将VM命令列表连接到FrameworkElement的行为。这似乎是最灵活和可恢复的解决方案
public class AttachCommandBindingsBehavior : Behavior<FrameworkElement>
{
public ObservableCollection<CommandBinding> CommandBindings
{
get
{
return (ObservableCollection<CommandBinding>)GetValue(CommandBindingsProperty);
}
set
{
SetValue(CommandBindingsProperty, value);
}
}
public static readonly DependencyProperty CommandBindingsProperty = DependencyProperty.Register("CommandBindings", typeof(ObservableCollection<CommandBinding>), typeof(AttachCommandBindingsBehavior), new PropertyMetadata(null, OnCommandBindingsChanged));
private static void OnCommandBindingsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
AttachCommandBindingsBehavior attachCommandBindingsBehavior = (AttachCommandBindingsBehavior)sender;
if (attachCommandBindingsBehavior == null)
return;
ObservableCollection<CommandBinding> commandBindings = (ObservableCollection<CommandBinding>)e.NewValue;
if (commandBindings != null)
{
if (attachCommandBindingsBehavior.CommandBindings != null)
attachCommandBindingsBehavior.CommandBindings.CollectionChanged -= attachCommandBindingsBehavior.CommandBindings_CollectionChanged;
attachCommandBindingsBehavior.CommandBindings.CollectionChanged += attachCommandBindingsBehavior.CommandBindings_CollectionChanged;
}
}
void CommandBindings_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
ObservableCollection<CommandBinding> collection = (ObservableCollection<CommandBinding>)sender;
if (collection != null)
{
foreach (CommandBinding commandBinding in collection)
AssociatedObject.CommandBindings.Add(commandBinding);
}
}
}
公共类AttachCommandBindingsBehavior:行为
{
公共ObservableCollection命令绑定
{
得到
{
返回(ObservableCollection)GetValue(CommandBindingsProperty);
}
设置
{
SetValue(CommandBindingsProperty,value);
}
}
public static readonly dependencProperty CommandBindingsProperty=dependencProperty.Register(“CommandBindings”、typeof(observeCollection)、typeof(AttachCommandBindingsBehavior)、newpropertyMetadata(null、OnCommandBindingsChanged));
CommandBindingsChanged上的私有静态无效(DependencyObject发送方,DependencyPropertyChangedEventArgs e)
{
AttachCommandBindingsBehavior AttachCommandBindingsBehavior=(AttachCommandBindingsBehavior)发送方;
如果(attachCommandBindingsBehavior==null)
返回;
ObservableCollection命令绑定=(ObservableCollection)e.NewValue;
if(commandBindings!=null)
{
if(attachCommandBindingsBehavior.CommandBindings!=null)
attachCommandBindingsBehavior.CommandBindings.CollectionChanged-=attachCommandBindingsBehavior.CommandBindings\u CollectionChanged;
attachCommandBindingsBehavior.CommandBindings.CollectionChanged+=attachCommandBindingsBehavior.CommandBindings\u CollectionChanged;
}
}
void CommandBindings\u CollectionChanged(对象发送方,System.Collections.Specialized.notifycollectionchangedventargs e)
{
ObservableCollection collection=(ObservableCollection)发送方;
if(集合!=null)
{
foreach(集合中的CommandBinding CommandBinding)
AssociatedObject.CommandBindings.Add(commandBinding);
}
}
}
在xaml中,您可以执行以下操作:
<i:Interaction.Behaviors>
<localBehaviors:AttachCommandBindingsBehavior CommandBindings="{Binding CommandBindings}"/>
</i:Interaction.Behaviors>
很抱歉没有时间提供详细的答案,但您的第一个链接是正确的。该示例将行为与视图模型紧密耦合(此:AssociatedObject.selecteditemas NestingItemTreeViewModelBase;
)。这将防止行为真正可重用。您应该公开ICommand
依赖项属性,而不是强制转换。将这些DPs绑定到包含命令逻辑的ViewModel,然后将应用程序命令中继到绑定到此DPs的命令。这将符合MVVM模式。希望这能给你一个方向,你能详细说明这一部分吗:“然后将应用程序命令中继到绑定到此DPs的命令”?另外,我不需要usercontrol,那么这些依赖属性去哪里呢?您也可以将DPs添加到行为中。它们也从DependencyObject
派生,所有WPF控件都是如此。在内部,即CopyCommandCanExecute
中,分别调用e.CanExecute=CopyCommand.CanExecute(null)
和CopyCommand.Execute(null)
(CopyCommand
是CopyCommand DP的包装器)。在Xaml中,您可以将您的ViewModel绑定到它`对于任何使用此行为的人,请知道它已损坏,并且只有在行为附加后添加命令绑定时才起作用(这种情况几乎从未发生过)。另一个用户对此实现有问题,我发布了一个可以更可靠地工作的解决方案。