• Windows 8 系列(九):关于VariableSizedWrapGrid与WrapGrid 对Visibility变化而引起的布局变化的支持


    最近好久没有写博客了,今天分享一下关于工作中遇到的关于Visibility变化而引起的布局变化的问题。 

    先以一个小例子开场,需求: 新浪微博 添加账号界面中需要有“登陆”按钮,当用户点击此按钮后,需要把按钮换成ProgressRing。如果登陆不成功,弹出错误信息并把ProgressRing替换成“登陆”按钮。

    如下图:

    在按钮与ProgressRing切换的时候我们的一般做法是两种:

    1. 用两个Visibility属性隐藏其中按钮,然后再显示;

    2. 删除按钮、添加ProgressRing;删除ProgressRing,添加按钮;

    第二种比较浪费资源,所以大家都把第一种作为较为常用的方法,即: 用Visibility属性来控制某些UI元素的隐藏与否,特别是需要重复切换的。

    现在切入正题,先上图:

    想必玩过Win8开发的童鞋们一定不陌生,这是在VS中创建GridView模版的应用,启动后的首页面。

    需求是:点击某一项,使其从界面中消失,但是布局不变,即:如果我任意删除一个单元,后面的单元会补充到前面去,中间不会有空白空间。

    乍一看跟上面例子的需求类似,可以在数据集的单元数据中添加个Visibility类型的属性,通过绑定到ItemTemplate中的最外层布局控件上来实现隐藏。但是你真的这么做了,却发现结果是这样的:

    Wow! 为什么? 如果你看看GridView的代码,并试图修改点内容,或许会有所发现:

    <GridView
                x:Name="itemGridView"
                AutomationProperties.AutomationId="ItemGridView"
                AutomationProperties.Name="Grouped Items"
                Grid.RowSpan="2"
                Padding="116,137,40,46"
                ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
                ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
                SelectionMode="None"
                IsSwipeEnabled="false"
                IsItemClickEnabled="True"
                ItemClick="ItemView_ItemClick">
    
                <GridView.ItemsPanel>
                    <ItemsPanelTemplate>                        
                        <VirtualizingStackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>
                <GridView.GroupStyle>
                    <GroupStyle>
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>
                                <Grid Margin="1,0,0,6">
                                    <Button
                                        AutomationProperties.Name="Group Title"
                                        Click="Header_Click"
                                        Style="{StaticResource TextPrimaryButtonStyle}" >
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock Text="{Binding Title}" Margin="3,-7,10,10" Style="{StaticResource GroupHeaderTextStyle}" />
                                            <TextBlock Text="{StaticResource ChevronGlyph}" FontFamily="Segoe UI Symbol" Margin="0,-7,0,10" Style="{StaticResource GroupHeaderTextStyle}"/>
                                        </StackPanel>
                                    </Button>
                                </Grid>
                            </DataTemplate>
                        </GroupStyle.HeaderTemplate>
                        <GroupStyle.Panel>
                            <ItemsPanelTemplate>
                                <VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,80,0"/>
                            </ItemsPanelTemplate>
                        </GroupStyle.Panel>
                    </GroupStyle>
                </GridView.GroupStyle>
            </GridView>

    关键因素1:<GroupStyle.Panel>中的 VariableSizedWrapGrid

     如果把<GroupStyle.Panel>中的 VariableSizedWrapGrid替换成<StackPanel Orientation="Horizontal" Margin="0,0,80,0"/>,你会发现效果变成了这样:

    Group Title 1 中的 Item Titile 2的项被删除掉了以后,后面的元素都向前移动了,证明VariableSizedWrapGrid控件内部对Visibility变化导致的布局变化的支持度不是很好。(你注意到在ItemTitile2项被隐藏后,为什么中间的空间会比较大,不像其他元素一样?  这个留给大家去研究吧,卖个关子。。。)

    关键因素2:WrapGrid

    或许你的应用中不需要分组,也会出现类似的情况,那可能是这样的:

    <GridView
                x:Name="itemGridView"
                AutomationProperties.AutomationId="ItemGridView"
                AutomationProperties.Name="Grouped Items"
                Grid.RowSpan="2"
                Padding="116,137,40,46"
                ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
                ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
                SelectionMode="None"
                IsSwipeEnabled="false"
                IsItemClickEnabled="True"
                ItemClick="ItemView_ItemClick">
    
                <GridView.ItemsPanel>
                    <ItemsPanelTemplate>                        
                        <WrapGrid Orientation="Vertical"/>
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>
            </GridView>

    同样的,隐藏某一项后,后面的元素并不会填充被隐藏元素的空间,而只是隐藏了那一项,剩下的位置不动。。。

    那你试试把WrapGrid换成 VirtualizingStackPanel,问题解决了。

    你或许在问,如果这样改,空白的空间是解决了,但是我们的整体布局也被打乱了。。。

    没错,其实这些都只是下下策,更多的是为了告诉大家,这几个控件对Visibility属性变化而引起的布局变化的支持程度,而相比较之下,或许从数据源中删除数据才是更好的解决方案,即解决了空白空间的问题,也解决了布局被打乱的问题。

  • 相关阅读:
    oracle 视图views
    5分钟把任意网站变成桌面软件
    Angular http跨域
    jQuery版本升级踩坑大全
    redis 模糊删除key
    jedisCluster 报错: redis.clients.jedis.exceptions.JedisClusterException: No way to dispatch this command to Redis Cluster because keys have different slots.
    mac电脑复制键失灵
    java8 for ,forEach ,lambda forEach , strean forEach , parller stream forEach, Iterator性能对比
    linux光标操作
    redis hashmap数据结构分析
  • 原文地址:https://www.cnblogs.com/lihaiyin/p/2843953.html
Copyright © 2020-2023  润新知