Win10 UWP开发中的重复性静态UI绘制小技巧 2

简介: 原文:Win10 UWP开发中的重复性静态UI绘制小技巧 2小技巧1 地址:http://www.cnblogs.com/ms-uap/p/4641419.html 介绍 我们在上一篇博文中展示了通过Shape.Stroke族属性实现静态重复性UI绘制,使得UWP界面的实现变得稍微灵活一些了。
原文: 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(0, 12).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中的开发提供方便!;)

目录
相关文章
|
1月前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
3天前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
22天前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
1月前
|
开发框架 JavaScript 前端开发
HarmonyOS UI开发:掌握ArkUI(包括Java UI和JS UI)进行界面开发
【10月更文挑战第22天】随着科技发展,操作系统呈现多元化趋势。华为推出的HarmonyOS以其全场景、多设备特性备受关注。本文介绍HarmonyOS的UI开发框架ArkUI,探讨Java UI和JS UI两种开发方式。Java UI适合复杂界面开发,性能较高;JS UI适合快速开发简单界面,跨平台性好。掌握ArkUI可高效打造符合用户需求的界面。
117 8
|
2月前
|
JavaScript API 开发者
掌握ArkTS,打造HarmonyOS应用新视界:从“Hello World”到状态管理,揭秘鸿蒙UI开发的高效秘诀
【10月更文挑战第19天】ArkTS(ArkUI TypeScript)是华为鸿蒙系统中用于开发用户界面的声明式编程语言,结合了TypeScript和HarmonyOS的UI框架。本文介绍ArkTS的基本语法,包括组件结构、模板和脚本部分,并通过“Hello World”和计数器示例展示其使用方法。
86 1
|
2月前
|
缓存 测试技术 C#
使用Radzen Blazor组件库开发的基于ABP框架炫酷UI主题
【10月更文挑战第20天】本文介绍了使用 Radzen Blazor 组件库开发基于 ABP 框架的炫酷 UI 主题的步骤。从准备工作、引入组件库、设计主题、集成到 ABP 框架,再到优化和调试,详细讲解了每个环节的关键点和注意事项。通过这些步骤,你可以打造出高性能、高颜值的应用程序界面。
|
2月前
|
JavaScript 索引
Vue开发中Element UI/Plus使用指南:常见问题(如Missing required prop: “value“)及中文全局组件配置解决方案
Vue开发中Element UI/Plus使用指南:常见问题(如Missing required prop: “value“)及中文全局组件配置解决方案
196 0
|
2月前
|
开发框架 JavaScript 前端开发
鸿蒙NEXT开发声明式UI是咋回事?
【10月更文挑战第15天】鸿蒙NEXT的声明式UI基于ArkTS,提供高效简洁的开发体验。ArkTS扩展了TypeScript,支持声明式UI描述、自定义组件及状态管理。ArkUI框架则提供了丰富的组件、布局计算和动画能力。开发者仅需关注数据变化,UI将自动更新,简化了开发流程。此外,其前后端分层设计与编译时优化确保了高性能运行,利于生态发展。通过组件创建、状态管理和渲染控制等方式,开发者能快速构建高质量的鸿蒙应用。
142 3
|
7月前
|
Android开发 缓存 双11
android的基础ui组件,Android开发社招面试经验
android的基础ui组件,Android开发社招面试经验
android的基础ui组件,Android开发社招面试经验
|
3月前
|
前端开发 开发者 UED
前端只是切图仔?来学学给开发人看的UI设计
该文章针对前端开发者介绍了UI设计的基本原则与实践技巧,覆盖了布局、色彩理论、字体选择等方面的知识,并提供了设计工具和资源推荐,帮助开发者提升产品的视觉与交互体验。

热门文章

最新文章