Winform到WPF转换:BeginInvoke到什么?

时间:2022-08-27 21:20:19

Here's my old code from WinForms:

这是来自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:

是否有一种简单的方法将其转换为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");
            });
        }
    }

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.

但是第二个“代表”呼叫失败了。我该如何调用此委托?我想我可以完成整个制作委托方法,制作委托方法的实例,调用该特定实例等,但我认为这些匿名委托的重点是避免这种麻烦。另外,我的旧winforms代码在整个地方都有第一个实现,所以我真的希望避免对我的所有代表进行去匿名化。

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:

编辑:我可以像以前一样尝试使用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");
            }));
        }
    }

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

MethodInvoker的使用不是犹太教。是否有单独的实现,或使用相同的行为的其他方式?

2 个解决方案

#1


5  

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.

另外,使用BackgroundWorker组件进行查找。不仅适用于wpf,还适用于winform异步操作。

#2


12  

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.

System.Windows.Forms.MethodInvoker只是一个不带参数且返回void的Delegate。在WPF中,您只需将其替换为System.Action即可。还有其他内置的Delegates接受参数,返回值或两者。

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

#1


5  

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.

另外,使用BackgroundWorker组件进行查找。不仅适用于wpf,还适用于winform异步操作。

#2


12  

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.

System.Windows.Forms.MethodInvoker只是一个不带参数且返回void的Delegate。在WPF中,您只需将其替换为System.Action即可。还有其他内置的Delegates接受参数,返回值或两者。

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