【问题标题】:link command of KeyBinding in mainwindow's view model to an user control's view model commandbindings将主窗口视图模型中的 KeyBinding 命令链接到用户控件的视图模型命令绑定
【发布时间】:2013-10-31 17:03:09
【问题描述】:

我有一个主窗口,里面有一个包含列表视图的用户控件。 用户控件还有一个按钮,可以将 listview 的所有内容复制到剪贴板。 这就是复制功能的实现方式。 下面是用户控件 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 类包含依赖属性“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函数中的sender对象是usercontrol中的listview,在 复制其内容。 复制所有功能可与用户控件上的按钮正常工作。 我必须在主窗口中为复制功能创建一个键绑定。我在主窗口中创建了其他键绑定,这些键绑定工作正常,因为命令是在 MainWindowViewModel 中定义的,但是由于复制所有命令的命令绑定在用户控件的视图模型中,我在将主窗口视图模型中的键绑定命令与 usercontrolviewmodel 中的命令绑定链接时遇到问题. 有人可以帮我解决这个问题。

提前致谢。

【问题讨论】:

    标签: c# wpf mvvm key-bindings


    【解决方案1】:

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


    更新>>>

    好的,所以我以前从未使用过CommandBindings,因为使用我的ActionCommandRelayCommand 更容易所以,但我刚刚在 MSDN 上对其进行了调查,并提出了两个想法浮现在脑海中。

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

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

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

    【讨论】:

    • 谢谢谢里登。但是我在实施这个解决方案时可能会遇到一些问题。 childViewModel 没有要复制的特定命令。它使用名为 Commandbindings 的依赖属性(请查看上面的 usercontrol xaml 和 AttachedProperties 类)。我确实可以访问 parenViewModel 中 childViewModel 的命令绑定。无论如何我可以用它来执行命令。 Executed 事件处理程序中的发送者对象也应该是列表视图(复制按钮的命令目标是列表视图)。
    猜你喜欢
    • 2014-11-08
    • 2011-09-01
    • 1970-01-01
    • 2012-10-02
    • 1970-01-01
    • 2013-01-16
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多