私がWPFを持っているとしましょうTextBox
:
<TextBox Text="{Binding Foo}" />
プロパティが(つまり、他のコントロールやコードではなく、特に更新された)によって更新されたICommand
後に実行する方法はありますか?Foo
TextBox
TextBox
「コードビハインド」を避けたいので、バインディングのSourceUpdatedイベントを使用したくありません。
MVVM警察が来て、コードが遅れてしまった場合にあなたを捕まえることができないことに気づいていますか?とにかく、イベントを使用してコマンドなどを実行することは、基本的にC#ではなくXAMLでコーディングすることです。どちらの方法でも、コントロールは目的のコマンドを公開しないため、イベントをコマンドにフックする必要があります。
私はこれがあなたが求めているものだと思います、私が間違った軌道に乗っているかどうか私に知らせてください:
Fooの更新がテキストボックスとテキストボックスのみからいつ行われるかを知りたいとします。つまり、Fooの更新が、コマンドを実行したくないコードからのものである場合、正しいですか?
もしそうなら:
<TextBox Name="Fred" Text="{Binding Foo, NotifyOnSourceUpdated=True}" SourceUpdated="Fred_SourceUpdated"/>
次に、背後にある「邪悪な」コードに次のようになります。
private void Fred_SourceUpdated(object sender, DataTransferEventArgs e)
{
}
このメソッドでは、ビューのデータコンテキストをビューモデルにキャストして、必要なコマンドを呼び出すことができます。他の何かがFooを更新した場合、ソース更新イベントは呼び出されません。
OPで言及しているように、本当にコードを残したくない場合は、添付の動作を行うことができますが、それは「ナンセンス」要件にとっては大規模なやり過ぎです。ロジックがテキストボックスからの変更であるかどうかに依存するという事実は、ビューがすでにビュー以上のものであることを意味します。このアプローチでも、VMでコマンドコードを完全にテスト可能にすることができます。
2回目の編集
また、テキストを変更するのではなく、eventtoコマンドを介してXAMLでソース更新イベントを使用することも検討できます。
やりたいことを何でもするメソッドを作ってみて、raisepropertychanged()が呼び出された後にそのメソッドを呼び出すことができます。例えば
public void MyMethod()
{
//Do whatever;
}
そして、あなたのプロパティゲッターセッターで:
public string MyText
{
get { return _MyText; }
set
{
_MyText = value;
RaisePropertyChanged("MyText")
// THen call that method
MyMehtod();
}
}
構文がオフになっている可能性があります。最近はvbを実行することに慣れています。これがお役に立てば幸いですが、他のオプションが必要な場合は他の方法があります。
編集2:
<Textbox Text="{Binding Foo}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding TextChangedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
TextChangedCommandがビューモデル内にある場所
TextChangedがEventNameであるかどうかわからないので、使用可能なすべてのイベントタイプを記憶していません
を実装したとすると、イベントINotifyPropertyChanged
を処理するだけで済みます。PropertyChanged
イベントハンドラーでコマンドを実行します。このイベントハンドラーは、ViewModelに含まれます(コードビハインドではありません)。
編集
これは、MVVMLightでのEventToCommandの動作の例です。これを使用すると、任意のイベントをコマンドで処理できます。
<Rectangle Fill="White"
Stroke="Black"
Width="200"
Height="100">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<cmd:EventToCommand Command="{Binding TestCommand,
Mode=OneWay}"
CommandParameter="{Binding Text,
ElementName=MyTextBox,
Mode=OneWay}"
MustToggleIsEnabledValue="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle>
編集2
Foo
別のアイデアは、コードを介して変更するときに常にメソッドを使用することです。Foo
このように、メソッドを使用しない変更は、ユーザーが変更した必要があることがわかります。
private bool _isFooUpdating;
private void SetFoo(string value)
{
_isFooUpdating = true;
Foo = value;
_isFooUpdating = false;
}
public string Foo
{
get { return _foo; }
set
{
if (_foo = value) return;
_foo = value;
OnFooChanged();
OnPropertyChanged("Foo");
}
}
private void OnFooChanged()
{
if (_isFooUpdating) return;
FooChangedCommand.Execute();
}