2

ICommand をコントロールのイベントにフックするさまざまな実装を検討しています。たとえば、TextBox の GotFocus は、View Model で GotFocusCommand を呼び出す必要があります。次に、(自分の学習のために) 自分のバージョンを実装するというアイデアを思いつきましたが、うまく機能していますが、XAML で 1 つのイベントを 1 つのコマンドにしかリンクできません。

(基本的には、リフレクションを使用して指定されたイベントを見つけてから、コマンドを実行する AddEventHandler を実行します)

これはうまくいきます:

<Button 
  local:EventToCommand.Event="Click" 
  local:EventToCommand.Command="{Binding TestCommand}" 
  />  

しかし、これはしません:

<Button 
  local:EventToCommand.Event="Click" 
  local:EventToCommand.Command="{Binding ClickCommand}" 
  local:EventToCommand.Event="GotFocus" 
  local:EventToCommand.Command="{Binding GotFocusCommand}"
  />  

属性名の重複エラーが発生します。

次のようなことは可能でしょうか:

<Button>
  <Some Xaml Element>
    <local:EventToCommand Event="Click" Command="{Binding ClickCommand}" />
    <local:EventToCommand Event="GotFocus" Command="{Binding GotFocusCommand}" />
  </Some Xaml Element>
</Button>

複数のイベントをコマンドに「マップ」するには?

4

3 に答える 3

1

ブレンドイベントトリガーとアクションを使用すると、独自のコレクションを処理する必要がなくなります。また、任意のコントロールに追加できます。

MVVMLightsEventToCommandを参照してください

または、ここでの私の拡張(ソース)

于 2011-10-21T16:39:00.230 に答える
1

これにはいくつかの方法があります。添付プロパティを使用するか、Button から継承して EventToCommand オブジェクトのリストを含む独自の DependencyProperty を追加し、そのコレクションに追加するときに、イベントをコマンドに関連付けます。これが紛らわしいと思われる場合は、いくつかの例を作成してみることができます。

C#

    public class EventedButton : Button
{
    public static DependencyProperty EventCommandsProperty
        = DependencyProperty.Register("EventCommands", typeof(EventToCommandCollection), typeof(EventedButton), new PropertyMetadata(null));


    public EventToCommandCollection EventCommands
    {
        get
        {
            return this.GetValue(EventCommandsProperty) as EventToCommandCollection;
        }
        set
        {
            this.SetValue(EventCommandsProperty, value);
        }
    }

    public EventedButton()
    {
        this.EventCommands = new EventToCommandCollection(this);
    }
}

Xaml:

    <local:EventedButton>
        <local:EventedButton.EventCommands>
            <local:EventToCommand />
        </local:EventedButton.EventCommands>
    </local:EventedButton>

EventToCommandCollection 内で、アイテムがコレクションに追加されたときに必要なイベントにアタッチ/デタッチします。

更新: 添付プロパティ

コレクションを添付プロパティとして実行するコードを次に示します。

C#

        public static DependencyProperty CommandsProperty =
        DependencyProperty.RegisterAttached(
        "Commands",
        typeof(ICollection<EventToCommand>),
        typeof(DependencyObject),
        new PropertyMetadata(null, OnCommandsChanged));


    private static void OnCommandsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Attach/Detach event handlers
    }

    public static void SetCommands(DependencyObject element, ICollection<EventToCommand> value)
    {
        element.SetValue(CommandsProperty, value);
    }

    public static ICollection<EventToCommand> GetCommands(DependencyObject element)
    {
        return (ICollection<EventToCommand>)element.GetValue(CommandsProperty);
    }

Xaml:

    <local:EventedButton>
        <local:EventToCommand.Commands>
            <local:EventToCommandCollection>
                <local:EventToCommand/>
            </local:EventToCommandCollection>
        </local:EventToCommand.Commands>
    </local:EventedButton>
于 2011-10-21T14:47:44.387 に答える
0

GalaSoft MVVMLightToolKit-これを実行できるEventToCommand

<Button> 
  <i:Interaction.Triggers>
     <i:EventTrigger EventName="Click" >
      <cmd:EventToCommand 
          PassEventArgsToCommand="True"
           Command="{Binding ButtonClick}"
       />
    </i:EventTrigger>
 </i:Interaction.Triggers>
  <i:Interaction.Triggers>
     <i:EventTrigger EventName="GotFocus" >
      <cmd:EventToCommand 
          PassEventArgsToCommand="True"
           Command="{Binding ButtonGotFocus}"
       />
    </i:EventTrigger>
 </i:Interaction.Triggers>
</Button>

この名前空間をインポートする場所

 i- xmlns:i="clr-namespace:System.Windows.Interactivity;
    assembly=System.Windows.Interactivity"
 cmd-xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;
     assembly=GalaSoft.MvvmLight.Extras.WPF4"
于 2011-10-21T18:04:37.637 に答える