zoukankan      html  css  js  c++  java
  • [UWP] 自定义一个ItemsPanel

    在做游民星空的搜索页面的时候,需要展示搜索热点词,返回的是一个string数组的形式,然后以一种错落的方式显示,每一个Item的大小都和热点词长度一致,然后一行放不下之后就换行,描述的不太直观,直接看图好了。

    当我有这个布局需求的时候我首先就想到了看过的一篇ms-uap的博客-通过Measure & Arrange实现UWP瀑布流布局 ,自定义ItemsPanel可以满足我的需求

    首先新建一个类继承Panel,然后重写Panel里的两个方法MeasureOverride 和 ArrangeOverride

    贴出MSDN的原版解释

    MeasureOverride(Size availableSize)

    When overridden in a derived class, measures the size in layout required for child elements and determines a size for the FrameworkElement derived class.

    ArrangeOverride (Size finalSize)

    When overridden in a derived class, positions child elements and determines a size for a FrameworkElement derived class.

    我的理解是MeasureOverride 是计算布局中所有的子控件需要的大小之和并返回这个值,availableSize参数是父控件提供的可用大小,关键是计算

    而ArrangeOverride对子元素进行布局操作并决定布局需要的大小,主要是布局。实际上运行的时候也是先执行MeasureOverride方法然后执行ArrangeOverride方法。

    在MeasureOverride中可以获取每个子控件的大小(宽度和高度),通过传过来的availableSize得到父控件的可用大小,然后就是简单的数学了,Panel给我的感觉像是一张有坐标系的图纸,通过坐标在上面布局子控件

    这里的布局逻辑是,将子控件横向排列,并记下当前已布局的子控件的宽度和,直到有下一个子控件的宽度+已布局子控件的宽度和>父控件的宽度时,换行,也就是把Y坐标+=控件的高度(这里控件的高度都是一致的)

      protected override Size MeasureOverride(Size availableSize)
            { 
                //可用空间大小
                Size usefulSize = new Size(availableSize.Width, double.PositiveInfinity);
    
                //控件高度
                double y = 0;
                double x = 0;
    
                foreach (UIElement item in Children)
                {
                    item.Measure(usefulSize);
    
                    Size itemSize = item.DesiredSize;
                    double itemWidth = itemSize.Width;
    
                    y = (itemSize.Height) > y ? itemSize.Height : y;
    
                    //加入该子控件后一行满了
                    if (x + itemSize.Width > availableSize.Width)
                    {
                        x = 0;
                        y += itemSize.Height;
                    }
                    x += itemSize.Width;
                }
    
                return new Size(availableSize.Width, y);
            }
    
            /// <summary>
            /// 为每个子控件布局
            /// </summary>
            /// <param name="finalSize"></param>
            /// <returns></returns>
            protected override Size ArrangeOverride(Size finalSize)
            { 
                //记录横坐标
                double x = 0.0;
                double y = 0.0;
    
                foreach (UIElement item in Children)
                {
                    Size itemSize = item.DesiredSize;
                    double itemWidth = itemSize.Width;
    
                    //加入该控件后一行满了
                    if (x + itemSize.Width > finalSize.Width)
                    {
                        x = 0;
                        y += itemSize.Height;
                    }
                    //控件的坐标
                    Point pt = new Point(x, y);
    
                    //控件布局
                    item.Arrange(new Rect(pt, itemSize));
                    x += itemSize.Width;
                }
    
                return finalSize;
            }
  • 相关阅读:
    线上redis禁止使用keys等时间复杂度高的命令
    组合索引的使用效果的总结
    Netty 断线重连解决方案
    可作为GC Root的对象
    在同一个sqlSession执行一个相同的查询时,Mybatis有一级缓存,不会去查数据库,由此引发的一个bug
    HashMap 和 currentHashMap JDK8总结
    Java程序导致服务器CPU占用率过高的问题排除过程
    一条sql执行的很慢的原因有哪些
    主键索引和非主键索引的区别
    黑马程序员
  • 原文地址:https://www.cnblogs.com/arcsinw/p/5272913.html
Copyright © 2011-2022 走看看