10

WinForms からの私の古いコードは次のとおりです。

    private void ValueChanged(double inValue1, double inValue2) {
        //only manual mode for this driver, so that's easy.
        if (ValueLabel.InvokeRequired) {
            ValueLabel.Invoke(new MethodInvoker(delegate {
                ValueLabel.Text = (inValue1* inValue2/ 1000).ToString("f1");
            }
                ));
        }
        else {
            ValueLabel.Text = (inValue1* inValue2/ 1000).ToString("f1");
        }
    }

これを WPF フレンドリーに変換する簡単な方法はありますか? これまでのところ、私は持っています:

   private void KVPValueChanged(double inValue1, double inValue2) {
        if (ValueLabel.Dispatcher.Thread == Thread.CurrentThread){
            ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
        } else {
            ValueLabel.Dispatcher.BeginInvoke(delegate {
                ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
            });
        }
    }

しかし、その 2 番目の「デリゲート」呼び出しは失敗します。このデリゲートを呼び出すにはどうすればよいですか? デリゲート メソッドの作成、デリゲート メソッドのインスタンスの作成、その特定のインスタンスの呼び出しなどをすべて実行できると思いますが、これらの匿名デリゲートの全体的なポイントは、その面倒を避けることだと思いました。さらに、私の古い winforms コードには最初の実装がいたるところにあるため、すべてのデリゲートの匿名化を回避したいと考えています。

編集:以前と同じように MethodInvoker を使用しようとすることはできますが、コンパイラが混乱します。MethodInvoker は System.Windows.Forms の一部であるため、そのアプローチを使用しても機能しません。次のように:

    private void ValueChanged(double inValue1, double inValue2) {
        if (ValueLabel.Dispatcher.Thread == Thread.CurrentThread) {
            ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
        }
        else {
            ValueLabel.Dispatcher.BeginInvoke(new System.Windows.Forms.MethodInvoker(delegate {
                ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
            }));
        }
    }

その MethodInvoker の使用はコーシャではありません。それの別の実装、または同じ動作を使用する他の方法はありますか?

4

2 に答える 2

12

System.Windows.Forms.MethodInvoker は、パラメーターをとらず、void を返す単純なデリゲートです。WPF では、 System.Actionに置き換えるだけです。パラメータ、戻り値、またはその両方を受け入れるその他の組み込みデリゲートもあります。

あなたの場合、

ValueLabel.Dispatcher.BeginInvoke(new System.Windows.Forms.MethodInvoker(delegate {
            ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
        }));

になる

ValueLabel.Dispatcher.BeginInvoke(new Action(delegate() {
            ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
        }));
于 2009-04-17T12:22:14.827 に答える
5

デリゲートの署名を変更する必要があると思います:

ValueLabel.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate(invalue1, invalue2){
    ValueLabel.Content = ...

また、BackgroundWorker コンポーネントを使用して検索します。wpf だけでなく、winform の非同期操作にも使用できます。

于 2009-04-16T22:43:26.743 に答える