由于工作原因,需要在程序中加入数学公式编辑功能,因此在网上找了不少开源数学公式程序。经过比较,最终选择了Math-Editor-master程序(可以在github上搜索此名称)。

我的程序(简称主程序)是采用.net framework 3.5+winform编写的,Math-Editor-master程序采用.net framework 4.0+WPF编写而成。在将数学编辑程序加入到主程序过程中,碰到了很多问题,现将这些问题一一叙述如下:

1 .net framework版本兼容

.net程序只能引用小于或者等于其.net framework版本的其它.net程序,因此第一步要做的是将Math-Editor-master程序使用的.net framework版本更改为3.5。这里碰到的问题主要是两个:

1) XAML文件中很多标签在.net framework 3.5中不能使用。对于不能使用的标签,直接删除。

2) 有几个类的函数无法使用。因为这些函数是在.net framework 4.0中新建的,采用扩展方法和辅助类的形式在.net framework 3.5中增加这些函数即可解决。

2 winform程序调用wpf窗口

winform程序中如果直接采用new方法创建一个wpf窗口实例,然后调用show的话,wpf窗口会接收不到window系统消息,这是因为winform窗口和wpf窗口的实现不一致造成的。为了能够正常使用wpf窗口,需要调用ElementHost.EnableModelessKeyboardInterop,该函数使Windows 窗体中以无模式方式打开时能正确地接收键盘消息。还有WindowInteropHelper类,它协助 Windows Presentation Foundation (WPF) 与 Win32 代码之间的互操作。

具体的使用示例如下:

Editor.MainWindow win = new Editor.MainWindow();

ElementHost.EnableModelessKeyboardInterop(win);

WindowInteropHelper inspector = new WindowInteropHelper(win);

inspector.Owner = this.Handle;

win.ShowDialog();

3 wpf窗口无法找到全局资源

应用上面一节所示的代码后,就可以在winfom程序中调用wpf窗口了。但由于Math-Editor-master程序中控件、窗口界面比较多,涉及到很多控件的样式,程序作者定义了全局的资源,供各控件、窗口调用。Math-Editor-master程序编译为独立运行的程序时,一切都正常,但当winfom程序中调用wpf窗口时,wpf窗口启动时报类似于“Cannot find resource named 'ToolbarButtonStyle'. Resource names are case sensitive”的错误。通过查找项目内容,发现'ToolbarButtonStyle'是一个样式定义,被定义在一个MainDictionary.xaml文件中。当Math-Editor-master程序独立运行时,该文件被包含在一个App.xaml(内容如下图)文件中作为全局资源被加载,资源文件中的内容被保存在System.Windows.Application.Current.Resources。由于winform程序中不包含System.Windows.Application.Current对象,wpf窗口也就无法从全局资源中找到需要的资源,从而导致wpf窗口启动时报上述的错误。

解决此错误的思路比较简单,就是在winfom程序中,调用wpf窗口之前,在程序中创建一个System.Windows.Application对象,然后将MainDictionary.xaml文件中的资源到去到System.Windows.Application.Current.Resources。有很多种方法实现该思路,你可以在google中搜索winfom+application-level resource+wpf进行搜索,也可以查找“Managing Application Resources when WPF is Hosted”,这篇文章介绍的特别详细。

我采用的方法如下:

public static void EnsureApplicationResources(){   if (Application.Current == null)   {          // create the Application object        new Application();       // merge in your application resources   Application.Current.Resources.MergedDictionaries.Add(Application.LoadComponent(newUri("/Editor;component/MainDictionary.xaml", UriKind.Relative)) as ResourceDictionary);    }}

只要在调用wpf窗口之前调用此函数,wpf窗口中涉及全局资源的引用就可以正常引用了。

4 wpf窗口无法加载资源文件

Math-Editor-master程序是一个比较复杂的wpf程序,它包含了很多的工具条图片和字体文件,这些内容都是动态加载的。Math-Editor-master程序编译为独立运行的程序时,一切都正常,但是作为winfom程序的一部分就无法正常运行,wpf窗口中的图片和字都不能正常显示。通过查找程序代码,发现在wpf窗口中加载图片和字体时都是采用的Uri的方式指定文件路径,路径如下图所示:

在图片路径中,application:,,,/images/commands指的是整个解决方案的启动项目下的images/commands目录,但实际上图片是放到Math-Editor-master项目的images/commands目录下,如果Math-Editor-master项目独立运行没有问题,但是Math-Editor-master项目作为winfom的一部分运行时,启动项目是winfom项目,导致Uri指定的路径错误。我解决图片路径问题的方法是采用Uri的另外一个构造函数,指定图片的相对路径,并且把application改为Editor(Math-Editor-master项目命名空间),这样图片路径变成了/Editor;component/images/commands ,这样就可以正确找到图片了。

字体无法显示的问题与图片类似,唯一的不同是FontFamily要求Uri为绝对路径,通过查找MSDB,发现只要将Uri路径修改为pack://application:,,,/Editor;component/STIX/,就可以了,其中application:,,,/Editor指后面的路径是应用程序的Editor程序集中的路径。

5 winfrom程序无法多次创建wpf窗口对象

所有上述问题解决后,就可以在winfom中正常调用wpf窗口了,而且数学公式、工具条都显示正常。但是如果主程序不关闭,第二次创建wpf窗口时,在函数EnsureApplicationResources中Application.Current会重新变成null,这时如果执行下面的new Application();代码,会报“不能在应用程序域中多次创建System.Windows.Application对象”的错误。

造成这个问题的主要原因是System.Windows.Application.ShutdownMode属性。这个属性用于设置何时将Application.Current对象关闭。该属性可以取值如下图所示,默认值为OnLastWindowClose。

通过查阅资料,OnLastWindowClose指当Application.Windows全部关闭时关闭Application对象,这里的窗口应该是指wpf窗口。所以在winform中调用wpf窗口,然后关闭wpf窗口,此时Application.Current被设置为null。

Winform调用wpf窗口时,应将System.Windows.Application.ShutdownMode属性设置为OnExplicitShutdown,然后在winform程序的main函数最后显式调用Application.Shutdown函数释放Application对象。这样问题就解决了。

在winform中调用wpf窗口的例子可以在如下链接中获取:

http://pan.baidu.com/s/1hqPNAOc

在C# winform程序中调用WPF写的数学公式编辑器相关推荐

  1. 在winform程序中启动wpf窗体

    有时候需要在winform程序中利用wpf的许多优良特性,如何在其中启动wpf窗体呢? 前提:MainWindow.xaml是从别的地方copy到这个项目的,值得注意的是,除了MainWindow.x ...

  2. 在WinForm应用程序中嵌入WPF控件(转)

      我们知道,在WPF界面上添加WinForm的控件需要使用WindowsFormHost类.而在WinForm界面上添加WPF控件该如何做呢?有没有类似的类呢?明显是有的,ElementHost就是 ...

  3. 我的WCF之旅(6):在Winform Application中调用Duplex Service出现TimeoutException的原因和解决方案...

    几个星期之前写了一篇关于如何通过WCF进行 双向通信的文章([原创]我的WCF之旅(3):在WCF中实现双向通信(Bi-directional Communication) ),在文章中我提供了一个如 ...

  4. C#中Winform程序中如何实现多维表头【不通过第三方报表程序】

    问题:C#中Winform程序中如何实现多维表头. 在网上搜了很多方法,大多数方法对于我这种新手,看的都不是很懂.最后在新浪博客看到了一篇比较易懂的文章:[DataGridView二维表头与合并单元格 ...

  5. 在WinForm程序中嵌入ASP.NET

    现在的流行趋势是桌面程序Web化,Web程序桌面化,呵呵.最终目标就是你中有我,我中有你.例如MSN Explorer就是一个很好的展示,让用户在使用的时候分不清什么时候是在本地什么时候是在网络.而这 ...

  6. 在Winform程序中设置管理员权限及为用户组添加写入权限

    在我们一些Winform程序中,往往需要具有一些特殊的权限才能操作系统文件,我们可以设置运行程序具有管理员权限或者设置运行程序的目录具有写入的权限,如果是在操作系统里面,我们可以设置运行程序以管理员身 ...

  7. 在WinForm程序中嵌入ASP.NET[转]

    在WinForm程序中嵌入ASP.NET 现在的流行趋势是桌面程序Web化,Web程序桌面化,呵呵.最终目标就是你中有我,我中有你.例如MSN Explorer就是一个很好的展示,让用户在使用的时候分 ...

  8. (转)在Winform程序中设置管理员权限及为用户组添加写入权限

    本文转载自:http://www.cnblogs.com/wuhuacong/p/5645172.html 在我们一些Winform程序中,往往需要具有一些特殊的权限才能操作系统文件,我们可以设置运行 ...

  9. 安卓程序中调用 linux 命令

    博客: 安卓之家 微博: 追风917 CSDN: 蒋朋的家 简书: 追风917 在研究串口 jni 开发的时候,遇到了这样一段代码: Process su;su = Runtime.getRuntim ...

最新文章

  1. “Python之父”从Dropbox退休
  2. 5.Xilinx RapidIO核例子工程源码分析
  3. hibernate+mysql时,会出现事物不管用
  4. 【SVM】A Practical Guide to Support Vector Classication
  5. 算法杂货铺——分类算法之决策树(Decision tree)
  6. 腾讯开源手游热更新方案,Unity3D下的Lua编程
  7. LeetCode 1877. 数组中最大数对和的最小值(贪心)
  8. HTTP和HTTPS的主要区别(面试常考)——计算机网络
  9. collatz序列 python程序_Python Collatz序列实现过程解析
  10. cdn搭建原理_直播平台搭建并不难,最难的是这两点
  11. Angular开发实践(五):深入解析变化监测
  12. 微服务系列:分布式日志 ELK 搭建指南
  13. 如何用美剧真正提升你的英语水平(转载)
  14. 手机显示主服务器连接异常怎么办,手机主服务器连接配置异常
  15. [PyG] 1.如何使用GCN完成一个最基本的训练过程(含GCN实现)
  16. Android各版本的版本号、版本名、API及发布时间
  17. Unity学习笔记:Animator、Animator Controller、Animation Cilp之间的关系、以及Blend Tree的用法;
  18. 新彩虹世界密码系统是多少_希望最近的世界密码日是我们需要的最后一个
  19. 银联进件渠道教程-云闪付收银台最新方法(可对接易支付)
  20. 国外LEAD网站采集你会了吗

热门文章

  1. STM32F103Mini移植RT-ThreadNano
  2. 二分查找 二分答案 万字详解,超多例题,带你学透二分。
  3. BatchFormer:有效提升数据稀缺场景的模型泛化能力|CVPR2022
  4. uNo面板L灯一直闪_单开双控什么意思?单开双控开关接线图和面板接法图解
  5. springBoot上传文件
  6. Odyssey 2022 | 希尔贝壳受邀参加国际顶级说话人和语种识别研讨会
  7. 如何攻击深度学习系统?--可解释性及鲁棒性研究
  8. 煽情的儿子535=随笔
  9. iOS密码查找工具:4uKey Password Manager for Mac
  10. Vmware+UOS-server-1050e虚拟机安装(含软件链接)