Winforms to WPF conversion: BeginInvoke to what?

无人久伴 提交于 2019-12-10 12:42:44

问题


Here's my old code from 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");
        }
    }

Is there an easy way to convert this to be WPF friendly? So far, I have:

   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");
            });
        }
    }

But that second 'delegate' call fails. How can I invoke this delegate? I suppose I can go through the whole making a delegate method, making an instance of the delegate method, invoking that particular instance, etc, but I thought the whole point of these anonymous delegates was to avoid that hassle. Plus, my old winforms code has that first implementation all over the place, so I'd really like to avoid having to de-anonymize all my delegates.

Edit: I can try to use the MethodInvoker like I was before, but then the compiler gets confused. MethodInvoker is part of System.Windows.Forms, so using that approach doesn't work. As in:

    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");
            }));
        }
    }

That use of MethodInvoker is not kosher. Is there a separate implementation of it, or some other way to use the same behavior?


回答1:


I think you need to change the signature of the delegate:

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

Also, look up using the BackgroundWorker component. Not just for wpf but also for the winform async operations.




回答2:


System.Windows.Forms.MethodInvoker is simply a Delegate that take no parameters and returns void. In WPF, you can just replace it with System.Action. There are also other built-in Delegates that accept parameters, return values, or both.

In your case,

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

becomes

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


来源:https://stackoverflow.com/questions/758233/winforms-to-wpf-conversion-begininvoke-to-what

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!