0

I have a mainwindow inside which there is a usercontrol which contains a listview. User control also has a button which copies all the contents of listview to clipboard. This is how the copy functionality has been implemented. below is a part of xaml of usercontrol -

<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>

The AttachedProperties class holds the Dependency property "CommandBindings" - below is the code -

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);
    }
}

Below is the usercontrol viewmodel's code related to copying the items of 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);
    }
}

The sender object in CtrlCCopyCmdExecuted function is the listview in usercontrol which is futher used in copying its contents. The copy all functionality works fine with the button on user control. I have to create a key binding for copy functionality in mainwindow. I have created other keybindings in mainwindow which works fine as the commands are defined in MainWindowViewModel, but since the commandbindings of the copy all command are in the usercontrol's view model, I am facing problems in linking command of keybinding in mainwindowviewmodel with the commandbinding in usercontrolviewmodel. Can Someone help me out with this.

Thanks in advance.

4

1 回答 1

0

如果您的父视图模型可以访问子视图模型,那么您有两个主要选择。这两个选项都涉及在父视图模型中创建一个ICommandto to 属性: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是一个基于 common 的自定义类RelayCommand


更新>>>

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

首先,如果您ApplicationCommands.Copy在 child 中使用 command 对象UserControl,那么您当然可以KeyBinding在 parent 视图中使用相同的对象。ApplicationCommands是一个static类,Copy也是一个static属性,所以无论你怎么称呼它,它都是同一个对象:

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

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

于 2013-10-31T17:18:26.247 回答