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;
            }
  • 相关阅读:
    算法----(1)冒泡排序
    淘宝爬虫
    爬虫_豆瓣电影top250 (正则表达式)
    爬虫_猫眼电影top100(正则表达式)
    Android 简单调用摄像头
    Android 简单天气预报
    思维模型
    This view is not constrained, it only has designtime positions, so it will jump to (0,0) unless you
    Android studio preview界面无法预览,报错render problem
    Android studio 3.1.2报错,no target device found
  • 原文地址:https://www.cnblogs.com/arcsinw/p/5272913.html
Copyright © 2011-2022 走看看