【问题标题】:Implement WinForms using WPF?使用 WPF 实现 WinForms?
【发布时间】:2009-10-29 03:52:01
【问题描述】:

这个问题是与同事在午餐时间交谈的结果...我读过类似WPF vs. Winforms 的问题...我个人认为长期 WPF 是要走的路。问题/问题是在此期间要做什么。

是的,WPF 确实有它的优势;不是基于 GDI/USER 构建的就是其中之一。但是在这个时间点(即 2009 年末;使用 VS2008 甚至可能是 VS2005;Silverlight3 最近发布但尚未广泛采用/部署),WPF 几乎看起来可能是一个“过度设计”的解决方案。虽然我确信这会随着时间的推移而改变,但它不会让今天的事情变得更容易,也不会在近期(比如

让我们面对现实吧,WinForms 真的简单易行;尤其是对于许多仍在“快乐”使用 MFC 的同事来说。是的,可能很难做流畅的动画、3D 图形、渐变等;但这是一个非常实用的解决方案,很多人(即 C++/MFC 开发人员)现在很容易理解

有了这个冗长的介绍——有没有人想过/累/等等。关于使用 WPF(即 WinForms sans GDI/USER)实现(大部分)WinForms 的想法?我敢肯定,考虑到Control.Handle 之类的东西,100% 的重新实现是不可能的。但似乎许多 WinForms 控件可以使用 WPF“在后台”重新实现。或者这真的不可能吗?

通过“重新实现”,我设想删除对 System.Windows.Forms 的程序集引用,用(比如说)Microsoft.Wpf.WinForms 替换它们,然后重建我的应用。之后,我希望修复一些(相对较少的)编译器和/或运行时错误(比如 P/Invokes to Win32 APIs)。

这样的东西似乎是对 Microsoft 的各种 WinForms/WPF 互操作策略(例如 WindowsFormsHost)的一个很好的补充。例如,开发人员可以开始以更加渐进的方式使用/学习 WPF。

编辑:虽然各种“为什么?”讨论很有趣,但他们没有回答基本的技术问题:“是的,..这是如何......;或者不是,......因为......”。

【问题讨论】:

  • 我知道你的目的是什么,但这真的值得这么麻烦吗?

标签: .net wpf winforms


【解决方案1】:

老实说,我认为您可能可以实现一个层来允许您将大部分 WinForms 移植到 WPF,但您确实不应该这样做。让我打个比方——从 WinForms 迁移到 WPF 就像从命令式语言迁移到面向对象的语言(或从 OO 迁移到纯函数式语言)。这真的很难,似乎没有任何工作正常,解决方案没有意义,一切似乎都过度设计,然后......你明白。您灵光一现,灯泡亮了,您会看到一个全新的世界,其中的任务更容易完成和维护(比在 WinForms 中)。

但首先你必须了解它。在 WPF 中保持 WinForms 风格的编码真的很容易,所以你必须强迫自己不要这样做,否则你永远不会采取下一步行动。强迫自己从头开始,学习如何应用 MVVM,看看 Prism,构建一些非常简单的应用程序,然后添加到它们以探索如何以 WPF 方式管理复杂性。您可能会在 WPF 中实现 WinForms,但您所拥有的只是人们在 WPF 中编写 WinForms。基本上,您最终得到的结果相当于(从命令式 -> OO 时代)使每个类都成为具有所有静态方法的单例。您可能正在“使用” WPF,但您(和/或您的同事)永远不会超过那个阶段。

根据我从您的情况中收集到的信息,我建议您不要尝试切换到 WPF,除非您正在与一个小团队一起编写新的应用程序。如果最终确实如此,那么小团队可以成为变革的核心,因为一旦您组织中的一个人“了解”了它,他们就会教他们附近的其他人,直到整个地方的灯泡开始亮起。这就是我们在我目前的组织中所做的事情,回顾过去 6 个月中每个人所取得的进步是惊人的。

【讨论】:

  • 老实说,这实际上是一个很好的类比。我完全记得有一个你正在谈论的灯泡时刻,我记得我之前的挣扎。我也支持您的建议 - Winforms 不会很快消失,没有必要将复杂的已经混合的应用程序移植到 WPF 没有非常令人信服的理由。
【解决方案2】:

我不确定我是否理解您的问题 - 已经可以像 Winforms 一样使用 WPF 库(在没有 XAML 的代码中组装所有内容),并且大多数常见的 Winforms 控件都有其直接的 WPF 类似物。

真正的问题是您为什么要这样做?使用 WPF 数据绑定和模板技术可以轻松解决开发 Winform 应用程序的许多重大挑战。

我什至不是在谈论花哨的视觉效果,它只是在 winforms 中花费太多的工作,而只是像可视化集合中任意项目的列表。

此外,如果您以 Winforms 风格的代码组装所有内容,您将无法获得设计时编辑支持。

【讨论】:

  • 如果没有 xaml,使用 wpf 几乎与使用 winforms 相同 - 如果有人要经历为 Visual Studio 创建设计器插件的所有麻烦,您可能会以这种方式使用它。就像在 winforms 中一样,您可以拥有一个庞大的设计器生成的函数来创建和定位子控件。但说真的,这是错误的做法。我知道在 WPF 模式下开始思考很困难,这对我来说也不是一个容易的改变。但它在不到 36 个月的时间内就获得了巨大的回报。
  • 我的第一个 WPF 应用程序基本上是 winform 应用程序 - 控件的 xaml 部分基本上就像旧的 .designer.cs 文件一样,其他一切都在代码隐藏文件中完成。因此,很有可能已经以类似方式的 winform 使用 WPF。当然,一旦我了解了 datatemplates、controltemplates、wpf 风格的数据绑定以及 MVVM 的好处,用旧的方式做事很快就变得几乎无法忍受了。
  • 哦,我当然明白。切换平台从来都不是一个简单的过程,只有当组织更大时才会变得更加困难。所以是的,如果切换非常困难,那么对于您当前的需求可能不值得。在这种情况下,我认为您最好继续使用 Winforms - 这绝不是一个不合理的决定。但是,如果您想使用 WPF,您可能应该花一些时间学习该平台,作为一个整体。
  • “大多数常见的 Winforms 控件都有其直接的 WPF 类似物。”确切地。如果您想要没有 GDI/用户的 Windows 窗体,据我所知,您已经拥有它。您可能需要使用一些第三方控件,但差距正在迅速填补。没有人强迫您使用 WPF 的非“实用”功能。丹,您能否更具体地说明您要缩小的差距是什么?是设计师支持吗?
  • 好的,既然我读了你的编辑,我想我明白你想看什么了。我不确定创造这样的东西的挑战是否真的值得。在试图调和两者的根本差异时,您似乎不可避免地会遇到两种平台的一些奇怪的混合。在 WPF 应用程序中托管 Winfom 控件(反之亦然)对我来说似乎是一个不错的折衷方案。
【解决方案3】:

首先,WPF 没有“过度设计”。我会说它的设计非常完美,因为要实现一个 UI 框架是一项极其复杂的工作,该框架在单个平台上支持丰富的可组合性、丰富的数据绑定、2D 和 3D。

WPF 有一个轻微的学习曲线,但不是很陡峭,并且是分阶段进行的。给自己2天的时间,你永远不会回头。 WinForms 很容易做简单的事情。 WPF 对任何事情都很容易,而您通过其广泛的可组合性和数据绑定所拥有的功能将使 WinForms 为比您最基本的应用程序更复杂的任何事情感到羞耻。

至于重新实现 WinForms 控件...几乎不需要。许多第三方提供的高度复杂的 WinForms 控件只是需要,因为自定义任何 WinForms 控件的 UI 非常困难。使用 WPF,增强任何 OOB 控制都很容易,而且几乎是无限的。

我强烈推荐 WPF 作为首选的 UI 平台,除非您的目标硬件无法呈现 WPF。

【讨论】:

  • 今天、昨天或明天,它仍然不是一个过度设计的解决方案。如果您的同事无法掌握它,那么请务必继续使用 WinForms。但是,如果您认为他们有能力掌握它,并且只是因为它是新事物而与之抗争,那么我认为避免它是一个糟糕的决定。进步有时需要痛苦,如果只是为了在忍受痛苦后比以前更轻松。
【解决方案4】:

给你的同事打个比方:

汽车和马车哪个更好?

  1. 汽车不像马车那样成熟。马和马车已经有 2000 多年的历史了,汽车不到 200 年。

  2. 汽车设计过度且极其复杂。马和马车很简单。

  3. 世界上许多地方的人都不会开车,但对马和马车有很好的技能。

问题:我们能否简化我们的汽车,使其由缰绳控制、吃干草并由兽医和马车制造商维修?

我的观点是,WPF 目前是一项非常成熟的技术,比 WinForms 更强大、更易于使用,而且一点也不难学。除了“乡村驾驶”和其他特殊目的之外,它应该是首选车辆。

我同意其他人的观点,即以类似 WinForms 的方式使用 WPF 是微不足道的,因此如果您想以这种方式使用 WPF,则不需要显着的学习曲线,但不利用新范例是浪费.

我不同意您应该延迟在主应用程序中实现 WPF。在单个应用程序中混合 WinForms 和 WPF 内容非常容易且轻松。我建议在 WPF 中构建新部分并将旧部分保留在 WinForms 中,直到需要接触某些东西。即使您现有的应用程序是本机 C++,只要可以从托管代码轻松访问数据,使用 WPF 仍然很容易。

【讨论】:

  • 1900 年,汽车还很原始。 WPF 是一项非常成熟的技术,可以与当今的汽车相媲美。您缺少的是您所在地区的基础设施。一个更好的比较是决定今天在第三世界国家购买汽车还是马车。当然,建设 WPF 基础设施所需的几周时间远比加油站、汽车修理店等要便宜得多,而这些设施是在孟加拉国偏远村庄方便使用汽车所需的。但是,很难知道如何处理您的马鞍和剩余的干草。 :-)
  • 更严肃的一点是:我在很多 WinForms 集成的东西上也遇到了同样的情况。我花了大约三周的时间才使这一切都与 WPF 一起工作。我为每个功能位创建了一个干净的 WPF API,然后编写了垫片以允许 WinForms 代码使用新的 API 而无需任何代码更改。通过 WPF 更高的生产力,我花费的时间在一个月内很容易得到回报。
  • @Dan:这就是为什么你同时使用你所拥有的 Winforms/MFC 来满足你的需要,并且在那段时间里你基于现在的工作进行开发并使它在WPF。您不会停止为正在开发和测试中的东西工作的东西!在 WPF 中开发所需的时间比 Winforms 少,比 MFC 少得多。
【解决方案5】:

一个叫做WindowsFormsHost 的东西可以帮助最初移动控件。但是,我发现它非常慢。花时间学习 WPF 并从头开始编写所有内容并利用这些功能(尤其是数据绑定)会更好!

【讨论】:

    【解决方案6】:

    您确实必须从您正在创建的应用程序生命周期的长期角度来看待它。虽然 WPF 可能不如 Windows 窗体成熟,但它允许程序员分离设计 (XAML) 和逻辑 (C#/VB)。我不相信如果您在 WPF 中以 Windows 窗体样式创建控件会很好。想象一下将来出于某种原因将其全部放回 XAML 中!

    话虽如此,如果您真的希望将一些 Windows 窗体的控件引入 WPF,这是完全可能的。您只需添加对 WindowsFormsIntegration 的引用,在代码中为其添加适当的命名空间,并在 XAML 中添加 WindowsFormsHost 标记。在我看来,使用它应该只是暂时的(目前它相当慢)。另一方面,未来的框架很可能会使 WPF 变得更好(我认为是 4.0)。

    现在学习 WPF 可能是您能做的最好的事情。开始了解 Windows 窗体中某些缺少的控件并使用 WPF 工具包可能会有点耗时,因为有些东西与 Windows 窗体不同(想到控件自定义和数据绑定)。

    如果您继续使用 Windows 窗体,您将错过 WPF 中加快开发速度的新功能。例如,由于设计和逻辑的分离更加明显,您可以让其他人从事设计工作,而其他人则从事应用程序的逻辑方面的工作。

    【讨论】:

    • 没错,所以从现在开始只会给您带来优势...我相信人们将不得不以某种方式改变和使用现代技术。 WPF 在某种意义上是 Windows 窗体的正常延续,就像 Windows 7 是 Windows Vista 和 Windows XP。
    • @Dan 有一天刚来上班,臀部上挂着一把塑料枪,说“我们从今天开始使用 WPF,任何人都有这个问题”。当然要确保枪清晰可见;)
    • C++/MFC 是一种费力且缓慢的接口创建方式。某些语言更适合某些任务,而其他语言则不然。可以肯定的是,C++/MFC 允许比 .NET 语言更高效的代码,但这真的很耗时!虽然您的公司需要一年时间来使用 C++/MFC 创建这个超快速的应用程序,但另一家(可能是竞争对手的公司)正在使用 WPF 创建 5 个应用程序并因此赚更多的钱。
    • 当然 C++/MFC 并没有过时,但对于当前可用的其他技术所能完成的工作,成本实在是太高了。此外,对于今天的计算机,使用 C#/VB 制作的应用程序,即使它不如用 C++ 制作的应用程序高效,也可以毫无问题地运行。
    • 准确地说,向 MFC 程序员表明是时候转换的方法是证明许多需要用 MFC 解决数周才能解决的问题可以用 WPF 在几分钟内完成。 MFC 非常高效、真实,但在创建和维护方面也非常耗费人力。当然……问题是切换到 WPF 后,您可能会发现不再需要 100 多个程序员来处理工作量。
    猜你喜欢
    • 2023-03-03
    • 2011-03-05
    • 2011-06-24
    • 1970-01-01
    • 2015-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    相关资源
    最近更新 更多