Viewbox在UWP开发中的应用

简介: 原文:Viewbox在UWP开发中的应用Windows 8.1 与Windows Phone 8.1的UAP应用,终于在Windows 10上统一到了UWP之下。原来3个不同的project也变为一个。
原文: Viewbox在UWP开发中的应用

Windows 8.1 与Windows Phone 8.1的UAP应用,终于在Windows 10上统一到了UWP之下。原来3个不同的project也变为一个。没有了2套xaml页面,我们需要用同一个页面适应所有的设备。更麻烦的是在Desktop设备上,我们的应用窗口是可以随意拖动大小的。这对我们的UI布局提出了更高的要求。当然我们也有了新的工具来应对:

VisualState中增加了StateTriggers,通过不同的条件触发Trigger并自动切换到对应的VisualState,还能加入自己定义触发条件的Trigger。

新增了RelativePanel控件,可以让其中的元素使用相对位置布局来适应不同的设备和窗口大小。

另一方面微软官方也发布了一些指导建议,比如Responsive design 101 for Universal Windows Platform (UWP) apps , UI basics for Universal Windows Platform (UWP) apps, Plan your Universal Windows Platform (UWP) app 等一系列文章。这对我们也很有启发。

然而这些都没有具体提到对于窗口大小拖动情况下的处理,下面就来分享一下我们在尝试开发UWP应用的过程中对这种情况的一些思考。

总体布局

我们的应用,总体上是非常简单地采用了UI basics for Universal Windows Platform (UWP) apps 中 图1和图2 的布局,有着始终显示的顶栏和底栏,中间则是内容显示区域。

如果沿用UAP的设计,我们可能会为顶栏和底栏设计一个固定高度,让中间的内容区域可以随屏幕大小来变化。然而在UWP中,我们的应用窗口可以在最小500 X 320,到全屏之间自由变化。如果仍然采用固定高度,那在窗口变小的情况下,内容区域就会被顶栏和底栏挤压,这并不是我们希望的。所以我们在全局的布局上采用了按比例分配的策略:

<Grid.RowDefinitions>

<RowDefinition x:Name="rd_1" Height="*" ></RowDefinition>

<RowDefinition x:Name="rd_2" Height="8*"></RowDefinition>

<RowDefinition Height="60*"></RowDefinition>

<RowDefinition x:Name="rd_4" Height="8*" ></RowDefinition>

<RowDefinition x:Name="rd_5" Height="*" ></RowDefinition>

</Grid.RowDefinitions>

这样一来在不同的窗口大小和设备的情况下都可以有所兼顾。

但这又带来新的问题:我们顶栏和底栏中的文字,图片大多是固定大小的。怎样才能让它们随屏幕和设备自动适应呢?用新的StateTriggers固然可以,但对于每个固定大小的控件,都要指定它们在不同VisualState下的新大小,有些麻烦。而且我们的布局并没有很大的变化,没有一定使用StateTriggers必要。所以这里我们想到了Viewbox 控件。Viewbox 是一个可以将其中内容缩放到自身大小的容器。我们在按比例划分的Grid中放入Viewbox ,再把顶栏和底栏放到Viewbox 中,这样他们就可以在不同窗口大小和设备上都保持统一的比例了:

<Viewbox x:Name="vbNav" Grid.Row="1" HorizontalAlignment="Left" Visibility="Visible">

<Grid Margin="50,0" >

<Image Source="{StaticResource mainPageMenuLeftImg}" Stretch="Uniform" HorizontalAlignment="Left" Height="160"

Margin="-20,0,0,0" VerticalAlignment="Center" Canvas.ZIndex="100"></Image>

<ListView x:Name="lvNav" SelectionMode="Single" Height="160" Canvas.ZIndex="99"

SelectionChanged="lvNav_SelectionChanged" HorizontalAlignment="Left"

VerticalAlignment="Center" ScrollViewer.HorizontalScrollMode="Enabled"

Background="#FFF6EBA1" ItemContainerStyle="{StaticResource ContextControlItemContainerStyle}">

<ListView.ItemsPanel>

<ItemsPanelTemplate>

<VirtualizingStackPanel Orientation="Horizontal" Margin="0" VerticalAlignment="Center"></VirtualizingStackPanel>

</ItemsPanelTemplate>

</ListView.ItemsPanel>

</ListView>

<Image Source="{StaticResource mainPageMenuRightImg}" Stretch="Uniform" HorizontalAlignment="Right" Height="160"

Margin="0,0,-20,0" VerticalAlignment="Center" Canvas.ZIndex="100"></Image>

</Grid>

</Viewbox>

这里的image和listview都是固定大小的,使用了viewbox以后就可以始终保持只占屏幕一定比例,而不会在小屏幕上超出Grid而在大屏幕上显得比较小了。

内容布局

我们的页面内容有2种,一种是内容列表,一种则是包括编辑和预览的界面。

对于内容列表,我们使用了Responsive design 101 for Universal Windows Platform (UWP) apps中的resize策略。

主要是一个横向滚动的GridView,在屏幕足够高的情况下显示3行或4行内容,较小的情况下则显示2行。然而这个较小的情况实际上覆盖了比较大的范围,如果仍然使用固定大小的列表元素控件则会遇到和顶栏和底栏类似的问题。所以我们又一次使用了viewbox: 将内容区域放一个Grid在最外层,再把包含GridView的viewbox放在其中。响应最外层的Grid的sizechange事件,改变GridView的长宽比例以适应显示区域。

Xaml:

<Grid x:Name="grid_content" SizeChanged="gridRoot_SizeChanged" Grid.Row="2">

<Viewbox>

<GridView x:Name="gv_Content" ItemContainerStyle="{StaticResource contentTemplateStyle}"

SelectionMode="Single" IsSynchronizedWithCurrentItem="{x:Null}"

SelectionChanged="gvContent_SelectionChanged" IsItemClickEnabled="True"

VerticalAlignment="Stretch" HorizontalAlignment="Stretch"

Width="630"

Height="774"

ScrollViewer.HorizontalScrollMode="Enabled" ScrollViewer.HorizontalScrollBarVisibility="Visible"

Margin="20">

<GridView.ItemsPanel>

<ItemsPanelTemplate>

<WrapGrid Orientation="Vertical" Margin="0" MaximumRowsOrColumns="4" VerticalAlignment="Top"></WrapGrid>

</ItemsPanelTemplate>

</GridView.ItemsPanel>

</GridView>

</Viewbox>

</Grid>

CS:

private void gridRoot_SizeChanged(object sender, SizeChangedEventArgs e)

{

try

{

Grid thisGrid = sender as Grid;

if (thisGrid.ActualHeight >=480 && thisGrid.ActualHeight <=720)

{

this.gv_Content.Height = 784 * 1.5; //改变高度,放3个列表元素

}

else if (thisGrid.ActualHeight >720)

{

this.gv_Content.Height = 784 * 2; //改变高度,放4个列表元素

}

     else

{

this. gv_Content.Height = 784; //改变高度,放2个列表元素

}

this. gv_Content.Width = thisGrid.ActualWidth / (thisGrid.ActualHeight) * this. gv_Content.Height; //调整宽度,适应显示区域比例

}

catch (Exception ex)

{

Debug.WriteLine(ex.Source + "\r\n" + ex.Message + "\r\n" + ex.StackTrace);

}

}

而包含编辑和预览的界面,我们则采取了在屏幕宽度较小的时候将预览界面隐藏,让界面可以在编辑和预览之间切换的策略。

小结

以上就是我们面对UWP在UI布局方面新特性的一部分心得,希望能抛砖引玉,吸引更多的小伙伴加入到UWP的开发中来。

目录
相关文章
|
9月前
|
C# 容器
WPF技术之Viewbox控件
WPF Viewbox控件是一个布局控件,用于缩放并扩展其子元素,以适应可用空间。
267 0
|
9月前
|
C# 计算机视觉
WPF技术之Background
在WPF中,Background属性用于设置元素的背景。它可以接受多种类型的值,包括颜色、图像、线性渐变和径向渐变等。
554 0
|
9月前
|
C# Windows
WPF技术之Border控件
WPF(Windows Presentation Foundation)的Border控件用于创建一个可视的边框,可以将其他控件包裹在内。
332 0
WPF技术之Border控件
|
Windows
[UWP]使用AdaptiveTrigger实现自适应布局
原文:[UWP]使用AdaptiveTrigger实现自适应布局 这篇博客将介绍如何在UWP开发中使用AdaptiveTrigger实现自适应布局。 场景1:窗体宽度大于800时,窗体背景色为绿色,窗体在0到800之间为蓝色。
984 0
|
C#
WPF 自定义Metro Style窗体
原文:WPF 自定义Metro Style窗体 为了使WPF程序在不同版本的操作系统上保持一致的显示效果,我们需要重写WPF控件样式。这篇博客将展示如何创建一个Metro Style的WPF窗体。 首先先看一下最终窗体的效果图, 通过截图我们可以看出来这个窗体由两部分组成,顶部为最小化和关闭按钮,其他区域为窗体的显示区域。
1272 0
|
存储 开发工具
UWP Background过渡动画
原文:UWP Background过渡动画 首先说两件事: 1、大爆炸我还记着呢,先欠着吧。。。 2、博客搬家啦,新地址:https://blog.ultrabluefire.cn/ ==========下面是正文========== 前些日子看到Xaml Controls Gallery的ToggleTheme过渡非常心水,大概是这样的: 在17134 SDK里写法如下: 1 2 3 4 5 这和我原本的思路完全不同。
768 0
|
数据库 C# 数据库管理
UWP 使用Telerik Grid控件
原文:UWP 使用Telerik Grid控件 还是老规矩,看一下最终效果。   数据是从SQLite中读取,然后绑定到DataGrid中显示的。   先看一下XAML   开头引用—————— xmlns:grid="using:Telerik.
1211 0
|
C#
WPF&#39;s Style BasedOn
原文:WPF's Style BasedOn 1 2 3 4 5 6 All Style Based 1 2 3 4 5 6 7 8 9 ...
1471 0
|
C#
WPF's Style BasedOn
原文:WPF's Style BasedOn 1 2 3 4 5 6 All Style Based 1 2 3 4 5 6 7 8 9 ...
925 0