12

MVVM-Lightを使用していくつかのカスタムコマンドを正常に使用しましたが、アプリケーションがウィンドウレベルだけでなく、詳細なアイテムレベルでも標準のApplicationCommandsに応答するようにしたいです。

ノードをTreeViewコピーして貼り付けることができるようにしたいものがあります。各TreeViewItemには独自のViewModelがHierarchicalDataTemplatesあり、いくつかの異なるタイプがあるため、XAMLで表示されます。ViewModelクラスに、コピー、貼り付け、およびCanCopyとCanPasteのメソッドを実装しました。必要に応じて、これらを指すMVVM-Light RelayCommandsを簡単に実装できますが、それは正しくないようです。

メニュー、Ctrl+CおよびCtrl+V、または最終的にはコンテキストメニューを使用してコマンドにアクセスしたいと思います。また、TextBoxなど、UIの他の要素のコピー/貼り付け機能を壊したくありません。この目的には、組み込みのApplicationCommandsを使用するのが適切と思われます。ただし、これらの例はUserControlコードビハインドで処理されているだけです。私はUserControlを持っていません(または必要ありません)。また、MVVMに実際に続いているわけでもありません。

ビューモデル、つまりデータテンプレートにバインドApplicationCommand.Copyしてコマンドを実行する方法はありますか?ApplicationCommand.Paste

4

2 に答える 2

9

TreeView にアタッチされた動作を使用してこれを解決しました。TreeViewItems または Templates は、ルーティングされたコマンドを取得していないようです。幸いなことに、TreeView には、ViewModel を取得するために使用できる SelectedItem プロパティもあります。

(動作は概念的には @Natxo の回答のリンクのソリューションに似ていますが、すべてを解決するわけではありません。)

振る舞いクラス:

public class TreeViewClipboardBehavior : Behavior<TreeView>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        CommandBinding CopyCommandBinding = new CommandBinding(
            ApplicationCommands.Copy,
            CopyCommandExecuted,
            CopyCommandCanExecute);
        AssociatedObject.CommandBindings.Add(CopyCommandBinding);

        CommandBinding CutCommandBinding = new CommandBinding(
            ApplicationCommands.Cut,
            CutCommandExecuted,
            CutCommandCanExecute);
        AssociatedObject.CommandBindings.Add(CutCommandBinding);

        CommandBinding PasteCommandBinding = new CommandBinding(
            ApplicationCommands.Paste,
            PasteCommandExecuted,
            PasteCommandCanExecute);
        AssociatedObject.CommandBindings.Add(PasteCommandBinding);
    }

    private void CopyCommandExecuted(object target, ExecutedRoutedEventArgs e)
    {
        NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
        if (item != null && item.CanCopyToClipboard)
        {
            item.CopyToClipboard();
            e.Handled = true;
        }
    }

    private void CopyCommandCanExecute(object target, CanExecuteRoutedEventArgs e)
    {
        NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
        if (item != null)
        {
            e.CanExecute = item.CanCopyToClipboard;
            e.Handled = true;
        }
    }

    private void CutCommandExecuted(object target, ExecutedRoutedEventArgs e)
    {
        NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
        if (item != null && item.CanCutToClipboard)
        {
            item.CutToClipboard();
            e.Handled = true;
        }
    }

    private void CutCommandCanExecute(object target, CanExecuteRoutedEventArgs e)
    {
        NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
        if (item != null)
        {
            e.CanExecute = item.CanCutToClipboard;
            e.Handled = true;
        }
    }


    private void PasteCommandExecuted(object target, ExecutedRoutedEventArgs e)
    {
        NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
        if (item != null && item.CanPasteFromClipboard)
        {
            item.PasteFromClipboard();
            e.Handled = true;
        }
    }

    private void PasteCommandCanExecute(object target, CanExecuteRoutedEventArgs e)
    {
        NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
        if (item != null)
        {
            e.CanExecute = item.CanPasteFromClipboard;
            e.Handled = true;
        }
    }
}

XAML

<TreeView Grid.Row="2" ItemsSource="{Binding SystemTreeRoot}">
    <i:Interaction.Behaviors>
        <local:TreeViewClipboardBehavior/>
    </i:Interaction.Behaviors>
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:MyViewModel}" ItemsSource="{Binding Children}">
            <!-- Template content -->
        </HierarchicalDataTemplate>
</TreeView>
于 2011-10-12T18:59:47.160 に答える
3

を探していると思いますCommandBindings。私はいくつかのテキストボックスに似たものを使用しています:

    <DataTemplate x:Key="textBoxTemplate" >
        <TextBox>
            <TextBox.CommandBindings>
                <CommandBinding Command="ApplicationCommand.Copy" 
                                Executed="CommandBinding_Executed"
                                CanExecute="CommandBinding_CanExecute">
                </CommandBinding>
            </TextBox.CommandBindings>
        </TextBox>
    </DataTemplate>

PreviewCanExecutePreviewExecutedも利用可能であることに注意してください。

編集:ここのサンプルをチェックして、MVVM に準拠させてください。

于 2011-10-04T09:58:18.380 に答える