将主窗口视图模型中的KeyBinding的链接命令链接到用户控件的视图模型命令绑定

时间:2013-10-31 17:03:10

标签: c# wpf mvvm key-bindings

我有一个主窗口,里面有一个包含listview的usercontrol。 用户控件还有一个按钮,可以将listview的所有内容复制到剪贴板。 这就是复制功能的实现方式。 下面是usercontrol的xaml的一部分 -

<Button Command="Copy" 
     CommandTarget="{Binding ElementName=testCodeView}"
     CommandParameter="Copy"
</Button> 

<ListView  x:Name="testCodeView" 
       ItemsSource="{Binding Products}" BorderThickness="0" Grid.Row="1"
       ItemTemplate="{StaticResource testViewTemplate}"       
       ItemContainerStyle="{StaticResource testCodesListItem}"
       infra:AttachedProperties.CommandBindings ="{Binding CommandBindings}">
</ListView>

AttachedProperties类包含Dependency属性“CommandBindings” - 下面是代码 -

public class AttachedProperties
{
public static DependencyProperty CommandBindingsProperty =
        DependencyProperty.RegisterAttached("CommandBindings", typeof(CommandBindingCollection), typeof(AttachedProperties),
        new PropertyMetadata(null, OnCommandBindingsChanged));
public static void SetCommandBindings(UIElement element, CommandBindingCollection value)
    {
        if (element != null)
            element.SetValue(CommandBindingsProperty, value);
    }
    public static CommandBindingCollection GetCommandBindings(UIElement element)
    {
        return (element != null ? (CommandBindingCollection)element.GetValue         (CommandBindingsProperty) : null);
    }
}

下面是usercontrol viewmodel与复制listview项目相关的代码。

public class UserControlViewModel : INotifyPropertyChanged
{
    public CommandBindingCollection CommandBindings
    {
        get
        {
            if (commandBindings_ == null)
            {
                commandBindings_ = new CommandBindingCollection();
            }
            return commandBindings_;
        }
    }
    public UserControlViewModel 
    {
        CommandBinding copyBinding = new CommandBinding(ApplicationCommands.Copy,   
        this.CtrlCCopyCmdExecuted, this.CtrlCCopyCmdCanExecute);
        // Register binding to class
        CommandManager.RegisterClassCommandBinding(typeof(UserControlViewModel), copyBinding);
        this.CommandBindings.Add(copyBinding);
    }
    private void CtrlCCopyCmdExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        copyToclipboard_.CtrlCCopyCmdExecuted(sender, e);
    }
}

CtrlCCopyCmdExecuted函数中的发送方对象是usercontrol中的listview,后者将在 复制其内容。 复制所有功能与用户控件上的按钮一起正常工作。 我必须在mainwindow中为复制功能创建一个键绑定。我已经在mainwindow中创建了其他键绑定,因为命令在MainWindowViewModel中定义,但是由于copy all命令的命令绑定在usercontrol的视图模型中,因此我遇到了将mainwindowviewmodel中的键绑定命令与usercontrolviewmodel中的commandbinding链接的问题。 。 有人可以帮我解决这个问题。

提前致谢。

1 个答案:

答案 0 :(得分:0)

如果您的父视图模型可以访问子视图模型,那么您有两个主要选项。这两个选项都涉及在父视图模型中为ICommand创建Bind属性:

<KeyBinding Gesture="CTRL+C" Command="{Binding Copy, Mode=OneWay}" />

第一个选项涉及创建一个BaseViewModel类,其中包含abstract ICommand属性...任何扩展BaseViewModel的类都有来实现这个命令......那么你可以拥有这种类型的子视图模型属性,只需传递值:

public override ICommand Copy
{
    get { return new ActionCommand(action => ViewModel.Copy.Execute(null), 
canExecute => ViewModel.Copy != null); }
}

我怀疑你在每个视图模型上都想要这个命令,所以让我们研究第二个选项。基本思想是,如果您可以访问子视图模型,则可以将命令“传递”给子项:

public ICommand Copy
{
    get { return new ActionCommand(action => childViewModel.Copy.Execute(action), 
canExecute => childViewModel.Copy.Execute(canExecute)); }
}

ActionCommand是一个基于公共RelayCommand

的自定义类

更新&gt;&gt;&gt;

好的,所以我之前从未使用CommandBindings因为使用我的ActionCommandRelayCommand 所以更容易,但我刚刚调查过在MSDN上,我想到了两个想法。

首先,如果您在子ApplicationCommands.Copy中使用UserControl命令对象,那么您肯定可以在父视图中的KeyBinding中使用相同的对象。 ApplicationCommandsstatic类,Copystatic属性,因此无论您在何处调用它,都是相同的对象:

<KeyBinding Gesture="CTRL+C" Command="ApplicationCommands.Copy" />

如果失败,您可以在父视图模型中创建ICommand属性,并创建自己的Copy命令,或者只返回ApplicationCommands.Copy命令。然后,您可以从父视图子视图Bind到它...或者,您甚至可以从父视图模型将其添加到子视图CommandBinding对象中