【问题标题】:Winforms to WPF conversion: BeginInvoke to what?Winforms 到 WPF 的转换:BeginInvoke 到什么?
【发布时间】:2009-04-16 22:06:16
【问题描述】:

这是我在 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");
            });
        }
    }

但是第二个“委托”调用失败了。我怎样才能调用这个委托?我想我可以完成整个制作委托方法,制作委托方法的实例,调用该特定实例等,但我认为这些匿名委托的全部意义在于避免这种麻烦。另外,我的旧 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 的使用不符合犹太教规。是否有单独的实现,或其他方式来使用相同的行为?

【问题讨论】:

    标签: wpf winforms delegates begininvoke


    【解决方案1】:

    System.Windows.Forms.MethodInvoker 只是一个不带参数并返回 void 的委托。在 WPF 中,您可以将其替换为 System.Action。还有其他内置的 Delegates,accept parametersreturn valuesboth

    在你的情况下,

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • der。忘记包含 Windows 窗体库,这是方法调用程序所在的位置。
      • sry,在回顾我的 Pro WPF 书籍寻找真正答案之前说得太早了 :)
      • 是的,'ThreadStart' 似乎是这里的神奇词汇。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-04
      • 1970-01-01
      • 1970-01-01
      • 2010-09-11
      • 2010-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多