timer.Enabled状態をラップするプロパティにチェックボックスをバインドしました。他のスレッドからUIを変更しようとしたときにInvalidOperationExceptionが発生しました
のMainForm:
chbTimer.DataBindings.Add(new Binding("Checked", _inactividadController, "TimerEnabled")
{
DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged,
ControlUpdateMode = ControlUpdateMode.OnPropertyChanged
});
_inactividadController:
public bool TimerEnabled
{
get { return _timer.Enabled; }
set
{
_timer.Enabled = value;
InvokePropertyChanged(new PropertyChangedEventArgs("TimerEnabled"));
}
}
_timer.Elapsed:
private void Test(object sender, ElapsedEventArgs e)
{
TimerEnabled = false;
}
例外はここに起こる:
public event PropertyChangedEventHandler PropertyChanged;
public void InvokePropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, e); //<-- BOOM
}
を
私はここで何が起こっているのか十分に理解しています。タイマーは別のスレッドで動作し、メインスレッドにあるchbTimerを更新しようとしますが、これは不正な操作です。しかし、私はこの問題をどのように修正するかについては考えていません。
試しましたthis UIからの変更がバインディングに反映されないため(ユーザーがチェックボックスをオンにしたときにタイマーが状態を変更しないため)、アプローチは有効ですが動作しません。
提案がありますか?おかげ
の実装を変更し、あなたはあなたのハンドラコードも同様に表示することはできますか。 – vendettamit
UIスレッドに呼び出しをマーシャリングする必要があります。 Windowsフォームでこれを行う方法がわからない、Control.Invokeを使用する以外は、ここではうまくいきません(ハックしないでください)。 UIのスレッドでSynchronizationContextを作成して(キャプチャして)、そのSCをバインディングコードで使用しますか? – Will
@vendettamitごめんなさい? 'PropertyChangedEventHandler'がそこにあります。どのハンドラを参照するのかわからない。 – Vallo