0

我的WPF应用程序在其主窗口中有这个问题:

public partial class MainWindow : Window, ICallbackNotify

这个“ ICallbackNotify ”是为了与MapInfo COM通信 并确保UI 和 MapInfo之间的交互性

public interface ICallbackNotify : ISynchronizeInvoke
{
    // Method called by MapInfoCallback class when user chooses custom OLE menuitem 
    void OnMenuItemClick(uint id);

    // Method called by MapInfoCallback class when the status bar text changes 
    void OnStatusBarTextChanged(string text);

    // Method called by MapInfoCallback class when window changes
    void OnWindowContentsChanged(uint windowId);
}

问题是,这段代码在Windows From中工作得很好,但是当我把它放到WPF中时,有一个错误消息:

Error   1   'WpfApplication3.MainWindow' does not implement interface member 'System.ComponentModel.ISynchronizeInvoke.InvokeRequired'  c:\users\dragon\documents\visual studio 2010\Projects\WpfApplication3\WpfApplication3\MainWindow.xaml.cs    25  26  WpfApplication3

我不知道为什么或如何解决这个问题

4

1 回答 1

2

在幕后,Windows 窗体和 WPF 非常不同。

ISynchronizeInvoke 是基于 Win32 API 构建的 Windows 窗体概念,不适用于 WPF。在 WPF 中,我们使用 Dispatcher 在线程之间进行通信。

从您的问题来看,您想要做的是在 WPF 应用程序中托管一个 WinForms COM 控件。为了连接这两种技术,Microsoft 提供了一个 WindowsFormHost 控件,您可以使用它来包含您的组件。 这篇博客文章对此进行了很好的描述。查看此 MSDN 示例:https ://msdn.microsoft.com/en-us/library/vstudio/ms751761(v=vs.100).aspx


更新:

听起来您遇到的问题不是在运行时而是在编译期间?让我们放慢脚步,明确一点:

在 Windows 窗体中,所有用户控件和窗口都实现 ISynchronizeInvoke。WPF 不是基于传统的 Win32 WinProc 消息泵构建的,因此它们不实现此接口。如果将 INotifyCallBack 接口和实现“按原样”复制并粘贴到 MainWindow.xaml.cs 中,则会出现编译错误,因为在该类中未实现基本接口 ISynchronizeInvoke。要绕过编译错误,您必须实现 ISynchronizeInvoke 签名:

public partial class MainWindow : Window, ISynchronizeInvoke
{
   public IAsyncResult BeginInvoke(Delegate method, object[] args)
   {
      throw new NotImplementedException();
   }
   public object EndInvoke(IAsyncResult result)
   {
      throw new NotImplementedException();
   }
   public object Invoke(Delegate method, object[] args)
   {
      throw new NotImplementedException();
   }
   public bool InvokeRequired
   {
      throw new NotImplementedException();
   }
}

但猜猜怎么了?如果您这样做,则由您来提供ISynchronizeInvoke和 WPF 调度程序之间的正确映射。 所以不要这样做!上面的代码可能会编译,但它可能无法正常工作(或根本无法正常工作)。

相反,请使用 Microsoft 提供的 Windows 窗体集成功能在 WindowsFormHost 控件中托管您的控件。由于您需要在 INotifyCallback 中实现自定义代码,因此您需要将该代码放入自定义 Windows 窗体用户控件中。

总而言之,您需要遵循上面列出的文章提供的方向:

  • 参考System.Windows.Forms.dllWindowsFormsIntegration.dll
  • 将适当的命名空间添加到 MainWindow.xaml
  • WindowsFormsHost作为容器添加到 MainWindow.xaml 中,然后将自定义控件放入其中。

因此,不要将 ICallbackNotify 实现放在 WPF MainWindow 上,而是将其放在标准的 Windows 窗体 UserControl 中:

namespace YourProject {
   using System.ComponentModel;
   using System.Windows.Forms;

   public class MyCustomMapControl : UserControl, ICallbackNotify
   {
       // your custom code goes here
   }
}
于 2011-07-20T16:27:35.900 回答