目的

在UWP开发中,我们常常用到两个显示列表的控件:ListView和GridView。而这两个列表控件在PC等大屏幕上如果能多列“智能”调整自己的大小(通常是根据当前窗口大小调整宽度),那么用户就会在同一屏幕内接收到更多信息,同时空间的利用率得以提高,也会提高应用的视觉体验。这是我的第一篇博客,向大家分享一下列表项宽度自适应的实现。

实现思路及方法

我们最初的想法可能是,定义列表项模板,给模板里的Panel起个名字,在窗口的SizeChanged事件里加入调整其宽度的代码。这种想法最朴素,然而在操作中遇到了一些问题:我们不能在后台代码里直接访问DataTemplete里的元素。而且,当同一页面中存在多个列表时,给大家都分配一个名字也比较傻,而且后台代码会堆积,不利于维护。

这个时候,数据绑定就可以大显身手了。

我们可以在Xaml里定义一个随便什么元素(当然,它只起到一个“桥”的作用,不能影响当前布局。(废话))这里,我们定义一个Border即可:

 <Border x:Name="width"/>

然后,创建一个我们想要实现自适应的列表,注意其中的绑定

 <GridView  x:Name="testlist">
  <GridView.ItemTemplate>
    <DataTemplate>
      <Grid Width="{Binding ElementName=width,Path=Width}">
......
      </Grid>
    </DataTemplate>
  </GridView.ItemTemplate>
</GridView>

接下来我们所要做的只有一步:在后台的SizeChanged事件中加入对width宽度的调整即可。这里为了方便,我们把它写成一个方法,可以放在自己App的Helper类里供应用内所有列表调用。这个方法长成这个样子:

   class WidthFit
{
/// <summary>
/// 获取自适应列表项宽度
/// </summary>
/// <param name="width">当前窗口宽度</param>
/// <param name="max">列表项最大宽度</param>
/// <param name="min">列表项最小宽度</param>
/// <param name="offset">偏移量</param>
/// <returns></returns>
public static double GetWidth(double width, int max, int min, int offset = )
{
if (offset < || offset > )
{
offset = ;
}
double w = ;
int column = ;
int maxcolumn = (int)width / min;
double i2 = width / min;
for (int i = ; i <= maxcolumn; i++)
{
if (Math.Abs(i - i2) < )
{
column = (int)Math.Truncate(i2) == ? : (int)Math.Truncate(i2);
}
}
w = width / column;
w -= offset * column;
return w;
}
}

代码很易读,在这里不做过多说明。只说明一下,offset这个参数用来设定宽度的偏移量,因为我们的列表项之间、列表与父面板间通常会有间距,这个间距也要被考虑到,否则实际显示的列数可能会减少,很不美观。

这样,我们可以方便地调用此方法:

 private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
2 {
  width.Width = WidthFit.GetWidth(ActualWidth, , );
4 }

实现的效果就不贴出来了,大家可以动手试一试。

还有什么没提到……

ListView能实现这种效果吗?能。具体做法也很简单,更改一下ListView默认的ItemPanel即可,余下的工作与GridView完全一样。

 <ListView.Style>
<Style TargetType="ListView">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.Style>

到了要说“但是”的时候了。上面提到的GetWidth方法有一个小缺陷:可能会造成看上去像是“显示的列数受到损失”的情况(当然啦,这个概率很小)。我们发现,这个Bug出现在列数发生变动的临界值附近。而原因其实也很简单,此时我们定义的最大宽度小于当前窗口宽度与计算出的列数的比,因而无法铺满窗口的宽度,看上去就像是少了一列一样。这个小缺陷当然也易于修正,大家可以在GetWidth方法里做点文章,怠惰一点的话,也可以直接使最大宽度设置得大一点。

明明快到考期了,可我还是“死猪不怕开水烫,越到考期我越浪”,强行水了我的第一篇博客。如果有什么错误与不周到的地方还望大佬们指正。我去补作业了……

【UWP】列表项宽度自适应的实现的更多相关文章

  1. 【UWP】拖拽列表项的排序功能实现

    在一些允许用户自定义栏目顺序的app(如:凤凰新闻.网易云音乐等),我们可以方便地拖拽列表项来完成列表的重新排序,进而完成对栏目顺序的重排.这个功能很人性化,而实现起来其实很简单(甚至都不用写什么后台 ...

  2. easyui-menu 宽度自适应

    easyui-menu里的菜单项是从后端获取的,而这个组件提供的API配置只能设置一个固定宽度,当获取的菜单项字数较多时有可能显示不全.解决方法如下: <style> .myClass{f ...

  3. duilib List控件,横向滚动时列表项不移动或者显示错位的bug的修复

    转载请说明出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/42264673 关于这个bug的修复我之前写过一篇博客,连接为:http:/ ...

  4. 自定义ListView适配器Adapter引用布局文件的情况下实现点击列表项时背景颜色为灰色

    listview控件设置适配器的时候,如果使用自定义的adapter,比如MyArrayAdapter extends ArrayAdapter<String> 如果listitem布局文 ...

  5. ListView控件的列表项的文字不满一行的时候,如何实现点击该列表项的空白区域仍可触发列表项的点击事件

    今天在做Demo的过程中,使用到了ListView.然而在实现过程中,发现一个出现了一个问题:只能点击列表项的文字区域可以触发点击事件,而点击列表项的空白区域无法触发点击事件. 如下图: listit ...

  6. 可编辑且宽度自适应input

    默认的input项是比较难看的,并且它的宽度还无法随着输入而变化,这样未免有些呆板,不过借助JavaScript可以达到宽度自适应的效果,下面为了方便使用了jQuery: <div class= ...

  7. Android学习笔记(23):列表项的容器—AdapterView的子类们

    AdapterView的子类的子类ListView.GridView.Spinner.Gallery.AdapterViewFlipper和StackView都是作为容器使用,Adapter负责提供各 ...

  8. ElementUI el-table 在flex下的宽度自适应问题

    BUG:在flex容器下面的一个flex:1的子容器里面写了个el-table用来展示列表数据,在做宽度自适应测试的时候发现该组件的宽度只会增加不会缩小. Debug:通过控制台发现组件生成的tabl ...

  9. css布局宽度自适应

    随着各种终端的不断涌现,网页中的元素适应不同的分辨率变得特别重要,根据经验,涉及到宽度自适应的一共有四种情况: 左端固定,右边自适应:右端固定,左边自适应:两端固定,中间自适应:中间固定,两端自适应. ...

随机推荐

  1. 数字(数学)操作类 Math Random 类 ,大数字操作类

    Math 提供了大量的数学操作方法 Math类中所有的方法都是static 方法

  2. Python3基础 set() 删除一个列表中的重复项

    镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...

  3. Jquery Validate 正则表达式实用验证代码常用的

    jQuery.validate 的正则验证功能,包括手机号码.电话号码.邮政编码.QQ号码.IP地址.字母和数字.中文的验证等 手机号码验证 以下为引用内容: 代码如下: jQuery.validat ...

  4. ReactiveCocoa学习笔记--用法

    1.监测UI变量的变化 return 后把值传递下去. 1.1.输出 [self.usernameTextField.rac_textSignal subscribeNext:^(id x){ NSL ...

  5. ios 清除列表选中状态

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

  6. Voilin 与 乐谱

    小提琴属于高音乐器,所以它使用的是高音谱号: 用音的时候,线不够用,那就得上加线,或下加线. 小提琴的弦对应的五线谱的位置为: 第四弦,对应五线谱的下加两条线的下面 第三弦,对应五线谱的第一线的下面 ...

  7. curl远程传输工具

    /** * curl远程传输工具 */ public function post_curl($url,$body,$header,$type='POST'){ $ch = curl_init(); c ...

  8. 横向子菜单栏ul根据其子元素li个数动态获取宽度,并与父li绝对垂直居中的jquery代码段

    ;(function(window){    $('.menuitem').hover(function(){        $('>a',this).css('background-color ...

  9. 基于jquery 封装的 select 小控件,解决 IE6 7 8里 select 边框 高度 无法遮挡等问题

    一.基本原理 select控件在浏览器中是个永远的痛,不同的版本解析出来的可谓五花八门.主要有以下问题: 1,IE6中无法设置高度,Z INDEX永远在最上,无法被其它层遮挡 2,IE7中可以设置高度 ...

  10. Angular - - angular.forEach、angular.extend

    angular.forEach 调用迭代器函数取每一项目标的集合,它可以是一个对象或数组.迭代器函数与迭代器(value.key)一起调用,其中值是一个对象属性或数组元素的值,而数组元素是对象属性的关 ...