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屬性變化而引起的布局變化的支持程度,而相比較之下,或許從數據源中刪除數據才是更好的解決方案,即解決了空白空間的問題,也解決了布局被打亂的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM