今回の問題の解決方法としては、
- SampleControlの中ではTriggerを記述しない
- SampleControlのTriggerを書いていたボタンのClickイベントをRaiseSampleEventメソッドに紐付ける
- MainWindow側で、SampleChangedに対してTriggerを設定する
の3点ことによって、MainWindowsViewModelのSomeCommandを呼び出すことが出来ます。
RaiseSampleEventメソッドが呼ばれない、というのを希望しているようですが、
メソッドを経由してイベントを発火させてした方が綺麗に作れます。
メソッドを呼ばない場合だと、ICommandを受け付ける依存関係プロパティを用意して、
PropertyMetaDataのPropertyCallbackで[RaiseSampleEvent]イベントのCommandに紐付ける、といった作りが必要になります。
-- 以下は理由等 --
kakashi さんが書きました: ↑6年前
SampleControl.xaml
コード:
<Button Grid.Row="1" Content="RaiseSampleEvent" Margin="0 10 0 0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<mvvm:EventToCommand Command="{Binding SomeCommand, Mode=TwoWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
MainWindow.xaml
コード:
<my:SampleControl
MouseLeftButtonDown="SampleControl_MouseLeftButtonDown"
SampleChanged="SampleControl_SampleChanged"
/>
※引用者によって一部を抜粋。
UserControlはUserControl内で参照関係を閉じる必要があります。
今回の場合は、UserControl (とそれに付属するViewModel) の外にある、
MainWindowsViewModelのSomeCommandをバインドしようとしているために問題が生じています。
オフトピック
一応、DataContextの設定がない場合は親のFrameworkElementを遡ってDataContextを使いますが、
今回はMvvmLightの機能によって、自動的にSampleControlにはSampleControlViewModelがバインドされます。
SampleControlのボタンに割り当てられたEventToCommandが参照するSomeCommandは、SampleControlViewModelのSomeCommandになります。
そして、このプロパティは見つからないため、SomeCommandのバインドは行われません。
[出力] - [デバッグ]には、
コード:
System.Windows.Data Error: 40 : BindingExpression path error: 'SomeCommand' property not found on 'object' ''String' (HashCode=-899346247)'. BindingExpression:Path=SomeCommand; DataItem='String' (HashCode=-899346247); target element is 'EventToCommand' (HashCode=11903911); target property is 'Command' (type 'ICommand')
System.Windows.Data Error: 40 : BindingExpression path error: 'SomeCommand' property not found on 'object' ''SampleControlViewModel' (HashCode=21520579)'. BindingExpression:Path=SomeCommand; DataItem='SampleControlViewModel' (HashCode=21520579); target element is 'EventToCommand' (HashCode=11903911); target property is 'Command' (type 'ICommand')
というエラーが報告されています。
オフトピック
前者は、SampleControl.xamlにDataContextがテキストで書かれている為に発生していると思われます。
SampleControlの参照関係を閉じるには、SomeCommandをSampelControlで使わないという方法しかありません。
幸い、[RaiseSampleEvent]ボタンのクリックイベントは残骸がコードビハインドにあるため、これに紐付けることが出来ます。
これにより、[RaiseSampleEvent]ボタンを押すとコントロールが[SampleChanged]イベントを発生させます。
あとは、Clickなどのイベントと同じく、親側 (=MainWindow側) で、SampleChangedイベントを購読すればよくなります。
Clickにやったのと同じようにTriggerを設定してやれば、SampleChangedイベントの発生を拾ってSomeCommandを呼び出してくれます。