WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit) 一文中,我们说到了在 WPF 中引入简单的 UWP 控件以及相关的注意事项。不过,通常更有实际价值的是更复杂的 UWP 控件的引入,通常是一整个 Page。

本文将介绍如何在 WPF 项目中引用 UWP 的控件库。


创建一个 UWP 控件库

建议专门为你复杂的 UWP 控件创建一个 UWP 控件库。在这个控件库中的开发就像普通 UWP 应用一样。这样比较容易创建出更复杂的 UWP 控件出来,而不会与 WPF 项目产生太多的影响。


▲ 创建一个 UWP 控件库


▲ 选择 SDK 版本

对 WPF 项目的准备工作

你依然需要阅读 WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit) 一文,以便将你的 WPF 项目改造成可以访问 UWP 类型的项目。

不方便的引入方式

你如果直接让 WPF 项目添加 UWP 项目的引用,将会得到一个错误提示:

也就是说并不能直接完成这样的引用。

也许将来 WPF 项目格式更新或者 Visual Studio 的更新能为我们带来这样更直接此引用方式。不过现在来看,还不能如此方便地使用。

编辑 UWP 项目文件

是的,你需要手工编写 UWP 的项目文件。

如果你阅读过 (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序 这篇文章,或者已经 理解了 C# 项目 csproj 文件格式的本质和编译流程,那么对这里 csproj 文件的编辑应该不会感觉到陌生或者害怕。当然,即便你没有编辑过或者不理解 csproj 也不用担心,你只需要按照本文要求进行操作即可。

现在,右击卸载项目,再右击编辑项目文件:


▲ 编辑项目文件

找到 Import targets 的哪一行,你需要在那一行前面的任意位置添加以下特别标注为新增的几行:

++  <PropertyGroup>
++ <EnableTypeInfoReflection>false</EnableTypeInfoReflection>
++ <EnableXBindDiagnostics>false</EnableXBindDiagnostics>
++ </PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />

随后,还要在以上 targets 之后再添加以下代码:

<PropertyGroup>
<!-- 这里需要填写你的 WPF 项目的路径 -->
<HostFrameworkProjectFolder>$(ProjectDir)..\Whitman.Wpf</HostFrameworkProjectFolder>
<ObjPath>obj\$(Platform)\$(Configuration)\</ObjPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<ObjPath>obj\$(Configuration)\</ObjPath>
</PropertyGroup>
<PropertyGroup>
<!-- 把此项目的输出文件都拷贝到 WPF 项目的生成路径下 -->
<PostBuildEvent>
md $(HostFrameworkProjectFolder)\$(ProjectName)
md $(HostFrameworkProjectFolder)\bin\$(Configuration)\$(ProjectName)
copy $(TargetDir)*.xbf $(HostFrameworkProjectFolder)\bin\$(Configuration)\$(ProjectName)
copy $(ProjectDir)*.xaml $(HostFrameworkProjectFolder)\bin\$(Configuration)\$(ProjectName)
copy $(ProjectDir)*.xaml.cs $(HostFrameworkProjectFolder)\$(ProjectName)
copy $(ProjectDir)$(ObjPath)*.g.* $(HostFrameworkProjectFolder)\$(ProjectName)
</PostBuildEvent>
</PropertyGroup>

需要注意:

  • 一定要在 targets 之后添加这些代码,因为 $(TargetDir)$(ProjectName) 等属性是在那里的 targets 执行完后才生成的。
  • 你的 UWP 项目中需要有 xaml,比如可以添加一个 MainPage.xaml 和 MainPage.xaml.cs,不然编译的时候可能会出现错误。

重新加载项目并编译

现在,重新加载那个 UWP 控件库,将其编译,以便将 UWP 项目的生成文件复制到 WPF 目录下。


▲ 生成的文件已复制到 WPF 目录下

在 WPF 项目中间接引用 UWP 控件库

现在,在 WPF 项目中开启所有文件夹的显示,然后将 UWP 项目中生成的文件添加到 WPF 项目中:


▲ 在 WPF 的项目中添加 UWP 的控件库

为了能够在每次编译 WPF 项目的时候确保 UWP 项目先编译,需要为 WPF 项目设置项目依赖。在依赖对话框中将 UWP 项目设为依赖。


▲ 添加项目依赖

现在,编译 WPF 项目的时候,会将 UWP 项目编译后的源码也一起编译到 WPF 项目中;相当于间接使用了 UWP 的控件库。

特别的,如果你的项目被 git 进行版本管理,你可能需要忽略 UWP 控件库项目中的文件。方法是在 WPF 项目内生成的 UWP 文件夹下添加一个 .gitignore 文件,填写所有内容忽略:

*.*

但记得需要额外通过 git add ./Whitman.Wpf/Whitman.Uwp/.gitignore 把这个文件添加到版本管理中,不然其他人不会生效。

在 WPF 项目中使用 UWP 控件库中的控件

这时,在 WindowsXamlHost 中就可以添加 UWP 控件库中的 MainPage 了。

<XamlHost:WindowsXamlHost InitialTypeName="Walterlv.Whitman.Universal.MainPage" />

于是,你可以在局部获得 UWP 完整 Page 的支持。或者你整个界面都是用 UWP 开发都没问题,并且还能获得 .NET Framework 的完全访问支持。(当然,未来一定是 .NET Core。)


▲ 运行后的效果

可以使用 UWP 的 Page,并且也能弹出 UWP 的 MessageDialog

而 MainPage 就是普通的 UWP MainPage:

<Page
x:Class="Walterlv.Whitman.Universal.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Walterlv.Whitman.Universal"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Width="400" VerticalAlignment="Center">
<TextBlock>
<Run Text="欢迎访问 吕毅的博客" />
<LineBreak />
<Run Text="https://walterlv.com" />
</TextBlock>
<Button Content="Click" Click="DemoButton_Click" />
</StackPanel>
</Page>
using System;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; namespace Walterlv.Whitman.Universal
{
public sealed partial class MainPage : Page
{
public MainPage() => InitializeComponent(); private async void DemoButton_Click(object sender, RoutedEventArgs e)
{
var button = (Button) sender;
await new MessageDialog("UWP 的消息框,在 WPF 的窗口中。", "walterlv").ShowAsync();
}
}
}

参考资料

WindowsXamlHost:在 WPF 中使用 UWP 控件库中的控件的更多相关文章

  1. WPF 控件库——轮播控件

    WPF 控件库系列博文地址: WPF 控件库——仿制Chrome的ColorPicker WPF 控件库——仿制Windows10的进度条 WPF 控件库——轮播控件 WPF 控件库——带有惯性的Sc ...

  2. 【ExtAspNet学习笔记】ExtAspNet控件库中常见问题

    1.在Grid控件中添加CheckBoxField控件,选择一行时,如何获取选择的CheckBoxField所对应记录的唯一标识值? ●解决方案: 在前台Grid控件中, 添加“<ext:Che ...

  3. 项目中通过Sorlj获取索引库中的数据

    在开发项目中通过使用Solr所提供的Solrj(java客户端)获取索引库中的数据,这才是真正对项目起实质性作用的功能,提升平台的检索性能及检索结果的精确性 第一步,引入相关依赖的jar包 第二步,根 ...

  4. WPF Devexpress 控件库中ChartControl 实现股票分时走势图

    概要 从事金融行业开发 ,会接触些图表控件,这里我分享一下自己基于DevExpress.Charts.v16.2开发的股票分时走势图的经验. 附上源码:点击跳转 如果需要讨论,Q群:580749909 ...

  5. WPF Devexpress控件库中ChartControl--实现不等距x轴

    一.概要 解决问题--ChartControl不等距x轴显示 二.CS代码 用过ChartControl的开发者们应该都知道,ChartControl中设置x轴间距间隔都是固定的数值. 比如(间隔10 ...

  6. DSAPI+DS控件库 Windows7风格控件演示

    效果图 部分代码 DSAPI.Win7特性.任务栏特效.初始化() '这句非常重要,很多对任务栏特性的操作都需要先初始化 DSAPI.Win7特性.设置任务栏窗口缩略图(Me, My.Resource ...

  7. 在DLL中导出另一静态库中的函数

    开发环境: win7_x64.VS2013 应用场景: 动态库A依赖动态库B,而动态库B又使用了静态库C:有些情况下,我们需要将C从B里面导出,然后提供给A使用. 正文: Step1: 1.新建测试静 ...

  8. Swift中如何化简标准库中冗长的类实例初始化代码

    可能有些童鞋并不知道,在Swift中缩写点符号对于任何类型的任何static成员都有效. 我们实际写一个例子看一下: import UIKit class CFoo{ static let share ...

  9. WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit)

    Windows Community Toolkit 再次更新到 5.0.以前可以在 WPF 中使用有限的 UWP 控件,而现在有了 WindowsXamlHost,则可以使用更多 UWP 原生控件了. ...

随机推荐

  1. oauth2(转载http://www.rollosay.com/it/%E4%BD%BF%E7%94%A8OAuth-Server-PHP%E5%AE%9E%E7%8E%B0OAuth2%E6%9C%8D%E5%8A%A1)

    http://www.rollosay.com/it/%E4%BD%BF%E7%94%A8OAuth-Server-PHP%E5%AE%9E%E7%8E%B0OAuth2%E6%9C%8D%E5%8A ...

  2. 使用Linux重定向解决nohup.out无写权限问题

    ■场景 执行nohup命令的时候,经常会出现下面这种没有写入权限的错误. nohup: ignoring input and appending output to `nohup.out'nohup: ...

  3. bzoj1607 / P2926 [USACO08DEC]拍头Patting Heads

    P2926 [USACO08DEC]拍头Patting Heads 把求约数转化为求倍数. 累计每个数出现的个数,然后枚举倍数累加答案. #include<iostream> #inclu ...

  4. 2017-2018-1 JaWorld 团队作业--冲刺7

    2017-2018-1 JaWorld 团队作业--冲刺7 冲刺博客 冲刺1 冲刺2 冲刺3 冲刺4 冲刺5 项目完成情况 存在的问题 存在的问题是敌机只设置了一种,没能实现多种敌机的游戏设置. 界面 ...

  5. 基于ARM、linux的MF RC522射频读卡器

    摘要:本设计将ARM.linux的嵌入式技术与RFID技术相结合,对于实现移动支付终端的低功耗.便携式和网络化具有特别的意义.首先是采用MF RC522芯片设计与制作读写器,实现对Mifare卡的读写 ...

  6. python 去除不可见的控制字符

    尤其是在json load的时候,字符串中的不可见控制字符可能会导致错误,应该先对字符串进行控制字符过滤. 对网页文本同样适用,最好在处理网页文本时先进性控制字符清洗. Replace null by ...

  7. POJ 1780 Code(欧拉回路+非递归dfs)

    http://poj.org/problem?id=1780 题意:有个保险箱子是n位数字编码,当正确输入最后一位编码后就会打开(即输入任意多的数字只有最后n位数字有效)……要选择一个好的数字序列,最 ...

  8. POJ 1637 Sightseeing tour(混合图欧拉回路+最大流)

    http://poj.org/problem?id=1637 题意:给出n个点和m条边,这些边有些是单向边,有些是双向边,判断是否能构成欧拉回路. 思路: 构成有向图欧拉回路的要求是入度=出度,无向图 ...

  9. JavaScript获取输入框内容

    html: <input name="money" type="number" placeholder="税前工资"><b ...

  10. 自己喜欢用的一个初始化的common.css

    body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, p, blockquote ...