【Win 10 应用开发】UI Composition 札记(三):与 XAML 集成
除了 DirectX 游戏开发,我们一般很少单独使用 UI Composition ,因此,与 XAML 互动并集成是必然结果。这样能够把两者的优势混合使用,让UI布局能够更灵活。
说到与 XAML 的集成,则我们必须先认识一位伙计,他非常重要,位于 Windows.UI.Xaml.Hosting 命名空间下,名叫 ElementCompositionPreview ,有了它,我们才可以在 XAML 元素与 Composition UI 元素之间游走。来看看它都公开了哪些成员。
public sealed class ElementCompositionPreview : IElementCompositionPreview
{ public static void SetImplicitShowAnimation(UIElement element, ICompositionAnimationBase animation); public static void SetImplicitHideAnimation(UIElement element, ICompositionAnimationBase animation); public static void SetIsTranslationEnabled(UIElement element, bool value); public static CompositionPropertySet GetPointerPositionPropertySet(UIElement targetElement); public static Visual GetElementVisual(UIElement element); public static Visual GetElementChildVisual(UIElement element); public static void SetElementChildVisual(UIElement element, Visual visual); public static CompositionPropertySet GetScrollViewerManipulationPropertySet(ScrollViewer scrollViewer);
}
这个类公开的方法都是静态的,无需实例调用。我们不要急于弄懂每个方法的作用,这样会把自己带入死胡同。此处,我们先重点掌握以下几个方法的用法。
1、GetElementVisual:要使 XAML 元素与 Composition API 交互,这个方法特别要紧,通过调用它,我们可以得到 XAML 元素中的 Composition UI 树的表示元素,并且能获取到关联的 Compositor 对象,有了关联的 Compositor实例,我们才能创建各种 UI 元素。
2、SetElementChildVisual:当我们使用 Composition API 创建完自定义的 UI 元素后,要调用这个方法把它插入到 XAML 对象的可视化树中。注意,UI 元素总是被插入到可视化树的最后一个位置,因此,我们自己组装的元素总是会挡住原来的 XAML 元素的。这个你得注意。
3、GetElementChildVisual:只有你调用过 SetElementChildVisual 方法把自定义 Visual 元素加入过可视化树,才能调用这个方法,这个方法就是返回你上一次插入的元素。如果你没有插入过自定义的可视化元素,则该方法会返回 null。注意,不要把这个方法跟 GetElementVisual 方法混淆,两者不同。GetElementVisual 方法是获得与目标 XAML 对象关联的可视化对象,而 GetElementChildVisual 方法是获取你上一次插入到可视化树的自定义元素。
下面给大伙看一个例子。
在页面上,我放了一个 Border 对象。
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Border Name="bd" Background="Black"/>
</Grid>
顺便把它的背景设置为黑色,方便后面看电影。
切换到代码文件,现在我们自定义组装一下UI,然后插入到 Border 元素的子树中。
public MainPage()
{
this.InitializeComponent();
CompositMyVisual();
} void CompositMyVisual()
{
Visual visualForbd = ElementCompositionPreview.GetElementVisual(bd);
// 组建UI
Compositor compos = visualForbd.Compositor;
// 根元素
ContainerVisual rootvs = compos.CreateContainerVisual();
// 第一个可视化元素
SpriteVisual v1 = compos.CreateSpriteVisual();
v1.Brush = compos.CreateColorBrush(Colors.Green);
v1.Size = new Vector2(450f, 300f); //大小
v1.Offset = new Vector3(30f, 20f, -1f); //位移
rootvs.Children.InsertAtTop(v1);
// 第二个可视化元素
SpriteVisual v2 = compos.CreateSpriteVisual();
v2.Brush = compos.CreateColorBrush(Colors.SkyBlue);
v2.Size = new Vector2(400f, 400f);
v2.Offset = new Vector3(180f, 125f, 0f);
rootvs.Children.InsertAtTop(v2); // 这一句很重要
ElementCompositionPreview.SetElementChildVisual(bd, rootvs);
}
记得,在组装完UI元素后,要调用 ElementCompositionPreview.SetElementChildVisual方法,把自定义的元素插入到可视化树中。
在前面的博文中,老周介绍过,ContainerVisual 是个容器元素,它公开一个 Children 集合,我们可以向其中添加子元素,这里头有四个方法我们可以调用。
1、InsertAtTop :子元素会始终位于其他元素的顶部,所以这个元素会遮挡住其他元素。
2、InsertAtBottom:所添加的子元素始终在显示层的底部,它会被其他元素遮挡。
3、InsertAbove:把当前子元素放到某个元素之上。比如我们可以明确指定让当前元素位于 A 元素之上,这使得当前元素可能遮挡住 A 元素。
4、InsertBelow:把当前元素放到某个元素的下方。如果当前元素放在 A 元素下面,那么,该元素可能被 A 元素遮挡。
我们看看这个例子的效果。
在上面的代码中,第一个元素是绿色画刷填充的,第二个是天蓝色的,而我们在插入元素树时,都把它们放到所有元素的顶部。
rootvs.Children.InsertAtTop(v1);
rootvs.Children.InsertAtTop(v2);
都位于顶部,那么后加上去的元素就会挡住前面的元素,所以我们看到,天蓝色的那块区域挡住了绿色区域的一部分。
使用这种交互,我们还可以很轻松地对 XAML 元素进行三维旋转。
这个例子的界面分为两部分。左边咱们放三个滑块,分别调节 XAML 对象在 X、Y、Z 轴上的旋转角度,范围在 -90 到 90 之间。
<Slider Name="sldX" Header="X 轴" Maximum="90" Minimum="-90" SmallChange="1" StepFrequency="1" Value="0" ValueChanged="OnSliderValChanged"/>
<Slider Name="sldY" Header="Y 轴" Maximum="90" Minimum="-90" SmallChange="1" StepFrequency="1" Value="0" ValueChanged="OnSliderValChanged"/>
<Slider Name="sldZ" Header="Z 轴" Maximum="90" Minimum="-90" SmallChange="1" StepFrequency="1" Value="0" ValueChanged="OnSliderValChanged"/>
界面的右边是一个矩形。
<Rectangle Grid.Column="1" Width="300" Height="300" Fill="Brown" Name="rect"/>
我们就是要让这个矩形进行三维旋转。
定义一个方法,从以上三个 Slider 控件中获得实时的值,然后改变矩形的三维方向(在三个轴上的旋转角度)。
void SetUI()
{
Visual v = ElementCompositionPreview.GetElementVisual(rect);
// 设置方向
float x = (float)sldX.Value;
float y = (float)sldY.Value;
float z = (float)sldZ.Value;
Quaternion q = new Quaternion(x, y, z, 1f);
v.Orientation = q;
}
一个 Quaternion 实例包含四个值,前三个就是三个坐标轴上旋转的值,那个 W 不管它,始终给它分配 1 就行了。
来,看看效果。
这个示例的源代码可以 点击这里下载。
好,本篇咱们就聊到这里,下一篇老周再介绍一下如何用 Win 2D 组件在 XAML 元素上画点东东,可以实现 WPF 中自定义 Renderer 的效果。
【Win 10 应用开发】UI Composition 札记(三):与 XAML 集成的更多相关文章
- 【Win 10 应用开发】UI Composition 札记(一):视图框架的实现
在开始今天的内容之前,老周先说一个问题,这个问题记得以前有人提过的. 设置 Windows.ApplicationModel.Core.CoreApplicationView.TitleBar.Ext ...
- 【Win 10 应用开发】UI Composition 札记(二):基本构件
在上一篇中,老周用一个示例,演示了框架视图的创建过程,在本篇中,老周将给大伙伴们说一下 Composition 构建 UI 的一些“零件”. UI Composition 有一个核心类——对,就是 C ...
- 【Win 10 应用开发】UI Composition 札记(六):动画
动画在 XAML 中也有,而且基本上与 WPF 中的用法一样.不过,在 UWP 中,动画还有一种表现方式—— 通过 UI Composition 来创建. 基于 UI Composition 的动画, ...
- 【Win 10 应用开发】UI Composition 札记(四):绘制图形
使用 Win 2D 组件,就可以很轻松地绘制各种图形,哪怕你没有 D2D 相关基础,也不必写很复杂的 C++ 代码. 先来说说如何获取 Win 2D 组件.很简单,创建 UWP 应用项目后,你打开“解 ...
- 【Win 10 应用开发】UI Composition 札记(五):灯光
UI Composition 除了能够为 UI 元素建立三维空间外,还有相当重要的一个部件——灯光.宇宙万物的精彩缤纷,皆源于光明,光,使我们看到各种东西,除了黑洞之外的世界都是五彩斑谰的.故而,真要 ...
- 【Win 10应用开发】认识一下UAP项目
Windows 10 SDK预览版需要10030以上版本号的Win 10预览版系统才能使用.之前我安装的9926的系统,然后安装VS 2015 CTP 6,再装Win 10 SDK,但是在新建项目后, ...
- 【Win 10 应用开发】在代码中加载文本资源
记得前一次,老周给大伙,不,小伙伴们介绍了如何填写 .resw 文件,并且在 XAML 中使用 x:Uid 标记来加载.也顺便给大伙儿分析了运行时是如何解析 .resw 文件的. 本来说好了,后续老周 ...
- 【Win 10 应用开发】启动远程设备上的应用
这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...
- 【Win 10应用开发】延迟共享
延迟共享是啥呢,这么说吧,就是在应用程序打开共享面板选择共享目标时,不会设置要共享的数据,而是等到共享目标请求数据时,才会发送数据,而且,延迟操作可以在后台进行. 这样说似乎过于抽象,最好的诠释方法, ...
随机推荐
- 深入浅出AQS之独占锁模式
每一个Java工程师应该都或多或少了解过AQS,我自己也是前前后后,反反复复研究了很久,看了忘,忘了再看,每次都有不一样的体会.这次趁着写博客,打算重新拿出来系统的研究下它的源码,总结成文章,便于以后 ...
- TCP/IP(一)之初识计算机网络
前言 在一段时间里,都很想知道一台电脑怎么跟另一台电脑通信的,我发送一个qq给女朋友,怎么准确的发送过去的,又是怎么接受消息的. 接下来一段时间给大家慢慢分享关于计算机网络的相关知识. 一.局域网.广 ...
- [bzoj1066] [SCOI2007] 蜥蜴 - 网络流
在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个 ...
- Java高级工程师进阶路线
第一部分:宏观方面 一. JAVA.要想成为JAVA(高级)工程师肯定要学习JAVA.一般的程序员或许只需知道一些JAVA的语法结构就可以应付了.但要成为JAVA(高级) 工程师,您要对JAVA做比较 ...
- C# readonly
当某个字段是引用类型,并且该字段被标记为readonly时,不可改变的是引用,而非字段引用的对象,例如:
- python读取命令行参数的方法
1.sys模块 需要模块:sys参数个数:len(sys.argv)脚本名: sys.argv[0]参数1: sys.argv[1]参数2: sys.argv[2] test.p ...
- python 发送邮件,未完
def send_mail(): try: print "send mail..." # handle = smtplib.SMTP('smtp.163.com', 25) # h ...
- wpf 中英文版编写
var uriC = new Uri("/YTManage.Language;component/Chinese.xaml", UriKind.Relative); // 得到资源 ...
- Maven-环境搭建以及建立Maven项目
Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具. 多的不说,直接开始这章节的主要内容. 1.maven下载地址http://maven.apac ...
- px转vw和vh的工具(对前端同学有用)
CSS3中有两个新尺寸单位vw和vh, 这两个单位非常适合于开发移动端自适应页面. 假如说有一个设计师做了一张1136x750px的页面,这长页面是针对iPhone6的屏幕设计的. 前端开发工程师将这 ...