1

RelayCommand LoadImage を提供するビュー モデルがあります。

通常、ボタンを使用して、コマンドをこのボタンにバインドします。

ただし、ビューのコード ビハインドから LoadImage コマンドを呼び出したいと思います (ビュー モデルに配置してはならないビュー関連のものを実行する必要があります)。

私が知っている 1 つの方法は、Button_Click などのボタンのイベント ハンドラーを作成することです。Button_Click では、DataContext を対応する ViewModel にキャストし、このインスタンスを使用して呼び出します(DataContext as MyViewModel).LoadImage.Execute(...)

ビューモデルを知る必要があるため、これは奇妙です。

私がしようとしているのは、LoadImage をボタンではなくビュー内のリソースにバインドすることです。そのため、Button_Click イベントは、特定の ViewModel を知る必要なく、特定の名前で FindResource を呼び出して ICommand にキャストするだけで済みます。

これは可能ですか?コマンド自体は、呼び出し元のコンテキストを知る必要があるため、静的ではありません。

4

2 に答える 2

1

プロジェクトで参照される Prism を必要とする動作を作成することで、それを実現できます。

public class LoadImageBehavior : Behavior<Button>
{
    public public static static readonly DependencyProperty CommandProperty =
        DependencyProperty.Register("Command", typeof (ICommand), typeof (LoadImageBehavior));

    public ICommand Command
    {
        get { return (ICommand) GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.Click += AssociatedObject_Click;
    }

    private void AssociatedObject_Click(object sender, RoutedEventArgs e)
    {
        //Logic...

        if(Command != null && Command.CanExecute(null))
            Command.Execute(null);

        //Logic...
    }
}

Xaml の場合:

    <Button>
        <i:Interaction.Behaviors>
            <Behaviors:LoadImageBehavior Command="{Binding LoadImageCommand}"/>
        </i:Interaction.Behaviors>
    </Button>
于 2013-07-26T12:58:39.567 に答える
0

Bill Zhang のビヘイビアのアイデアに基づいて、制御にとらわれず、再利用できる汎用バージョンを作成しました。必要な組み立ては

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

実行をイベント ハンドラーに渡すトリガー アクションを作成しました。

using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;
using System;

namespace Misc
{
   public class CommandWithEventAction : TriggerAction<UIElement>
   {
      public event Func<object, object> Execute;

      public static DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(CommandWithEventAction), null);
      public ICommand Command
      {
         get
         {
            return (ICommand)GetValue(CommandProperty);
         }
         set
         {
            SetValue(CommandProperty, value);
         }
      }


      public static DependencyProperty ParameterProperty = DependencyProperty.Register("Parameter", typeof(object), typeof(CommandWithEventAction), null);
      public object Parameter
      {
         get
         {
            return GetValue(ParameterProperty);
         }
         set
         {
            SetValue(ParameterProperty, value);

         }
      }

      protected override void Invoke(object parameter)
      {
         var result = Execute(Parameter);
         Command.Execute(result);
      }

   }
}

カスタム動作のロジックを回避するために、任意のイベントをイベント コールバックにフックし、その後にコマンド呼び出しを行うことができます。

XAML:

<Button>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <misc:CommandWithEventAction Command="{Binding LoadImageCommand}" Parameter="Custom data"  Execute="CommandWithEventAction_OnExecute"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    Execute
</Button>

これにより、オブジェクトとしてボックス化された「カスタムデータ」文字列が呼び出された関数に渡されます

CommandWithEventAction_OnExecute

その署名はFunc<object,object>パラメータを使用し、オブジェクトにボックス化されて渡される何かを返す必要がありますLoadImageCommand

于 2013-07-26T13:57:24.257 に答える