WPF 窗口未实现 ISynchronizeInvoke.InvokeRequired 错误

发布于 2024-11-25 01:10:14 字数 1104 浏览 4 评论 0原文

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

public partial class MainWindow : Window, ICallbackNotify

这个“ ICallbackNotify ”是与 MapInfo COM 通信的 并保证 UI 和 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 中时,出现错误 msg :

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

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

I have this problem that My WPF App in its MainWindow:

public partial class MainWindow : Window, ICallbackNotify

this " ICallbackNotify " is to communicate with MapInfo COM
and to assure The interactivity between 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);
}

The problem is, this code is working just fine in Windows From but when i put it into WPF there is an ERROR msg :

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

and i cant figure out why or how to solve this problem

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

赠意 2024-12-02 01:10:14

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.dll 和 WindowsFormsIntegration.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
   }
}

Under the hood Windows Forms and WPF are very different.

ISynchronizeInvoke is a Windows Form concept built upon Win32 API that doesn't apply to WPF. In WPF, we use the Dispatcher for communicating between threads.

From your question it sounds like what you want to do is host a WinForms COM control inside a WPF application. In order to bridge these two technologies, Microsoft has a WindowsFormHost control that you can use to contain your component. This blog post has a pretty good write up on that. Checkout this MSDN example: https://msdn.microsoft.com/en-us/library/vstudio/ms751761(v=vs.100).aspx


Update:

It sounds like the problem you are having isn't at runtime but during compilation?? Let slow down and be clear:

In Windows Forms, all user controls and windows implement ISynchronizeInvoke. WPF isn't built on the traditional Win32 WinProc message pump, so they do not implement this interface. If you copy and paste your INotifyCallBack interface and implementation "as is" into the MainWindow.xaml.cs, you will get a compilation error because the base interface ISynchronizeInvoke is not implemented in that class. To bypass the compilation error you will have to implement the ISynchronizeInvoke signature:

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

But guess what? If you do this, it's up to you to provide the proper mapping between ISynchronizeInvoke and the WPF Dispatcher. So don't do this! The above code might compile but it likely won't work correctly (or at all).

Instead, use the Windows Form Integration capabilities provided by Microsoft to host your control inside a WindowsFormHost control. As you need to implement custom code in your INotifyCallback, you'll need to put that code into a custom windows forms user control.

All said, you need to follow the direction provided by the article listed above:

  • Reference System.Windows.Forms.dll and WindowsFormsIntegration.dll
  • Add the appropriate namespaces to your MainWindow.xaml
  • Add the WindowsFormsHost as a container into your MainWindow.xaml, and then put your custom control inside of that.

So instead of putting your ICallbackNotify implementation on the WPF MainWindow, put it in a standard Windows Form UserControl:

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

   public class MyCustomMapControl : UserControl, ICallbackNotify
   {
       // your custom code goes here
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文