Winforms转换为WPF:BeginInvoke变成了什么?

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

但是第二次调用“delegate”失败了。我该如何调用这个委托?我想我可以通过创建一个委托方法,然后创建该委托方法的实例,调用该特定实例等方式来完成,但是我认为这些匿名委托的整个重点是避免这种麻烦。此外,我的旧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 不太合适。是否有单独的实现方法,或者其他使用相同行为的方式?

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

5

我认为你需要更改委托的签名:

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

此外,还可以使用BackgroundWorker组件。不仅适用于WPF,也适用于WinForm异步操作。

我忘记包含Windows Forms库,这是方法调用器所在的地方。 - mmr
抱歉,我在回答之前过于草率了,没有查看我的《Pro WPF》书籍以获取真正的答案 :) - ChrisPelatari
是的,似乎'ThreadStart'在这里是关键词。谢谢! - mmr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接