IIが実際のアプローチを理解できなかっただけで申し訳ありませんが、さまざまなブログ投稿を調べましたが、答えに近づいているとは感じていません.
私は基本的に時間をコストに変換するストップウォッチである WP7 アプリケーションを作成しています。
Model にはメソッド Start() および Pause() と double プロパティ Cost が含まれています。ViewModel では、基になるモデル関数をトリガーする Start() と Pause() に ICommand を使用しています。ただし、Start() を呼び出した後、増加するコストを UI に反映させたいと考えています。
私はいくつかのアプローチを検討しました:
- ViewModel は、自己実装されたサブスクライバー モデルを介してモデルにサブスクライブし、モデルは、モデルが実行されている間、数ミリ秒ごとにすべてのサブスクライバーに通知します。
- View Model の StartCommand は、数ミリ秒ごとに Cost プロパティで RaisePropertyChanged イベントを発生させるバックグラウンド ワーカーを開始します。
モデルはスレッド化をまったく必要としないため、2 番目の提案を選択しました (ユーザーが開始と一時停止を押した時間をログに記録し、これをコスト計算に使用するだけです)。http://msdn.microsoft.com/en-us/library/cc221403(VS.95).aspxに基づいてアプローチしました
ただし、これを実行しようとすると「UnauthorizedAccessException」が発生します。コードは以下のとおりです。
バックグラウンドワーカーは、コンストラクターで VM メンバーとして作成されます
public MeetingCostViewModel()
{
_backgroundWorker = new BackgroundWorker
{
WorkerSupportsCancellation = true,
WorkerReportsProgress = false,
};
_backgroundWorker.DoWork += DoWork;
}
StartCommand は、バックグラウンド ワーカーの実行をトリガーします
private DelegateCommand _startCommand;
public ICommand StartCommand
{
get
{
return _startCommand ?? (_startCommand = new DelegateCommand(
delegate
{
_meetingCost.Start();
_keepUpdating = true;
if (_backgroundWorker.IsBusy != true)
{
_backgroundWorker.RunWorkerAsync();
}
}));
}
}
そして、これはhttp://blog.lab49.com/archives/1166に基づく実際のワーカー メソッドです。
private void DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
PropertyChangedEventHandler temp = PropertyChanged;
if (temp != null)
{
temp(this, new PropertyChangedEventArgs("Cost"));
}
Thread.Sleep(50);
}
}
これが正しいアプローチであるかどうかはわかりませんが、ビューをデータバインドし、「コードビハインド」なしで維持したいのですが、ここでのほとんどの代替応答では、賢明なコストで回避したいコントロールの明示的な設定が必要です。