本文介绍不那么常见的 WPF 相关的知识。


在 C# 代码中创建 DataTemplate

大多数时候我们只需要在 XAML 中就可以实现我们想要的各种界面效果。这使得你可能已经不知道如何在 C# 代码中创建同样的内容。

比如在代码中创建 DataTemplate,主要会使用到 FrameworkElementFactory 类型。

可以参考:

多个数据源合并为一个列表显示

WPF 提供 CompositionCollection 用于将多个列表合并为一个,以便在 WPF 界面的同一个列表中显示多个数据源的数据。

<ListBox Name="WalterlvDemoListBox">
    <ListBox.Resources>
        <CollectionViewSource x:Key="Items1Source" Source="{Binding Items1}"/>
        <CollectionViewSource x:Key="Items2Source" Source="{Binding Items2}"/>
    </ListBox.Resources>
    <ListBox.ItemsSource>
        <CompositeCollection>
            <CollectionContainer Collection="{Binding Source={StaticResource Items1Source}}" />
            <CollectionContainer Collection="{Binding Source={StaticResource Items2Source}}" />
            <ListBoxItem>Walterlv End Item 1</ListBoxItem>
            <ListBoxItem>Walterlv End Item 2</ListBoxItem>
        </CompositeCollection>
    </ListBox.ItemsSource>
</ListBox>

关于 CompositeCollection 的使用示例可以参考:

神樹桜乃写了一份非 WPF 框架的版本,如果希望在非 WPF 程序中使用,可以参考:

使用附加属性做缓存,避免内存泄漏

在没有使用 WPF 的时候,如果我们要为一个对象添加属性或者行为,我们可能会使用字典来实现。但字典带来了内存泄漏的问题,要自己处理内存泄漏问题可能会写比较复杂的代码。

然而,WPF 的附加属性可以非常容易地为对象添加属性或者行为,而且也不用担心内存泄漏问题。

例如,我曾经用 WPF 来模拟 UWP 流畅设计(Fluent Design)中的光照效果,使用附加属性来管理此行为则完全不用担心内存泄漏问题:

使用 ConditionalWeakTable 做非 WPF 版本的缓存

如果你有一些非 WPF 的对象需要做类似 WPF 那种附加属性,那么可以考虑使用 ConditionalWeakTable 来实现,Key 是那个对象,而 Value 是你需要附加的属性或者行为。

这里的引用关系是 Key 引用着 Value,如果 Key 被回收,那么 Value 也可以被回收。

使用代码模拟触摸

WPF 默认情况下的触摸是通过 COM 组件 PimcManager 获取到的,在禁用实时触摸后会启用系统的 TOUCH 消息获取到,如果开启了 Pointer 消息那么会使用 POINTER 消息。

我们可以继承自 TouchDevice 来模拟触摸,详见:

模拟 UWP 界面

在现有的 Windowing API 下,系统中看起来非常接近系统级的窗口样式可能都是用不同技术模拟实现的,只是模拟得很像而已。

如果要将 WPF 模拟得很像 UWP,可以参考我的这两篇博客:

模拟 Fluent Design 特效

目前 WPF 还不能直接使用 Windows 10 Fluent Design 特效。当然如果你的程序非常小,那么模拟一下也不会伤害太多性能:

然而充分利用 Fluent Design 的高性能,需要上 XAML Islands,详见:

  • [Using the UWP XAML hosting API in a desktop application - Windows apps Microsoft Docs](https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/using-the-xaml-hosting-api)

本文会经常更新,请阅读原文: https://dotnet-campus.github.io//post/those-people-dont-know-about-wpf.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 dotnet 职业技术学院 (包含链接: https://dotnet-campus.github.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系