日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

UWP開發(fā)入門(五)

 昵稱10504424 2016-01-11

  各位好,終于講到自定義Panel了。當系統(tǒng)自帶的幾個Panel比如Gird,StackPanel,RelativePanel不能滿足我們的特定要求時(其實不常見啦),自定義Panel就顯得非常必要,而且因為是針對性的處理,效果也會非常好。更何況自定義Panel其實并不復雜,今天俺們就來學習一下。

  記得上一篇自定義CommandBar在增加占位控件AppBarEmpty時,采用的是通過PageSizeChanged事件中計算頁面Width,減去CommandBar中其他控件Width后再賦值WidthAppBarEmpty的方法。就可行性而言是絕對沒問題的,代碼復雜度也很低,不失為一個好方法。但是復用性不太好,需要在每個Page都寫上一小段代碼。而我們的初衷是希望AppBarEmpty能夠自動撐開,計算自身所需的Width。

  遇到的困難來自StackPanel這個控件,StackPanel在計算自身所需空間時,會非常吝嗇按children元素所需的最小尺寸來申請。就好比申請經(jīng)費時按最下限申請,這種精神ZF部門應該學習,而公司組織TeamBuilding就應該排斥……)。說到這里,本篇的主題有了,就是通過自定義一個StackPanelEx來實現(xiàn)讓AppBarEmpty自動撐開的效果。

  前面說了,自定義Panel其實并不復雜。只有兩個方法需要override

復制代碼
        //
        // Summary:(根據(jù)子元素測量控件本身需要的空間)
        //     Provides the behavior for the Measure pass of the layout cycle. Classes can override
        //     this method to define their own Measure pass behavior.
        //
        // Parameters:
        //   availableSize:(控件本身的可用空間。如指定無窮大值,表示控件的大小將調(diào)整為內(nèi)容的可用大小)
        //     The available size that this object can give to child objects. Infinity can be
        //     specified as a value to indicate that the object will size to whatever content
        //     is available.
        //
        // Returns:(控件根據(jù)子元素大小計算得出的所需大?。?        //     The size that this object determines it needs during layout, based on its calculations
        //     of the allocated sizes for child objects or based on other considerations such
        //     as a fixed container size.
        protected virtual Size MeasureOverride(Size availableSize);
        //
        // Summary:(根據(jù)上面測量的結果,來對子元素進行布局)
        //     Provides the behavior for the Arrange pass of layout. Classes can override this
        //     method to define their own Arrange pass behavior.
        //
        // Parameters:
        //   finalSize:(控件用來排列自身及其子元素的最終確定的空間)
        //     The final area within the parent that this object should use to arrange itself
        //     and its children.
        //
        // Returns:(使用的實際大?。?        //     The actual size that is used after the element is arranged in layout.
        protected virtual Size ArrangeOverride(Size finalSize);
復制代碼

  聽上去是不是挺繞的?我們來看StackPanelEx的實際代碼:

復制代碼
    public class StackPanelEx : Panel
    {
        protected override Size MeasureOverride(Size availableSize)
        {
         double height = 0;
            foreach (var child in Children)
            {
                // Tell the child control to determine the size needed
                child.Measure(availableSize);
                height = child.DesiredSize.Height > height ? child.DesiredSize.Height : height;
            }

            return new Size(availableSize.Width,height);
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            int count = Children.Count(_ => _ is AppBarEmpty2);
            double totalLength = Children.Where(_ => _ is AppBarEmpty2 == false).Sum(_ => (_ as FrameworkElement).Width);
            var emptyWidth = (finalSize.Width - totalLength) / count;

            double x = 0;
            foreach (var child in Children)
            {
                if (child is AppBarEmpty2)
                {
                    child.Arrange(new Rect(x, 0, emptyWidth, 0));
                    x += emptyWidth;
                }
                else
                {
                    child.Arrange(new Rect(x, 0, child.DesiredSize.Width, child.DesiredSize.Height));
                    x += child.DesiredSize.Width;
                }
            }
            return finalSize;
        }
    }
復制代碼

  簡單解釋一下,首先在MeasureOverride方法里,告訴每個子元素(這里是AppBarButtonAppBarEmpty2)去算自己需要多少空間,一會要分地了。然后直接告訴上頭,Width我全要了,Height按我們村里最高的人給就行了。

  緊接著到了ArrangeOverride方法,上級領導比較大方,告訴該控件Width全給你,還有你Height要的太少,拖了上級Panel的后腿,多給一些Height免得擠到同級的其他控件……

  然后村長及開始分地了。AppBarButton就按他自己申請的給,AppBarEmpty2感覺是村長親戚,剩下的Width全給他們家承包了……

  最后向上頭匯報一下分地的情況,這事就算完了。

  AppBarEmpty2還是沒變,和上次一樣。

    public class AppBarEmpty2 : FrameworkElement, ICommandBarElement
    {
        public bool IsCompact { get; set; }
    }

  既然新的StackPanelEx寫好了,就該替換CommandBar原有的StackPanel,找到CommandBar模板中關于PrimaryItemsControl的部分

復制代碼
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="Auto"/>
                                    </Grid.ColumnDefinitions>
                                    <ContentControl x:Name="ContentControl" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsTabStop="False" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                    <ItemsControl x:Name="PrimaryItemsControl" Grid.Column="0" 
                                                  HorizontalAlignment="Stretch"  IsTabStop="False" MinHeight="{ThemeResource AppBarThemeMinHeight}">
                                        <ItemsControl.ItemsPanel>
                                            <ItemsPanelTemplate>
                                                <!--<StackPanel Orientation="Horizontal"/>-->
                                                <local:StackPanelEx ></local:StackPanelEx>
                                            </ItemsPanelTemplate>
                                        </ItemsControl.ItemsPanel>
                                    </ItemsControl>
                                </Grid>
復制代碼

  ItemsPanelTemplate中的StackPanel替換成StackPanelEx,同時將ItemsControlHorizontalAlignment="Right"改成HorizontalAlignment="Stretch",大功告成,再來看一下Page中的XAML部分:

復制代碼
       <CommandBar x:Name="commandBar" Grid.Row="3" Style="{StaticResource CommandBarStyle2}" >
            <AppBarButton x:Name="appbarButton" Icon="Accept" Label="fdsfdsf" ></AppBarButton>
            <local:AppBarEmpty2  ></local:AppBarEmpty2>
            <AppBarButton Icon="Accept" Label="fdsfdsf"></AppBarButton>
            <local:AppBarEmpty2  ></local:AppBarEmpty2>
            <AppBarButton Icon="Accept" Label="fdsfdsf" ></AppBarButton>
        </CommandBar>
復制代碼

  是不是非常的清爽,再也不用去寫什么SizeChanged事件了。實際效果如下圖:

 

 

 

 

 

 

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多