Win10 UWP开发中的重复性静态UI绘制小技巧 2
小技巧1 地址:http://www.cnblogs.com/ms-uap/p/4641419.html
介绍
我们在上一篇博文中展示了通过Shape.Stroke族属性实现静态重复性UI绘制,使得UWP界面的实现变得稍微灵活一些了。
但这一技巧还是有不少局限的,毕竟折腾StrokeDashArray属性看上去并不是那么直观和适用(还存在用扇形欺骗观众这样的“问题”啦)。
这一篇博文我们将为大家介绍一种更为适用,同时也更为灵活和强大的重复性UI绘制技巧。
ItemsControl.ItemsSource和
ItemsControl.ItemTemplate组合技
ItemsControl是一个很常见的控件,虽然它经常是以ListView、ListBox等衍生类的形式出现,想必大家也是经常使用它们。
而ItemsControl本身,则提供了最基本的“作为对象集合”的功能。
而其中ItemsControl.ItemsSource和ItemsControl.ItemTemplate两个属性最为重要。前者将通过指定策略预处理的数据赋予控件,后者将源数据映射为UI元素。
灵活运用它们,就能方便的做出精准而又快速的设计。
比如:

<Grid>
<Grid.Resources>
<design:AngleSource x:Key="source"/>
</Grid.Resources> <Grid HorizontalAlignment="Center" VerticalAlignment="Center"
Width="200" Height="200">
<ItemsControl ItemsSource="{Binding Source={StaticResource source}, Path=Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Control.VerticalAlignment" Value="Stretch"/>
<Setter Property="Control.HorizontalAlignment" Value="Center"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid RenderTransformOrigin="0.5,0.5">
<Line Stroke="Black" StrokeThickness="10" X1="5" X2="5" Y2="20" /> <Grid.RenderTransform>
<RotateTransform Angle="{Binding}"/>
</Grid.RenderTransform>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Grid>
让我们把目光放得“短浅”一点:),此处是不是完美解决了欺骗观众的问题?
一个小小的问题的解决,有时能带出新的解决方案和模式。那么让我们看看这段XAML有什么作用?
首先,AngleSource是这样一个类:
public class AngleSource
{
public IEnumerable<double> Items
{
get
{
return Enumerable.Range(, ).Select(d => d * 30.0);
}
}
}
它的作用就是提供一个数列,里面的数代表了我们要显示的线段相对图形中心的旋转角度。
这个AngleSource类,以静态资源的形式,将其含有的数列暴露给ItemsControl的ItemsSource属性:
ItemsSource="{Binding Source={StaticResource source}, Path=Items}"
然后我们通过自定义ItemTemplate,将简单的double数值具现为旋转的图形!
通过这种方式,我们可以使用简单的代码,来完成其最擅长的事,即按某种策略生成源数据。
PS:如果只有简单的数个元素,不使用ItemsSource+Binding也是可以的,只要像这样:
<ItemsControl>
<x:Double>30</x:Double>
<x:Double>60</x:Double>
<x:Double>90</x:Double>
</ItemsControl> <ItemsControl>
<local:FooItem Bar="123" Baz="456"/>
<local:FooItem Bar="789" Baz="233"/>
</ItemsControl>
我们还使用ItemsControl.ItemsPanel、ItemsControl.ItemContainerStyle两个属性配合,让每个线段能以表盘的中心为参考点进行旋转:
1)ItemContainerStyle是对Item的区域进行外围定制(Item本身交给ItemTemplate了)。
2)ItemsPanel的作用是定义元素在控件中的布局形式,默认的是StackPanel,也就是常见的ListBox和ListView的形式。
常见的还有:
<Grid/> <!-- 可以自动对齐 -->
<Canvas/> <!-- 一般为绝对定位,容易调整图层,并可以超出范围 -->
整个ItemsControl的层级大致如下:

同理,更多的变化呼之欲出:
这里我们简单地做两种扩展,更多的组合期待大家的灵活运用~
1. 带时间的表盘

<Grid>
<Grid.Resources>
<design:AngleSource x:Key="source"/>
<design:AngleClockConverter x:Key="toClock"/>
</Grid.Resources> <Grid HorizontalAlignment="Center" VerticalAlignment="Center"
Width="200" Height="200">
<ItemsControl ItemsSource="{Binding Source={StaticResource source}, Path=Items}"
RenderTransformOrigin="0.5,0.5">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Control.VerticalAlignment" Value="Stretch"/>
<Setter Property="Control.HorizontalAlignment" Value="Center"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid RenderTransformOrigin="0.5,0.5" Width="50">
<TextBlock Text="{Binding Converter={StaticResource toClock}}"
HorizontalAlignment="Center"/>
<Line Stroke="Black" StrokeThickness="10"
X1="5" X2="5" Y1="20" Y2="40"
HorizontalAlignment="Center"/>
<Grid.RenderTransform>
<RotateTransform Angle="{Binding}"/>
</Grid.RenderTransform>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Grid>
这段XAML不仅按角度画出了旋转的线段,还在此通过一个converter对源数据进行了一次映射。是不是有点linq select的感觉?
2. 斐波那契数列

<Grid>
<Grid.Resources>
<design:FibonacciSource x:Key="fibonacci"/>
</Grid.Resources>
<ItemsControl Margin="20"
ItemsSource="{Binding Source={StaticResource fibonacci}, Path=Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas>
<Line Y2="30" Stroke="Black"/>
<!-- 由于我们的Left定位实际只用于上面的Line -->
<!-- 那我们怎让下面的数值显示能居中于Line呢? -->
<!-- 因为Canvas是允许其内容的渲染超出范围的,我们可以以此先用Grid开辟一个足够大的空间 -->
<!-- 再在其中将TextBlock居中 -->
<Grid Width="50" Canvas.Left="-25" Canvas.Top="40">
<TextBlock HorizontalAlignment="Center" Text="{Binding}"/>
</Grid>
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
这段XAML也是很有趣,其中的ItemsSource仅仅是提供了一个IEnumerable<int>,也就是斐波那契数列,
而我们控制Canvas.Left画出了一系列标注线,它们距左端的位移分别是斐波那契数列的值!
或许在一些数理教学的App里能用得上呢……
另外
Source类同样可以暴露出使用形如FoobarItem的IEnumerable<T>,就可以在FoobarItem中设置更多更丰富的属性,
然后在ItemsControl.ItemTemplate(DataTemplate)进行Binding,辅以Style和Converter,实现更加丰富的效果。
这样做有什么好处?
这两篇博文为大家介绍了两种绘制重复性UI的办法,那我们掌握这些办法有什么意义,或者说我们能获得什么好处呢?
解耦。
将这些与程序逻辑完全无关的UI设定,完全地与功能逻辑剥离开。即使需要写一些代码,也和功能逻辑完全没有关联。
让code behind清爽,更加专注于功能的实现,而UI的变换仍旧是动态的。
精确。
由于使用XAML和原始数据生成UI,所以UI元素的属性和位移、旋转等变换是完全精准的,免去手工校准之虞。
并且配合CacheMode和ViewBox,使得UI在适配和渲染时表现清晰不失真,兼顾性能。
同时也提供了新的UI元素控制方式。
比如例子中的圆形进度条的实现。我们可以在后台代码中更新StrokeDashArray来展示进度。
又比如我们设定好了ItemsControl的数据展示策略,只需要再设定数据源,就能轻易地将其展示。
希望这两篇博客能够抛砖引玉,唤来更多创意和技巧,为大家在UWP中的开发提供方便!;)
Win10 UWP开发中的重复性静态UI绘制小技巧 2的更多相关文章
- Win10 UWP开发中的重复性静态UI绘制小技巧 1
介绍 在Windows 10 UWP界面实现的过程中,有时会遇到一些重复性的.静态的界面设计.比如:画许多等距的线条,画一圈时钟型的刻度线,同特别的策略排布元素,等等. 读者可能觉得这些需求十分简单, ...
- vue vuex开发中遇到的问题及解决小技巧
1.在vue的开发中,如果使用了vuex,数据的组装,修改时在mutations中,页面是建议修改变量值的,如果强制修改,控制台就会出现错误.如下: 这种错误虽然不会影响结果,但是是vuex不提倡的方 ...
- Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App
安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...
- Win10/UWP开发—使用Cortana语音与App后台Service交互
上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比 ...
- Win 10 开发中Adaptive磁贴模板的XML文档结构,Win10 应用开发中自适应Toast通知的XML文档结构
分享两篇Win 10应用开发的XML文档结构:Win 10 开发中Adaptive磁贴模板的XML文档结构,Win10 应用开发中自适应Toast通知的XML文档结构. Win 10 开发中Adapt ...
- Win10 UWP 开发系列:使用SQLite
在App开发过程中,肯定需要有一些数据要存储在本地,简单的配置可以序列化后存成文件,比如LocalSettings的方式,或保存在独立存储中.但如果数据多的话,还是需要本地数据库的支持.在UWP开发中 ...
- Win10/UWP开发-Ink墨迹书写
在UWP开发中,微软提供了一个新型的InkCanvas控件用来让用户能书写墨迹,在新版的Edga浏览器中微软自己也用到了该控件使用户很方便的可以在web上做笔记. InkCanvas控件使用很简单,从 ...
- UWP开发中的方向传感器
在UWP开发中,我们能使用的到方向有三种: OrientationSensor下的四元数:Compass罗盘的HeadingMagneticNorth:以及SimpleOrientationSenso ...
- Windows10(uwp)开发中的侧滑
还是在持续的开发一款Windows10的应用中,除了上篇博客讲讲我在Windows10(uwp)开发中遇到的一些坑,其实还有很多不完善的地方,比如(UIElement.Foreground).(Gra ...
随机推荐
- DataSet用法详细 转
DataSet用法详细 转 DataSet用法详细 一.特点介绍 1.处理脱机数据,在多层应用程序中很有用. 2.可以在任何时候查看DataSet中任意行的内容,允许修改查询结果的方法. 3.处理分级 ...
- UNIX 系统调用函数errno返回值搜集(in updating )
当Unix系统级函数遇到错误时,它们会典型地返回-1,并设置全局整数变量errno来表示什么出错了 阅读redis源码的时候,发现如果对系统级函数出错时的errno比较熟悉,写起程序来会游刃有余不少. ...
- Ext.encode 抛出异常“Uncaught RangeError: Maximum call stack size exceeded”
在用使用Ext.encode(ExtObject)过程中抛出了如下错误: Uncaught RangeError: Maximum call stack size exceeded 实际上,不能用 E ...
- Shell文本处理 - 分割合并与过滤
sort分类操作 示例文件 Boys in Company C:HK:192:2192 Alien:HK:119:1982 The Hill:KL:63:2972 Aliens:HK:532:4892 ...
- block的解析
1. 操作系统中的栈和堆 我们先来看看一个由C/C++/OBJC编译的程序占用内存分布的结构: 栈区(stack):由系统自动分配,一般存放函数参数值.局部变量的值等.由编译器自动创建与释放.其操作方 ...
- R与Java
对于从未接触代码的我,看到这些很陌生,现在需要做的是用r语言去做数据处理分析,将分析的结果给Java,然后在Java上输出想要的结果,没人给予指导,自己就这样瞎摸索,真希望有这方面的牛人给予指导,让一 ...
- Tomcat如何配置环境变量
1, JDK:版本为jdk-7-windows-i586.exe 下载地址: http://www.oracle.com/technetwork/java/javase/downloads/index ...
- java TreeMap用法
转自:http://huchenqiang90.blog.163.com/blog/static/11250080020101025956498/ 最近工作遇到需要按一个model中不同的列进行排序的 ...
- 【权值线段树】bzoj3224 Tyvj 1728 普通平衡树
一个板子. #include<cstdio> #include<algorithm> using namespace std; #define N 100001 struct ...
- 转 :meta name的含义:<META http-equiv=Content-Type content="text/html; charset=gb2312">
meta是什么?meta其实是html语言head区的一个辅助性标签.在几乎所有的网页里,我们都可以看到类似下面这段html代码:<META http-equiv=Content-Type co ...